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

369 lines
8.8 KiB
Markdown

# 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
```typescript
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
```typescript
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**
```typescript
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**
```json
{
"description": "Monthly Rent",
"total_amount": "2000.00",
"split_type": "PERCENTAGE",
"recurrence_pattern": {
"type": "monthly",
"interval": 1,
"endDate": "2024-12-31"
}
}
```
2. **Weekly Cleaning Service**
```json
{
"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