43 lines
1.8 KiB
Python
43 lines
1.8 KiB
Python
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
|