misc: allow PDF attachments on Factur-X files (#83897)
This commit is contained in:
parent
caa4309db9
commit
1ad965ffa1
|
@ -18,6 +18,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import typing
|
||||||
|
|
||||||
import facturx
|
import facturx
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
@ -60,7 +61,19 @@ def to_pdfa(pdf_bytes: bytes, icc_profile: str = DEFAULT_ICC_PROFILE):
|
||||||
DEFAULT_FACTURX_TEMPLATE = 'factur-x.xml'
|
DEFAULT_FACTURX_TEMPLATE = 'factur-x.xml'
|
||||||
|
|
||||||
|
|
||||||
def add_facturx_from_bytes(pdf_bytes: bytes, facturx_context: dict, template: str = DEFAULT_FACTURX_TEMPLATE):
|
def add_facturx_from_bytes(
|
||||||
|
pdf_bytes: bytes,
|
||||||
|
facturx_context: dict,
|
||||||
|
template: str = DEFAULT_FACTURX_TEMPLATE,
|
||||||
|
attachments: typing.Sequence[tuple[str, bytes]] = (),
|
||||||
|
):
|
||||||
pdfa_bytes = to_pdfa(pdf_bytes)
|
pdfa_bytes = to_pdfa(pdf_bytes)
|
||||||
|
attachments_dict = {filename: {'filedata': content} for filename, content in attachments}
|
||||||
facturx_xml = str(render_to_string(template, facturx_context)).encode('utf-8')
|
facturx_xml = str(render_to_string(template, facturx_context)).encode('utf-8')
|
||||||
return facturx.generate_facturx_from_binary(pdfa_bytes, facturx_xml)
|
with tempfile.NamedTemporaryFile(prefix='invoice-facturx-', suffix='.pdf') as f:
|
||||||
|
f.write(pdfa_bytes)
|
||||||
|
facturx.generate_facturx_from_file(f, facturx_xml, attachments=attachments_dict)
|
||||||
|
f.seek(0)
|
||||||
|
result = f.read()
|
||||||
|
f.close()
|
||||||
|
return result
|
||||||
|
|
|
@ -19,6 +19,7 @@ import io
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
import facturx
|
import facturx
|
||||||
|
import pypdf
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from eo_gestion.eo_facture.facturx import add_facturx_from_bytes, to_pdfa
|
from eo_gestion.eo_facture.facturx import add_facturx_from_bytes, to_pdfa
|
||||||
|
@ -212,3 +213,39 @@ def test_add_facturx_from_bytes_facture_avoir(fake_invoice_bytes):
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# https://stackoverflow.com/questions/2438800/what-is-the-smallest-legal-zip-jar-file
|
||||||
|
MINIMAL_ZIP_FILE = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_facturx_from_bytes_with_attachments(fake_invoice_bytes):
|
||||||
|
facturx_ctx = {
|
||||||
|
'numero_de_facture': 'F20190001',
|
||||||
|
'type_facture': '380',
|
||||||
|
'date_emission': datetime.date(2019, 1, 1),
|
||||||
|
'chorus_service_code': 'service-code',
|
||||||
|
'vendeur': 'Entr\'ouvert',
|
||||||
|
'vendeur_siret': '44317013900036',
|
||||||
|
'vendeur_tvai': 'FR09491081899',
|
||||||
|
'client_siret': '1234',
|
||||||
|
'client_name': 'RGFIPD',
|
||||||
|
'numero_engagement': '5678',
|
||||||
|
'numero_marche': 'ABCD',
|
||||||
|
'montant_ht': '10',
|
||||||
|
'montant_ttc': '12',
|
||||||
|
'montant_tva': '2',
|
||||||
|
'taux_tva': 20.0,
|
||||||
|
}
|
||||||
|
attachments = [
|
||||||
|
('PJ1.zip', MINIMAL_ZIP_FILE),
|
||||||
|
('PJ2.zip', MINIMAL_ZIP_FILE),
|
||||||
|
]
|
||||||
|
|
||||||
|
facturx_bytes = add_facturx_from_bytes(fake_invoice_bytes, facturx_ctx, attachments=attachments)
|
||||||
|
|
||||||
|
pdf_reader = pypdf.PdfReader(io.BytesIO(facturx_bytes))
|
||||||
|
assert [(k, v) for k, v in pdf_reader.attachments.items() if k != 'factur-x.xml'] == [
|
||||||
|
('PJ1.zip', [MINIMAL_ZIP_FILE]),
|
||||||
|
('PJ2.zip', [MINIMAL_ZIP_FILE]),
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue