"""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())