mitlist/docs/expense-system.md
Mohamad.Elsena 5018ce02f7 feat: Implement recurring expenses feature with scheduling and management
- Added support for recurring expenses, allowing users to define recurrence patterns (daily, weekly, monthly, yearly) for expenses.
- Introduced `RecurrencePattern` model to manage recurrence details and linked it to the `Expense` model.
- Implemented background job scheduling using APScheduler to automatically generate new expenses based on defined patterns.
- Updated expense creation logic to handle recurring expenses, including validation and database interactions.
- Enhanced frontend components to allow users to create and manage recurring expenses through forms and lists.
- Updated documentation to reflect new features and usage guidelines for recurring expenses.
2025-05-22 16:37:14 +02:00

8.8 KiB

Expense System Documentation

Overview

The expense system is a core feature that allows users to track shared expenses, split them among group members, and manage settlements. The system supports various split types and integrates with lists, groups, and items.

Core Components

1. Expenses

An expense represents a shared cost that needs to be split among multiple users.

Key Properties

  • id: Unique identifier
  • description: Description of the expense
  • total_amount: Total cost of the expense (Decimal)
  • currency: Currency code (defaults to "USD")
  • expense_date: When the expense occurred
  • split_type: How the expense should be divided
  • list_id: Optional reference to a shopping list
  • group_id: Optional reference to a group
  • item_id: Optional reference to a specific item
  • paid_by_user_id: User who paid for the expense
  • created_by_user_id: User who created the expense record
  • version: For optimistic locking
  • overall_settlement_status: Overall payment status

Status Types

enum ExpenseOverallStatusEnum {
	UNPAID = "unpaid",
	PARTIALLY_PAID = "partially_paid",
	PAID = "paid",
}

2. Expense Splits

Splits represent how an expense is divided among users.

Key Properties

  • id: Unique identifier
  • expense_id: Reference to parent expense
  • user_id: User who owes this portion
  • owed_amount: Amount owed by the user
  • share_percentage: Percentage share (for percentage-based splits)
  • share_units: Number of shares (for share-based splits)
  • status: Current payment status
  • paid_at: When the split was paid
  • settlement_activities: List of payment activities

Status Types

enum ExpenseSplitStatusEnum {
	UNPAID = "unpaid",
	PARTIALLY_PAID = "partially_paid",
	PAID = "paid",
}

3. Settlement Activities

Settlement activities track individual payments made towards expense splits.

Key Properties

  • id: Unique identifier
  • expense_split_id: Reference to the split being paid
  • paid_by_user_id: User making the payment
  • amount_paid: Amount being paid
  • paid_at: When the payment was made
  • created_by_user_id: User who recorded the payment

Split Types

The system supports multiple ways to split expenses:

1. Equal Split

  • Divides the total amount equally among all participants
  • Handles rounding differences by adding remainder to first split
  • No additional data required

2. Exact Amounts

  • Users specify exact amounts for each person
  • Sum of amounts must equal total expense
  • Requires splits_in data with exact amounts

3. Percentage Based

  • Users specify percentage shares
  • Percentages must sum to 100%
  • Requires splits_in data with percentages

4. Share Based

  • Users specify number of shares
  • Amount divided proportionally to shares
  • Requires splits_in data with share units

5. Item Based

  • Splits based on items in a shopping list
  • Each item's cost is assigned to its adder
  • Requires list_id and optionally item_id

Integration Points

1. Lists

  • Expenses can be associated with shopping lists
  • Item-based splits use list items to determine splits
  • List's group context can determine split participants

2. Groups

  • Expenses can be directly associated with groups
  • Group membership determines who can be included in splits
  • Group context is required if no list is specified

3. Items

  • Expenses can be linked to specific items
  • Item prices are used for item-based splits
  • Items must belong to a list

4. Users

  • Users can be payers, debtors, or payment recorders
  • User relationships are tracked in splits and settlements
  • User context is required for all financial operations

Key Operations

1. Creating Expenses

  1. Validate context (list/group)
  2. Create expense record
  3. Generate splits based on split type
  4. Validate total amounts match
  5. Save all records in transaction

2. Updating Expenses

  • Limited to non-financial fields:
    • Description
    • Currency
    • Expense date
  • Uses optimistic locking via version field
  • Cannot modify splits after creation

3. Recording Payments

  1. Create settlement activity
  2. Update split status
  3. Recalculate expense overall status
  4. All operations in single transaction

