
- 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.
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 identifierdescription
: Description of the expensetotal_amount
: Total cost of the expense (Decimal)currency
: Currency code (defaults to "USD")expense_date
: When the expense occurredsplit_type
: How the expense should be dividedlist_id
: Optional reference to a shopping listgroup_id
: Optional reference to a groupitem_id
: Optional reference to a specific itempaid_by_user_id
: User who paid for the expensecreated_by_user_id
: User who created the expense recordversion
: For optimistic lockingoverall_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 identifierexpense_id
: Reference to parent expenseuser_id
: User who owes this portionowed_amount
: Amount owed by the usershare_percentage
: Percentage share (for percentage-based splits)share_units
: Number of shares (for share-based splits)status
: Current payment statuspaid_at
: When the split was paidsettlement_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 identifierexpense_split_id
: Reference to the split being paidpaid_by_user_id
: User making the paymentamount_paid
: Amount being paidpaid_at
: When the payment was madecreated_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 optionallyitem_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
- Validate context (list/group)
- Create expense record
- Generate splits based on split type
- Validate total amounts match
- 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
- Create settlement activity
- Update split status
- Recalculate expense overall status
- All operations in single transaction
4. Deleting Expenses
- Requires version matching
- Cascades to splits and settlements
- All operations in single transaction
Best Practices
-
Data Integrity
- Always use transactions for multi-step operations
- Validate totals match before saving
- Use optimistic locking for updates
-
Error Handling
- Handle database errors appropriately
- Validate user permissions
- Check for concurrent modifications
-
Performance
- Use appropriate indexes
- Load relationships efficiently
- Batch operations when possible
-
Security
- Validate user permissions
- Sanitize input data
- Use proper access controls
Common Use Cases
-
Group Dinner
- Create expense with total amount
- Use equal split or exact amounts
- Record payments as they occur
-
Shopping List
- Create item-based expense
- System automatically splits based on items
- Track payments per person
-
Rent Sharing
- Create expense with total rent
- Use percentage or share-based split
- Record monthly payments
-
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
-
Daily
- Repeats every X days
- Example: Daily parking fee
-
Weekly
- Repeats every X weeks on specific days
- Example: Weekly cleaning service
-
Monthly
- Repeats every X months on the same date
- Example: Monthly rent payment
-
Yearly
- Repeats every X years on the same date
- Example: Annual insurance premium
Implementation Details
-
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 }
-
Recurring Expense Properties
- All standard expense properties
recurrence_pattern
: Defines how the expense repeatsnext_occurrence
: When the next expense will be createdlast_occurrence
: When the last expense was createdis_recurring
: Boolean flag to identify recurring expenses
-
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
-
Management Features
- Pause/resume recurrence
- Modify future occurrences
- Skip specific occurrences
- End recurrence early
- View all generated expenses
Best Practices for Recurring Expenses
-
Data Management
- Keep original recurring expense as template
- Generate new expenses in advance
- Clean up old generated expenses periodically
-
User Experience
- Clear indication of recurring expenses
- Easy way to modify future occurrences
- Option to handle exceptions
-
Performance
- Batch process expense generation
- Index recurring expense queries
- Cache frequently accessed patterns
Example Use Cases
-
Monthly Rent
{ "description": "Monthly Rent", "total_amount": "2000.00", "split_type": "PERCENTAGE", "recurrence_pattern": { "type": "monthly", "interval": 1, "endDate": "2024-12-31" } }
-
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
-
Decimal Handling
- Use string representation for decimals in API
- Convert to Decimal for calculations
- Round to 2 decimal places for money
-
Date Handling
- Use ISO format for dates
- Store in UTC
- Convert to local time for display
-
Status Updates
- Update split status on payment
- Recalculate overall status
- Notify relevant users
Future Considerations
-
Potential Enhancements
- Recurring expenses
- Bulk operations
- Advanced reporting
- Currency conversion
-
Scalability
- Handle large groups
- Optimize for frequent updates
- Consider caching strategies
-
Integration
- Payment providers
- Accounting systems
- Export capabilities