first commit

This commit is contained in:
Mateusz Gruszczyński
2026-03-13 15:17:32 +01:00
commit 986ffb200a
91 changed files with 4423 additions and 0 deletions

42
app/services/reporting.py Normal file
View File

@@ -0,0 +1,42 @@
from __future__ import annotations
from datetime import date, timedelta
from decimal import Decimal
from ..extensions import db
from ..models import Expense, ReportLog, User
from .mail import MailService
from .settings import get_bool_setting
def _range_for_frequency(frequency: str, today: date):
if frequency == 'daily':
start = today - timedelta(days=1)
label = start.isoformat()
elif frequency == 'weekly':
start = today - timedelta(days=7)
label = f'{start.isoformat()}..{today.isoformat()}'
else:
start = date(today.year, today.month, 1)
label = f'{today.year}-{today.month:02d}'
return start, today, label
def send_due_reports(today: date | None = None) -> int:
if not get_bool_setting('reports_enabled', True):
return 0
today = today or date.today()
sent = 0
users = User.query.filter(User.report_frequency.in_(['daily', 'weekly', 'monthly'])).all()
for user in users:
start, end, label = _range_for_frequency(user.report_frequency, today)
if ReportLog.query.filter_by(user_id=user.id, frequency=user.report_frequency, period_label=label).first():
continue
q = Expense.query.filter_by(user_id=user.id, is_deleted=False).filter(Expense.purchase_date >= start, Expense.purchase_date <= end)
rows = q.order_by(Expense.purchase_date.desc()).all()
total = sum((expense.amount for expense in rows), Decimal('0.00'))
MailService().send_template(user.email, f'Expense report {label}', 'expense_report', user=user, period_label=label, total=total, currency=user.default_currency, expenses=rows[:10])
db.session.add(ReportLog(user_id=user.id, frequency=user.report_frequency, period_label=label))
sent += 1
db.session.commit()
return sent