fina/backup/first -fina app/docs/CUSTOM_RECURRING_CHANGES.md
2025-12-26 00:52:56 +00:00

370 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Custom Recurring Expenses - What Changed
## Database Model Changes
### Before
```python
class Subscription(db.Model):
id
name
amount
frequency # only: weekly, biweekly, monthly, quarterly, yearly
category_id
user_id
next_due_date
is_active
is_confirmed
auto_detected
confidence_score
notes
created_at
last_reminded
```
### After ✨
```python
class Subscription(db.Model):
id
name
amount
frequency # NOW INCLUDES: custom
custom_interval_days # 🆕 For custom frequency
category_id
user_id
next_due_date
start_date # 🆕 First occurrence
end_date # 🆕 Optional end date
total_occurrences # 🆕 Payment limit
occurrences_count # 🆕 Current count
is_active
is_confirmed
auto_detected
auto_create_expense # 🆕 Auto-creation flag
confidence_score
notes
created_at
last_reminded
last_auto_created # 🆕 Last auto-create date
# 🆕 NEW METHODS
should_create_expense_today()
advance_next_due_date()
```
## Form Changes
### Create Subscription - Before
```html
Name: [_____]
Amount: [_____]
Frequency: [Monthly ▼] ← Only 5 options
Category: [Bills ▼]
Next Payment: [2025-01-15]
Notes: [_________]
[Cancel] [Save]
```
### Create Subscription - After ✨
```html
Name: [_____]
Amount: [_____]
Frequency: [Custom ▼] ← 6 options now, including Custom
→ Custom Interval: [45] days 🆕 (shown when Custom selected)
Category: [Bills ▼]
Start Date: [2025-01-01] 🆕
End Date: [2025-12-31] 🆕 (optional)
Total Payments: [12] 🆕 (optional)
☑ Auto-Create Expenses 🆕
"Automatically add expense when payment is due"
Notes: [_________]
[Cancel] [Save]
```
## UI Display Changes
### Subscription List - Before
```
🔄 Netflix Premium
💰 $19.99 / Monthly
📅 Next: Jan 15, 2025
📊 Annual: $239.88
[Edit] [Delete]
```
### Subscription List - After ✨
```
🔄 Netflix Premium ⚡ AUTO 🆕
💰 $19.99 / Monthly
📅 Next: Jan 15, 2025
📊 Annual: $239.88
🔢 8/12 times 🆕 (if total_occurrences set)
[Edit] [Delete]
🔄 Car Maintenance
💰 $75.00 / Every 45 days 🆕 (custom interval display)
📅 Next: Feb 28, 2025
📊 Annual: $608.25
[Edit] [Delete]
```
## Page Header Changes
### Before
```
🔄 Subscriptions
[🔍 Detect Recurring] [ Add Subscription]
```
### After ✨
```
🔄 Subscriptions
[⚡ Create Due Expenses] 🆕 [🔍 Detect Recurring] [ Add Subscription]
```
## Route Changes
### Before
```python
GET /subscriptions # List
GET /subscriptions/create # Form
POST /subscriptions/create # Save
GET /subscriptions/<id>/edit # Edit form
POST /subscriptions/<id>/edit # Update
POST /subscriptions/<id>/delete
POST /subscriptions/detect # AI detection
POST /subscriptions/<id>/accept
POST /subscriptions/<id>/dismiss
GET /subscriptions/api/upcoming
```
### After ✨
```python
GET /subscriptions # List
GET /subscriptions/create # Form (now with custom fields)
POST /subscriptions/create # Save (handles custom data)
GET /subscriptions/<id>/edit # Edit form (now with custom fields)
POST /subscriptions/<id>/edit # Update (handles custom data)
POST /subscriptions/<id>/delete
POST /subscriptions/detect # AI detection
POST /subscriptions/<id>/accept
POST /subscriptions/<id>/dismiss
GET /subscriptions/api/upcoming
POST /subscriptions/auto-create # 🆕 Auto-create expenses
```
## Translation Keys Added
### English
```python
'subscription.freq_custom': 'Custom' 🆕
'subscription.custom_interval': 'Repeat Every (Days)' 🆕
'subscription.start_date': 'Start Date' 🆕
'subscription.end_date': 'End Date' 🆕
'subscription.total_occurrences': 'Total Payments' 🆕
'subscription.auto_create': 'Auto-Create Expenses' 🆕
'subscription.create_due': 'Create Due Expenses' 🆕
'subscription.auto': 'AUTO' 🆕
'subscription.every': 'Every' 🆕
'subscription.days': 'days' 🆕
'subscription.times': 'times' 🆕
# + 5 more helper keys
```
### Romanian + Spanish
- All keys translated in both languages ✓
## Code Logic Changes
### Frequency Calculation - Before
```python
def get_frequency_days(self):
frequency_map = {
'weekly': 7,
'biweekly': 14,
'monthly': 30,
'quarterly': 90,
'yearly': 365
}
return frequency_map.get(self.frequency, 30)
```
### Frequency Calculation - After ✨
```python
def get_frequency_days(self):
if self.frequency == 'custom' and self.custom_interval_days: 🆕
return self.custom_interval_days 🆕
frequency_map = {
'weekly': 7,
'biweekly': 14,
'monthly': 30,
'quarterly': 90,
'yearly': 365
}
return frequency_map.get(self.frequency, 30)
```
### New Auto-Create Logic ✨
```python
def should_create_expense_today(self):
"""Check if expense should be auto-created today"""
if not self.auto_create_expense or not self.is_active:
return False
if not self.next_due_date or self.next_due_date != today:
return False
if self.last_auto_created == today:
return False # Already created today
if self.total_occurrences and self.occurrences_count >= self.total_occurrences:
return False # Reached limit
if self.end_date and today > self.end_date:
return False # Past end date
return True
def advance_next_due_date(self):
"""Move to next due date and check limits"""
interval_days = self.get_frequency_days()
self.next_due_date = self.next_due_date + timedelta(days=interval_days)
self.occurrences_count += 1
# Auto-deactivate if limits reached
if self.total_occurrences and self.occurrences_count >= self.total_occurrences:
self.is_active = False
if self.end_date and self.next_due_date > self.end_date:
self.is_active = False
```
## JavaScript Changes
### Create Form - Added
```javascript
function toggleCustomInterval() {
const frequency = document.getElementById('frequency').value;
const customGroup = document.getElementById('custom-interval-group');
const customInput = document.getElementById('custom_interval_days');
if (frequency === 'custom') {
customGroup.style.display = 'block';
customInput.required = true;
} else {
customGroup.style.display = 'none';
customInput.required = false;
}
}
```
## Files Created
1. `migrate_custom_recurring.py` - Migration script (Python)
2. `CUSTOM_RECURRING_GUIDE.md` - Complete user guide (30+ sections)
3. `CUSTOM_RECURRING_SUMMARY.md` - Quick feature summary
## Files Modified
1. `app/models/subscription.py` - Added 7 fields + 2 methods
2. `app/routes/subscriptions.py` - Updated create/edit + added auto-create endpoint
3. `app/templates/subscriptions/create.html` - Added custom frequency UI
4. `app/templates/subscriptions/edit.html` - Added custom frequency UI
5. `app/templates/subscriptions/index.html` - Added AUTO badge + auto-create button
6. `app/translations.py` - Added 15+ keys in 3 languages
## Migration Steps
### Database
```sql
-- New columns added:
ALTER TABLE subscriptions ADD COLUMN custom_interval_days INTEGER;
ALTER TABLE subscriptions ADD COLUMN start_date DATE;
ALTER TABLE subscriptions ADD COLUMN end_date DATE;
ALTER TABLE subscriptions ADD COLUMN total_occurrences INTEGER;
ALTER TABLE subscriptions ADD COLUMN occurrences_count INTEGER DEFAULT 0;
ALTER TABLE subscriptions ADD COLUMN auto_create_expense BOOLEAN DEFAULT 0;
ALTER TABLE subscriptions ADD COLUMN last_auto_created DATE;
-- Backfill start_date from next_due_date:
UPDATE subscriptions
SET start_date = next_due_date
WHERE start_date IS NULL AND next_due_date IS NOT NULL;
```
## Backward Compatibility
### ✅ Existing Subscriptions
- Continue working normally
- `custom_interval_days` is NULL (ignored)
- `auto_create_expense` defaults to False
- `start_date` backfilled from `next_due_date`
### ✅ Existing Routes
- All original routes still work
- New fields optional
- Forms handle NULL values gracefully
### ✅ API Responses
- New fields returned but not required
- Clients can ignore new fields
- No breaking changes
## Testing Scenarios
### ✅ Tested
1. Create standard monthly subscription → Works
2. Create custom 45-day interval → Works
3. Enable auto-create → Works
4. Set end date → Deactivates correctly
5. Set total payments (12) → Counts properly
6. Edit existing subscription → Preserves data
7. Romanian translation → All keys present
8. Spanish translation → All keys present
9. Auto-create button → Creates expenses
10. Dashboard widget → Shows custom intervals
## Performance Impact
- **Database**: 7 new columns (minimal impact)
- **Queries**: No additional complexity
- **UI**: 1 additional button (negligible)
- **JavaScript**: 1 small function (< 1KB)
- **Translation**: 15 keys × 3 languages (< 2KB)
**Overall**: Negligible performance impact
## Security Considerations
- All routes require `@login_required`
- CSRF tokens on all forms
- User-scoped queries only
- Input validation on custom interval
- SQL injection prevented (SQLAlchemy ORM)
## Summary of Improvements
| Feature | Before | After | Improvement |
|---------|--------|-------|-------------|
| Frequency Options | 5 | 6 (+ custom) | +20% flexibility |
| Scheduling Control | Basic | Advanced | End dates, limits |
| Automation | Manual only | Auto-create | Time savings |
| Occurrence Tracking | None | Full counter | Better insights |
| Custom Intervals | No | Yes | Unlimited flexibility |
---
**Total Lines of Code Changed**: ~500 lines
**New Features Added**: 7 major features
**Languages Supported**: 3 (EN, RO, ES)
**Database Columns Added**: 7
**New Routes**: 1 (auto-create)
**Documentation Pages**: 2 comprehensive guides