Files
Budget_Tool_Martinhal/backend/app/reports/render.py
T

53 lines
2.4 KiB
Python
Raw Normal View History

2026-10-29 20:40:02 +00:00
from datetime import datetime
from pathlib import Path
from types import SimpleNamespace
from jinja2 import Environment, FileSystemLoader, select_autoescape
from ..summary import YearView
from .charts import change_bars, grouped_bars
from .i18n import T
TEMPLATES = Path(__file__).parent / "templates"
env = Environment(loader=FileSystemLoader(TEMPLATES), autoescape=select_autoescape(["html"]))
CSS = (TEMPLATES / "report.css").read_text()
def _exported() -> str:
return datetime.now().strftime("%Y-%m-%d %H:%M")
def cost_report_html(view: YearView, lang: str, site: str | None = None, screen: bool = True) -> str:
t = T(lang, view.year.year, view.year.department.name)
cost_cats = view.with_lines("cost")
cats = []
for cv in cost_cats:
rows = [(lv.line.name, float(lv.figures.prior), float(lv.figures.adjusted)) for lv in cv.lines]
cats.append(SimpleNamespace(
name=cv.name(lang), count=len(cv.lines), totals=cv.totals,
chart=grouped_bars(rows, t.short_eur, lambda v: t.eur(v, 0))))
overview = grouped_bars([(c.name, float(c.totals.prior), float(c.totals.adjusted)) for c in cats], t.short_eur)
ranked = sorted([c for c in cats if c.totals.change_pct is not None],
key=lambda c: c.totals.change_pct, reverse=True)
change = change_bars([(c.name, float(c.totals.change_pct)) for c in ranked], lambda v: t.pct(v))
return env.get_template("cost_report.html").render(
t=t, title=t("cost_report_title"), year=view.year, site=site, cats=cats, costs=view.costs,
overview_chart=overview, change_chart=change, exported=_exported(), css=CSS, screen=screen)
def budget_html(view: YearView, lang: str, site: str | None = None, include_empty: bool = False) -> str:
t = T(lang, view.year.year, view.year.department.name)
cats = [SimpleNamespace(name=cv.name(lang), category=cv.category, lines=cv.lines, totals=cv.totals)
for cv in view.categories if cv.lines or include_empty]
# revenue first, as in the Budget IT sheet
cats.sort(key=lambda c: 0 if c.category.section == "revenue" else 1)
return env.get_template("budget.html").render(
t=t, title=t("budget_title"), year=view.year, site=site, cats=cats, costs=view.costs,
exported=_exported(), css=CSS)
def to_pdf(html: str) -> bytes:
from weasyprint import HTML # imported lazily: it loads system libraries
return HTML(string=html).write_pdf()