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