"""Ядро сервиса: построение значений и создание документа.""" from __future__ import annotations from . import config, store from .render import render_certificate, russian_date def base_url() -> str: if config.BASE_URL: return config.BASE_URL return f"http://{config.HOST}:{config.PORT}" def build_values(template: dict, body: dict) -> dict: defaults = template.get("defaults") or {} title = (body.get("title") or defaults.get("title") or template.get("title") or "").strip() text = body.get("body") if text is None: text = defaults.get("body", "") fields = body.get("fields") or {} values = { "title": title, "fio": (body.get("fio") or "").strip(), "body": text or "", "date": (body.get("date") or "").strip() or russian_date(), "fields": fields, } # произвольные поля из fields доступны как {ключ} for k, v in fields.items(): values.setdefault(str(k), v) return values def cert_api(cert: dict, base: str) -> dict: token = cert.get("public_token") return { **cert, "url": f"{base}/c/{cert['seq']}", "page": f"{base}/c/{cert['seq']}", "png": f"{base}/c/{cert['seq']}.png", "pdf": f"{base}/c/{cert['seq']}.pdf", "public_url": f"{base}/s/{token}" if token else None, "public_png": f"{base}/s/{token}.png" if token else None, "public_pdf": f"{base}/s/{token}.pdf" if token else None, } def create_certificate(template: dict, body: dict, base: str | None = None, created_by: int | None = None) -> dict: """Создать документ: зарезервировать номер, отрендерить, сохранить пути.""" base = base or base_url() values = build_values(template, body) cert = store.reserve_certificate( template=template["slug"], values=values, prefix=body.get("prefix"), number=body.get("number"), recipient_email=body.get("email") or body.get("recipient_email"), created_by=created_by, ) seq = cert["seq"] values["number"] = cert["number"] out_png = config.OUTPUT_DIR / f"{seq:06d}.png" out_pdf = config.OUTPUT_DIR / f"{seq:06d}.pdf" try: render_certificate(template, values, out_png, out_pdf) except Exception: store.delete_certificate(seq) raise store.update_certificate_files(seq, str(out_png), str(out_pdf)) return cert_api(store.get_certificate(seq), base)