4. Deleting Expenses

  • Requires version matching
  • Cascades to splits and settlements
  • All operations in single transaction

Best Practices

  1. Data Integrity

    • Always use transactions for multi-step operations
    • Validate totals match before saving
    • Use optimistic locking for updates
  2. Error Handling

    • Handle database errors appropriately
    • Validate user permissions
    • Check for concurrent modifications
  3. Performance

    • Use appropriate indexes
    • Load relationships efficiently
    • Batch operations when possible
  4. Security

    • Validate user permissions
    • Sanitize input data
    • Use proper access controls

Common Use Cases

  1. Group Dinner

    • Create expense with total amount
    • Use equal split or exact amounts
    • Record payments as they occur
  2. Shopping List

    • Create item-based expense
    • System automatically splits based on items
    • Track payments per person
  3. Rent Sharing

    • Create expense with total rent
    • Use percentage or share-based split
    • Record monthly payments
  4. Trip Expenses

    • Create multiple expenses
    • Mix different split types
    • Track overall balances

Recurring Expenses

Recurring expenses are expenses that repeat at regular intervals. They are useful for regular payments like rent, utilities, or subscription services.

Recurrence Types

  1. Daily

    • Repeats every X days
    • Example: Daily parking fee
  2. Weekly

    • Repeats every X weeks on specific days
    • Example: Weekly cleaning service
  3. Monthly

    • Repeats every X months on the same date
    • Example: Monthly rent payment
  4. Yearly

    • Repeats every X years on the same date
    • Example: Annual insurance premium

Implementation Details

  1. Recurrence Pattern

    interface RecurrencePattern {
    	type: "daily" | "weekly" | "monthly" | "yearly";
    	interval: number; // Every X days/weeks/months/years
    	daysOfWeek?: number[]; // For weekly recurrence (0-6, Sunday-Saturday)
    	endDate?: string; // Optional end date for the recurrence
    	maxOccurrences?: number; // Optional maximum number of occurrences
    }
    
  2. Recurring Expense Properties

    • All standard expense properties
    • recurrence_pattern: Defines how the expense repeats
    • next_occurrence: When the next expense will be created
    • last_occurrence: When the last expense was created
    • is_recurring: Boolean flag to identify recurring expenses
  3. Generation Process

    • System automatically creates new expenses based on the pattern
    • Each generated expense is a regular expense with its own splits
    • Original recurring expense serves as a template
    • Generated expenses can be modified individually
  4. Management Features

    • Pause/resume recurrence
    • Modify future occurrences
    • Skip specific occurrences
    • End recurrence early
    • View all generated expenses

Best Practices for Recurring Expenses

  1. Data Management

    • Keep original recurring expense as template
    • Generate new expenses in advance
    • Clean up old generated expenses periodically
  2. User Experience

    • Clear indication of recurring expenses
    • Easy way to modify future occurrences
    • Option to handle exceptions
  3. Performance

    • Batch process expense generation
    • Index recurring expense queries
    • Cache frequently accessed patterns

Example Use Cases

  1. Monthly Rent

    {
    	"description": "Monthly Rent",
    	"total_amount": "2000.00",
    	"split_type": "PERCENTAGE",
    	"recurrence_pattern": {
    		"type": "monthly",
    		"interval": 1,
    		"endDate": "2024-12-31"
    	}
    }
    
  2. Weekly Cleaning Service

    {
    	"description": "Weekly Cleaning",
    	"total_amount": "150.00",
    	"split_type": "EQUAL",
    	"recurrence_pattern": {
    		"type": "weekly",
    		"interval": 1,
    		"daysOfWeek": [1] // Every Monday
    	}
    }
    

API Considerations

  1. Decimal Handling

    • Use string representation for decimals in API
    • Convert to Decimal for calculations
    • Round to 2 decimal places for money
  2. Date Handling

    • Use ISO format for dates
    • Store in UTC
    • Convert to local time for display
  3. Status Updates

    • Update split status on payment
    • Recalculate overall status
    • Notify relevant users

Future Considerations

  1. Potential Enhancements

    • Recurring expenses
    • Bulk operations
    • Advanced reporting
    • Currency conversion
  2. Scalability

    • Handle large groups
    • Optimize for frequent updates
    • Consider caching strategies
  3. Integration

    • Payment providers
    • Accounting systems
    • Export capabilities