account_invoice_xrechnung/xreport.py
2024-12-06 14:04:35 +01:00

142 lines
4.7 KiB
Python

# -*- coding: utf-8 -*-
# This file is part of the account-invoice-xrechnung-module
# from m-ds for Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import zipfile
from facturx import generate_from_binary
from io import BytesIO
from slugify import slugify
from trytond.report import Report
from trytond.pool import Pool
from trytond.exceptions import UserError
from trytond.i18n import gettext
from .wizard_runreport import edoc_versions
class XReport(Report):
'eDocument Export'
__name__ = 'account_invoice_xrechnung.export'
@classmethod
def compress_as_zip(cls, fname, data):
""" compress
"""
content = BytesIO()
with zipfile.ZipFile(content, 'w') as content_zip:
content_zip.writestr(fname, data)
return content.getvalue()
@classmethod
def execute(cls, ids, data):
""" skip export-engine, run edocument-xml-convert
"""
def export_data(exp_content, fname, ext, data2):
""" get tuple to return from report.execute,
Args:
exp_content (bytes or str): result data of report
fname (str): file name
ext (str): extension
data2 (dict): data
Returns:
tuple: return value of report
"""
if data2['as_zip'] is True:
return (
'zip',
cls.compress_as_zip(
'%(fname)s.%(ext)s' % {
'fname': fname, 'ext': ext},
exp_content),
False,
file_name)
else:
return (ext, exp_content, False, fname)
pool = Pool()
IrDate = pool.get('ir.date')
Invoice = pool.get('account.invoice')
document_para = data['edocument'].split('-')
EDocument = pool.get(document_para[0])
document_var = document_para[1] if len(document_para) > 1 else None
invoice, = Invoice.browse([data['invoice']])
template = EDocument(invoice)
invoice_xml = template.render(edoc_versions[data['edocument']])
file_name = slugify('%(date)s-%(descr)s' % {
'date': IrDate.today().isoformat().replace('-', ''),
'descr': invoice.rec_name},
max_length=100, word_boundary=True, save_order=True)
if document_var and (
document_var == 'ferd') and (
EDocument.__name__ == 'edocument.facturxext.invoice'):
# convert to zugferd
invoice_pdf = cls.get_zugferd_pdf(invoice, invoice_xml)
return export_data(invoice_pdf, file_name, 'pdf', data)
else:
return export_data(invoice_xml, file_name, 'xml', data)
@classmethod
def get_used_report(cls):
""" get report to use from config
Raises:
UserError: if not report was found
Returns:
record: ir.action.report
"""
pool = Pool()
Configuration = pool.get('account.configuration')
ActionReport = pool.get('ir.action.report')
cfg1 = Configuration.get_singleton()
act_report = None
if cfg1 and cfg1.xrechn_zugferd_report:
act_report = cfg1.xrechn_zugferd_report
else:
# no report defined, use 1st found
act_report = ActionReport.search([
('model', '=', 'account.invoice'),
('extension', '=', 'pdf')], count=1)
if act_report:
act_report = act_report[0]
if not act_report:
raise UserError(gettext(
'account_invoice_xrechnung.msg_no_report_found'))
return act_report
@classmethod
def get_zugferd_pdf(cls, invoice, invoice_xml):
""" generate ZugFeRD-PDF
Args:
invoice (record): model account.invoice
invoice_xml (str): xml-data
"""
# pdf was already stored to db
if not (invoice.invoice_report_cache and (
invoice.invoice_report_format == 'pdf')):
raise UserError(gettext(
'account_invoice_xrechnung.msg_invalid_cachecontent',
invoice_name=invoice.rec_name))
zugferd_pdf = generate_from_binary(
pdf_file=invoice.invoice_report_cache,
xml=invoice_xml,
check_xsd=True,
pdf_metadata={
'author': invoice.company.rec_name,
'keywords': 'Factur-X, Invoice, Tryton',
'title': invoice.number,
'subject': invoice.description},
lang='de-DE')
return zugferd_pdf
# end XReport