diff --git a/routers/factures.py b/routers/factures.py index 80a210b..9ed35ac 100644 --- a/routers/factures.py +++ b/routers/factures.py @@ -159,29 +159,64 @@ def changer_statut_facture( from generate_facturx_jinja2 import Invoice, Party, Address, InvoiceLine, filter_amount, filter_datefmt - -@router.get("/{facture_id}/pdf", response_class=HTMLResponse) +@router.get("/{facture_id}/pdf") def telecharger_pdf(request: Request, facture_id: int, db: Session = Depends(get_db)): - from weasyprint import HTML + from weasyprint import HTML, Attachment + from facturx import generate_from_binary + import hashlib + import pikepdf + from pikepdf import Name + import io + facture = db.query(Facture).get(facture_id) if not facture: raise HTTPException(status_code=404) + # 1. XML Factur-X + invoice = get_invoice_data(facture_id, db) + xml_str = generate_facturx_xml(invoice) + xml_bytes = xml_str.encode("utf-8") + + # 2. Rendu HTML → PDF simple (pas PDF/A-3 ici) html_content = templates.get_template("pdf/facture.html").render({ "facture": facture, "settings": settings, }) + pdf_bytes = HTML(string=html_content, base_url=".").write_pdf( + pdf_variant="pdf/a-3b", + ) - pdf_bytes = HTML(string=html_content, base_url=".").write_pdf() + # 3. generate_from_binary gère : + # - l'intégration du XML + # - les métadonnées XMP Factur-X (DocumentType, DocumentFileName, etc.) + # - la conformité PDF/A-3b + pdf_bytes = generate_from_binary( + pdf_bytes, + xml_bytes, + flavor="factur-x", + level="BASIC", + ) + + # 4. Corriger uniquement /EF/F/Subtype → /text/xml avec pikepdf + pdf_io = io.BytesIO(pdf_bytes) + with pikepdf.open(pdf_io) as pdf: + names = pdf.Root.Names.EmbeddedFiles.Names + i = 0 + while i < len(names): + i += 1 # sauter la clé (string) + if i < len(names): + obj = names[i] + try: + obj.EF.F.Subtype = Name("/text/xml") + except Exception: + pass + i += 1 + + output = io.BytesIO() + pdf.save(output) + pdf_bytes = output.getvalue() filename = f"facture-{facture.numero}.pdf" - - xml_bytes = generate_facturx_xml(get_invoice_data(facture_id, db)) - - pdf_bytes = generate_from_binary(pdf_bytes, xml_bytes) - - filename = f"facture-{facture.numero}.pdf" - return Response( content=pdf_bytes, media_type="application/pdf", diff --git a/templates/pdf/facture.html b/templates/pdf/facture.html index 80a787c..dd81ce1 100644 --- a/templates/pdf/facture.html +++ b/templates/pdf/facture.html @@ -4,10 +4,22 @@