Unzip budget-app v7 into repo root
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
"""Short emails about reopen requests, sent through the configured account when email is on.
|
||||
|
||||
Best effort: a failure is written to the mail log and never blocks the action itself.
|
||||
"""
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from . import mailer
|
||||
from .models import BudgetYear, MailSettings, User
|
||||
|
||||
|
||||
def _ready(db: Session) -> MailSettings | None:
|
||||
cfg = db.get(MailSettings, 1)
|
||||
return cfg if cfg and mailer.is_ready(cfg) else None
|
||||
|
||||
|
||||
def reopeners(db: Session, budget: BudgetYear) -> list[User]:
|
||||
"""Who can reopen the budget: administrators and the department's approvers."""
|
||||
users = db.scalars(select(User).where(User.active)).all()
|
||||
return [u for u in users if u.role == "admin" or (u.role == "approver" and u.department_id == budget.department_id)]
|
||||
|
||||
|
||||
def send(db: Session, actor: User, budget: BudgetYear, to: list[User], subject: str, body: str) -> None:
|
||||
cfg = _ready(db)
|
||||
addresses = sorted({u.email for u in to if u.email and u.id != actor.id})
|
||||
if not cfg or not addresses:
|
||||
return
|
||||
try:
|
||||
addresses = mailer.clean_addresses(addresses)
|
||||
except mailer.MailError:
|
||||
return
|
||||
mailer.send(db, actor, cfg, to=addresses, cc=[], subject=subject, body=body, attachments=[], kind="notice",
|
||||
year_id=budget.id, context=f"{budget.department.name} {budget.year}")
|
||||
Reference in New Issue
Block a user