Files

77 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""PDF-Erzeugung in einem eigenen Prozess ohne Qt-Laufzeit ausführen."""
from __future__ import annotations
import json
import logging
from pathlib import Path
import shutil
import sys
from .create import create_invoice, find_customer, save_customer
from .gui_data import InvoiceForm
from .models import Party
from .render import render_html, render_pdf
def execute(request: dict, progress) -> dict:
"""Nur geprüfte Formulardaten an die gemeinsame Rechnungserstellung übergeben."""
form = InvoiceForm.model_validate(request['form'])
presets, resources = Path(request['presets']), Path(request['resources'])
invoice = form.invoice(presets)
if request['mode'] == 'preview':
progress('Entwurf wird ohne Nummernreservierung erstellt …')
invoice.meta.invoice_number = 'ENTWURF'
invoice.payment.reference = 'Entwurf – noch keine Rechnungsnummer vergeben'
invoice.meta.notes = 'ENTWURF – nicht zum Versand.\n' + (invoice.meta.notes or '')
folder = Path(request['scratch'])
(folder / 'assets').mkdir(exist_ok=True)
logo = presets / 'logo.svg'
if not logo.is_file():
logo = resources / 'assets/logo.svg'
shutil.copy2(logo, folder / 'assets/logo.svg')
result = render_pdf(render_html(invoice, resources / 'templates/invoice.html.j2'),
folder / 'entwurf.pdf', logging.getLogger('gui-preview'), base_url=str(folder))
if not result.ok:
raise RuntimeError(result.error)
return {'pdf': str(result.path)}
if request['mode'] != 'generate':
raise ValueError('Unbekannter Auftrag')
jar = Path(request['jar'])
if not jar.is_file():
raise ValueError('Mustang fehlt. Einmalig jr-einvoice setup-mustang ausführen.')
existing = find_customer(presets, form.buyer.name)
if existing and Party.model_validate(existing[1]['buyer']) != form.buyer:
raise ValueError('Dieser Kundenname ist mit anderen Stammdaten gespeichert. '
'Bitte den gespeicherten Kunden auswählen oder die Kundendatei prüfen.')
# Vorlagen dürfen vorhandene Kundenadressen nicht stillschweigend ersetzen.
match = existing or save_customer(presets, form.buyer.name, form.buyer.model_dump(mode='json'))
first = form.items[0]
result = create_invoice(root=Path(request['root']), resources=resources, presets=presets,
customer=match[0], entry=first.name, volume=first.quantity,
price=first.unit_price_net, items=form.items, notes=form.notes,
jar=jar, logger=logging.getLogger('gui'), number=form.number,
issued=form.issued, due_days=form.due_days,
service_period_start=form.start, service_period_end=form.end,
buyer_reference=form.buyer_reference, order_reference=form.order_reference,
progress=progress)
return {'invoice': result.invoice.model_dump(mode='json'), 'attachment': str(result.attachment),
'build': {key: str(value) if value is not None else None
for key, value in vars(result.build).items()}}
def main(argv=None):
request_path = Path((argv or sys.argv[1:])[0])
result_path = request_path.with_name('result.json')
try:
request = json.loads(request_path.read_text(encoding='utf-8'))
result = execute(request, lambda message: print(json.dumps({'progress': message}), flush=True))
result_path.write_text(json.dumps({'result': result}), encoding='utf-8')
return 0
except Exception as exc:
result_path.write_text(json.dumps({'error': str(exc)}), encoding='utf-8')
return 1
if __name__ == '__main__':
raise SystemExit(main())