148 lines
6 KiB
Python
148 lines
6 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Test script to create backdated recurring income entries
|
||
|
|
This will test the automatic income creation feature
|
||
|
|
"""
|
||
|
|
from datetime import datetime, timedelta
|
||
|
|
from app import create_app, db
|
||
|
|
from app.models import Income, User
|
||
|
|
from app.routes.income import calculate_income_next_due_date
|
||
|
|
|
||
|
|
def create_test_income():
|
||
|
|
"""Create backdated recurring income for testing"""
|
||
|
|
app = create_app()
|
||
|
|
|
||
|
|
with app.app_context():
|
||
|
|
# Get the first user (or create test user)
|
||
|
|
user = User.query.first()
|
||
|
|
if not user:
|
||
|
|
print("No users found in database. Please create a user first.")
|
||
|
|
return
|
||
|
|
|
||
|
|
print(f"Creating test income for user: {user.username}")
|
||
|
|
print(f"User currency: {user.currency}")
|
||
|
|
|
||
|
|
# Test 1: Monthly salary - backdated 2 months (should trigger 2 auto-creations)
|
||
|
|
two_months_ago = datetime.utcnow() - timedelta(days=60)
|
||
|
|
next_due_date = calculate_income_next_due_date('monthly', None, two_months_ago)
|
||
|
|
|
||
|
|
salary_income = Income(
|
||
|
|
amount=5000.0,
|
||
|
|
currency=user.currency,
|
||
|
|
description="Monthly Salary - Test",
|
||
|
|
source="Salary",
|
||
|
|
user_id=user.id,
|
||
|
|
tags='["recurring", "salary", "test"]',
|
||
|
|
frequency='monthly',
|
||
|
|
next_due_date=next_due_date,
|
||
|
|
is_active=True,
|
||
|
|
auto_create=True,
|
||
|
|
date=two_months_ago
|
||
|
|
)
|
||
|
|
db.session.add(salary_income)
|
||
|
|
print(f"✓ Created monthly salary income backdated to {two_months_ago.date()}")
|
||
|
|
print(f" Next due date: {next_due_date.date() if next_due_date else 'None'}")
|
||
|
|
|
||
|
|
# Test 2: Biweekly freelance - backdated 4 weeks (should trigger 2 auto-creations)
|
||
|
|
four_weeks_ago = datetime.utcnow() - timedelta(days=28)
|
||
|
|
next_due_date = calculate_income_next_due_date('biweekly', None, four_weeks_ago)
|
||
|
|
|
||
|
|
freelance_income = Income(
|
||
|
|
amount=1500.0,
|
||
|
|
currency=user.currency,
|
||
|
|
description="Freelance Project - Test",
|
||
|
|
source="Freelance",
|
||
|
|
user_id=user.id,
|
||
|
|
tags='["recurring", "freelance", "test"]',
|
||
|
|
frequency='biweekly',
|
||
|
|
next_due_date=next_due_date,
|
||
|
|
is_active=True,
|
||
|
|
auto_create=True,
|
||
|
|
date=four_weeks_ago
|
||
|
|
)
|
||
|
|
db.session.add(freelance_income)
|
||
|
|
print(f"✓ Created biweekly freelance income backdated to {four_weeks_ago.date()}")
|
||
|
|
print(f" Next due date: {next_due_date.date() if next_due_date else 'None'}")
|
||
|
|
|
||
|
|
# Test 3: Weekly side gig - backdated 3 weeks (should trigger 3 auto-creations)
|
||
|
|
three_weeks_ago = datetime.utcnow() - timedelta(days=21)
|
||
|
|
next_due_date = calculate_income_next_due_date('weekly', None, three_weeks_ago)
|
||
|
|
|
||
|
|
weekly_income = Income(
|
||
|
|
amount=300.0,
|
||
|
|
currency=user.currency,
|
||
|
|
description="Side Gig - Test",
|
||
|
|
source="Freelance",
|
||
|
|
user_id=user.id,
|
||
|
|
tags='["recurring", "side-gig", "test"]',
|
||
|
|
frequency='weekly',
|
||
|
|
next_due_date=next_due_date,
|
||
|
|
is_active=True,
|
||
|
|
auto_create=True,
|
||
|
|
date=three_weeks_ago
|
||
|
|
)
|
||
|
|
db.session.add(weekly_income)
|
||
|
|
print(f"✓ Created weekly side gig income backdated to {three_weeks_ago.date()}")
|
||
|
|
print(f" Next due date: {next_due_date.date() if next_due_date else 'None'}")
|
||
|
|
|
||
|
|
# Test 4: Every 4 weeks contract - backdated 8 weeks (should trigger 2 auto-creations)
|
||
|
|
eight_weeks_ago = datetime.utcnow() - timedelta(days=56)
|
||
|
|
next_due_date = calculate_income_next_due_date('every4weeks', None, eight_weeks_ago)
|
||
|
|
|
||
|
|
contract_income = Income(
|
||
|
|
amount=2000.0,
|
||
|
|
currency=user.currency,
|
||
|
|
description="Contract Work - Test",
|
||
|
|
source="Freelance",
|
||
|
|
user_id=user.id,
|
||
|
|
tags='["recurring", "contract", "test"]',
|
||
|
|
frequency='every4weeks',
|
||
|
|
next_due_date=next_due_date,
|
||
|
|
is_active=True,
|
||
|
|
auto_create=True,
|
||
|
|
date=eight_weeks_ago
|
||
|
|
)
|
||
|
|
db.session.add(contract_income)
|
||
|
|
print(f"✓ Created every-4-weeks contract income backdated to {eight_weeks_ago.date()}")
|
||
|
|
print(f" Next due date: {next_due_date.date() if next_due_date else 'None'}")
|
||
|
|
|
||
|
|
# Test 5: Custom 10-day cycle - backdated 30 days (should trigger 3 auto-creations)
|
||
|
|
thirty_days_ago = datetime.utcnow() - timedelta(days=30)
|
||
|
|
next_due_date = calculate_income_next_due_date('custom', 10, thirty_days_ago)
|
||
|
|
|
||
|
|
custom_income = Income(
|
||
|
|
amount=500.0,
|
||
|
|
currency=user.currency,
|
||
|
|
description="Custom Cycle Income - Test",
|
||
|
|
source="Other",
|
||
|
|
user_id=user.id,
|
||
|
|
tags='["recurring", "custom", "test"]',
|
||
|
|
frequency='custom',
|
||
|
|
custom_days=10,
|
||
|
|
next_due_date=next_due_date,
|
||
|
|
is_active=True,
|
||
|
|
auto_create=True,
|
||
|
|
date=thirty_days_ago
|
||
|
|
)
|
||
|
|
db.session.add(custom_income)
|
||
|
|
print(f"✓ Created custom (10-day) income backdated to {thirty_days_ago.date()}")
|
||
|
|
print(f" Next due date: {next_due_date.date() if next_due_date else 'None'}")
|
||
|
|
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
print("\n" + "="*60)
|
||
|
|
print("✓ Test recurring income entries created successfully!")
|
||
|
|
print("="*60)
|
||
|
|
print("\nExpected auto-creations when scheduler runs:")
|
||
|
|
print("- Monthly Salary: ~2 entries")
|
||
|
|
print("- Biweekly Freelance: ~2 entries")
|
||
|
|
print("- Weekly Side Gig: ~3 entries")
|
||
|
|
print("- Every-4-weeks Contract: ~2 entries")
|
||
|
|
print("- Custom 10-day: ~3 entries")
|
||
|
|
print("\nTotal expected: ~12 auto-created income entries")
|
||
|
|
print("\nTo trigger scheduler manually, run:")
|
||
|
|
print("docker compose exec web python -c \"from app.scheduler import process_due_recurring_income; process_due_recurring_income()\"")
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
create_test_income()
|