71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Ядро сервиса: построение значений и создание документа."""
|
|
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)
|