# -*- 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