From c0bfe61f9211cffbb8284c1f19f7d21250234e56 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Fri, 22 Dec 2023 15:12:39 +0100 Subject: [PATCH 01/15] Tryton 7.0 --- README.rst | 7 +++---- setup.py | 4 ++-- tryton.cfg | 2 +- versiondep.txt | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index 03c97fa..0aac6c8 100644 --- a/README.rst +++ b/README.rst @@ -9,12 +9,11 @@ pip install mds-account-invoice-xrechnung Requires ======== -- Tryton 6.8 +- Tryton 7.0 Changes ======= -*6.8.3 - 30.06.2023* +*7.0.0 - 22.12.2023* -- compatiblity to Tryton 6.8 -- code optimized +- compatiblity to Tryton 7.0 diff --git a/setup.py b/setup.py index fce9670..d97bb36 100644 --- a/setup.py +++ b/setup.py @@ -39,8 +39,8 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f: modversion[l2[0]] = {'min': l2[1], 'max': l2[2], 'prefix': l2[3]} # tryton-version -major_version = 6 -minor_version = 8 +major_version = 7 +minor_version = 0 requires = ['python-slugify'] for dep in info.get('depends', []): diff --git a/tryton.cfg b/tryton.cfg index 93c8304..8e71a4a 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -1,5 +1,5 @@ [tryton] -version=6.8.3 +version=7.0.0 depends: account_invoice bank diff --git a/versiondep.txt b/versiondep.txt index 0785719..32b59fc 100644 --- a/versiondep.txt +++ b/versiondep.txt @@ -1 +1 @@ -edocument_xrechnung;6.8.2;6.8.999;mds +edocument_xrechnung;7.0.3;7.0.999;mds From 3ed35309838d4bdf621a709d4eeafbd1401ab9c5 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 21 Nov 2024 14:25:46 +0100 Subject: [PATCH 02/15] update gitignore --- .env | 1 + .hgignore => .gitignore | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .env rename .hgignore => .gitignore (87%) diff --git a/.env b/.env new file mode 100644 index 0000000..d0efcdf --- /dev/null +++ b/.env @@ -0,0 +1 @@ +PYTHONPATH=~/Projekte/tr70/lib/python3.10/site-packages \ No newline at end of file diff --git a/.hgignore b/.gitignore similarity index 87% rename from .hgignore rename to .gitignore index 796d378..e349607 100644 --- a/.hgignore +++ b/.gitignore @@ -1,4 +1,4 @@ -syntax: glob +*.pyc build/* dist/* mds_account_invoice_xrechnung.egg-info/* From 38295dec3573a7ac932edb10e5adf987b1a92ebe Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 21 Nov 2024 14:34:10 +0100 Subject: [PATCH 03/15] file info --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index d97bb36..3d2ee45 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,8 @@ -""" Tryton module to add xrechnung-export to invoice -""" +# -*- 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. -# Always prefer setuptools over distutils from setuptools import setup # To use a consistent encoding from codecs import open From 2dac79debe15513e3a1fc95e4c626262b1c49a51 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 21 Nov 2024 14:34:17 +0100 Subject: [PATCH 04/15] formatting --- invoice.py | 9 +++------ setup.py | 9 ++------- wizard_runreport.py | 15 +++++---------- xreport.py | 7 +++---- 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/invoice.py b/invoice.py index 108d7b0..bbdeca2 100644 --- a/invoice.py +++ b/invoice.py @@ -4,7 +4,7 @@ # this repository contains the full copyright notices and license terms. from trytond.pool import PoolMeta -from trytond.pyson import Eval, And, Or +from trytond.pyson import Eval, And, Or, Bool class InvoiceLine(metaclass=PoolMeta): @@ -17,10 +17,7 @@ class InvoiceLine(metaclass=PoolMeta): cls.unit.states['required'], And( Eval('type') == 'line', - Eval('quantity', None) != None, - ), - ) - cls.unit.depends.add('type') - cls.unit.depends.add('quantity') + Bool(Eval('quantity')))) + cls.unit.depends.update(['type', 'quantity']) # end Invoice diff --git a/setup.py b/setup.py index 3d2ee45..fa92fb4 100644 --- a/setup.py +++ b/setup.py @@ -4,14 +4,10 @@ # this repository contains the full copyright notices and license terms. from setuptools import setup -# To use a consistent encoding from codecs import open from os import path import re -try: - from configparser import ConfigParser -except ImportError: - from ConfigParser import ConfigParser +from configparser import ConfigParser here = path.abspath(path.dirname(__file__)) MODULE = 'account_invoice_xrechnung' @@ -21,7 +17,6 @@ PREFIX = 'mds' with open(path.join(here, 'README.rst'), encoding='utf-8') as f: long_description = f.read() -# tryton.cfg einlesen config = ConfigParser() config.readfp(open('tryton.cfg')) info = dict(config.items('tryton')) @@ -88,9 +83,9 @@ setup( 'Natural Language :: English', 'Operating System :: OS Independent', 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ], keywords='tryton account invoice xrechnung edocument', diff --git a/wizard_runreport.py b/wizard_runreport.py index f1876a8..79977f4 100644 --- a/wizard_runreport.py +++ b/wizard_runreport.py @@ -18,8 +18,7 @@ sel_edocument = [ edoc_versions = { 'edocument.xrechnung.invoice': 'XRechnung-2.2', - 'edocument.uncefact.invoice': '16B-CII', - } + 'edocument.uncefact.invoice': '16B-CII'} class RunXRechnungReportStart(ModelView): @@ -62,8 +61,7 @@ class RunXRechnungReport(Wizard): buttons=[ Button(string='Cancel', state='end', icon='tryton-cancel'), Button(string='Export', state='export', icon='tryton-export'), - ], - ) + ]) def default_start(self, fields): """ set defaults @@ -75,8 +73,7 @@ class RunXRechnungReport(Wizard): result = { 'edocument': 'edocument.xrechnung.invoice', 'invoice': context.get('active_id', -1), - 'state': invoice[0].state if len(invoice) > 0 else '', - } + 'state': invoice[0].state if invoice else ''} return result def do_export(self, action): @@ -85,12 +82,10 @@ class RunXRechnungReport(Wizard): if self.start.state != 'posted': raise UserError(gettext( 'account_invoice_xrechnung.msg_invoice_must_posted', - invname=self.start.invoice.rec_name, - )) + invname=self.start.invoice.rec_name)) return action, { 'invoice': self.start.invoice.id, 'edocument': self.start.edocument, - 'as_zip': self.start.as_zip, - } + 'as_zip': self.start.as_zip} # end RunXRechnungReport diff --git a/xreport.py b/xreport.py index 7a17b06..a62acbc 100644 --- a/xreport.py +++ b/xreport.py @@ -38,10 +38,9 @@ class XReport(Report): invoice_string = 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) + 'date': IrDate.today().isoformat().replace('-', ''), + 'descr': invoice.rec_name}, + max_length=100, word_boundary=True, save_order=True) if data['as_zip'] is True: return ( From eda721690701cd23e7f1a69e9e15495ee67d0007 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 5 Dec 2024 11:28:44 +0100 Subject: [PATCH 05/15] export of xrechnung 2.2 + 2.3 + 3.0 --- locale/de.po | 16 ++++++++++++++++ locale/en.po | 20 ++++++++++++++++++++ wizard_runreport.py | 16 +++++++++++----- xreport.py | 2 +- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/locale/de.po b/locale/de.po index e877610..92b2ed1 100644 --- a/locale/de.po +++ b/locale/de.po @@ -30,6 +30,22 @@ msgctxt "field:account_invoice_xrechnung.runrep.start,edocument:" msgid "Type" msgstr "Typ" +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" + msgctxt "field:account_invoice_xrechnung.runrep.start,as_zip:" msgid "ZIP-File" msgstr "ZIP-Datei" diff --git a/locale/en.po b/locale/en.po index 5d9a36b..cd77d2b 100644 --- a/locale/en.po +++ b/locale/en.po @@ -22,6 +22,22 @@ msgctxt "field:account_invoice_xrechnung.runrep.start,edocument:" msgid "Type" msgstr "Type" +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" + msgctxt "field:account_invoice_xrechnung.runrep.start,as_zip:" msgid "ZIP-File" msgstr "ZIP-File" @@ -38,3 +54,7 @@ msgctxt "wizard_button:account_invoice_xrechnung.runrep,start,export:" msgid "Export" msgstr "Export" +msgctxt "model:account_invoice_xrechnung.export,name:" +msgid "eDocument Export" +msgstr "eDocument Export" + diff --git a/wizard_runreport.py b/wizard_runreport.py index 79977f4..d182832 100644 --- a/wizard_runreport.py +++ b/wizard_runreport.py @@ -12,12 +12,16 @@ from trytond.transaction import Transaction sel_edocument = [ - ('edocument.xrechnung.invoice', 'XRechnung UBL Invoice 2.1.1'), + ('edocument.xrechnung.invoice-2.2', 'XRechnung UBL Invoice 2.2'), + ('edocument.xrechnung.invoice-2.3', 'XRechnung UBL Invoice 2.3'), + ('edocument.xrechnung.invoice-3.0', 'XRechnung UBL Invoice 3.0'), ('edocument.uncefact.invoice', 'CII CrossIndustryInvoice D16B'), ] edoc_versions = { - 'edocument.xrechnung.invoice': 'XRechnung-2.2', + 'edocument.xrechnung.invoice-2.2': 'XRechnung-2.2', + 'edocument.xrechnung.invoice-2.3': 'XRechnung-2.3', + 'edocument.xrechnung.invoice-3.0': 'XRechnung-3.0', 'edocument.uncefact.invoice': '16B-CII'} @@ -44,7 +48,7 @@ class RunXRechnungReportStart(ModelView): def default_edocument(cls): """ default xrechnung """ - return 'edocument.xrechnung.invoice' + return 'edocument.xrechnung.invoice-3.0' # end RunXRechnungReportStart @@ -67,11 +71,13 @@ class RunXRechnungReport(Wizard): """ set defaults """ context = Transaction().context - Invoice = Pool().get('account.invoice') + pool = Pool() + Invoice = pool.get('account.invoice') + WizRepStart = pool.get('account_invoice_xrechnung.runrep.start') invoice = Invoice.browse([context.get('active_id', -1)]) result = { - 'edocument': 'edocument.xrechnung.invoice', + 'edocument': WizRepStart.default_edocument(), 'invoice': context.get('active_id', -1), 'state': invoice[0].state if invoice else ''} return result diff --git a/xreport.py b/xreport.py index a62acbc..4d68e82 100644 --- a/xreport.py +++ b/xreport.py @@ -31,7 +31,7 @@ class XReport(Report): pool = Pool() IrDate = pool.get('ir.date') Invoice = pool.get('account.invoice') - EDocument = pool.get(data['edocument']) + EDocument = pool.get(data['edocument'].split('-')[0]) invoice, = Invoice.browse([data['invoice']]) template = EDocument(invoice) From 4cceb26875bbba0999a5206ee4b07c3f01f4ac9a Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 5 Dec 2024 17:31:45 +0100 Subject: [PATCH 06/15] configuration for pdf-invoice --- __init__.py | 3 +++ configuration.py | 48 +++++++++++++++++++++++++++++++++++++ configuration.xml | 15 ++++++++++++ locale/de.po | 32 +++++++++++++++++++++++++ locale/en.po | 23 ++++++++++++++++++ tryton.cfg | 1 + view/configuration_form.xml | 16 +++++++++++++ 7 files changed, 138 insertions(+) create mode 100644 configuration.py create mode 100644 configuration.xml create mode 100644 view/configuration_form.xml diff --git a/__init__.py b/__init__.py index cb86728..f5712e6 100644 --- a/__init__.py +++ b/__init__.py @@ -7,10 +7,13 @@ from trytond.pool import Pool from .wizard_runreport import RunXRechnungReport, RunXRechnungReportStart from .invoice import InvoiceLine from .xreport import XReport +from .configuration import ConfigurationXRechnungexport, Configuration def register(): Pool.register( + Configuration, + ConfigurationXRechnungexport, InvoiceLine, RunXRechnungReportStart, module='account_invoice_xrechnung', type_='model') diff --git a/configuration.py b/configuration.py new file mode 100644 index 0000000..b308c5e --- /dev/null +++ b/configuration.py @@ -0,0 +1,48 @@ +# -*- 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. + + +from trytond.pool import PoolMeta, Pool +from trytond.model import ModelSQL, fields +from trytond.modules.company.model import CompanyValueMixin + + +class Configuration(metaclass=PoolMeta): + __name__ = 'account.configuration' + + xrechn_zugferd_report = fields.MultiValue(fields.Many2One( + model_name='ir.action.report', + domain=[ + ('model', '=', 'account.invoice'), + ('extension', '=', 'pdf')], + string='ZUGFeRD-Report', + help='Report that is to be used to generate the ZUGFeRD PDF.')) + + @classmethod + def multivalue_model(cls, field): + """ select table + """ + pool = Pool() + if field in { + 'xrechn_zugferd_report'}: + return pool.get('account_invoice_xrechnung.configuration') + return super(Configuration, cls).multivalue_model(field) + +# end Configuration + + +class ConfigurationXRechnungexport(ModelSQL, CompanyValueMixin): + "Account Configuration XRechnung Export" + __name__ = 'account_invoice_xrechnung.configuration' + + xrechn_zugferd_report = fields.Many2One( + model_name='ir.action.report', + string='ZUGFeRD-Report', + domain=[ + ('model', '=', 'account.invoice'), + ('extension', '=', 'pdf')], + help='Report that is to be used to generate the ZUGFeRD PDF.') + +# end ConfigurationXRechnungexport diff --git a/configuration.xml b/configuration.xml new file mode 100644 index 0000000..fdcbe15 --- /dev/null +++ b/configuration.xml @@ -0,0 +1,15 @@ + + + + + + + account.configuration + + configuration_form + + + + diff --git a/locale/de.po b/locale/de.po index 92b2ed1..00f6e09 100644 --- a/locale/de.po +++ b/locale/de.po @@ -73,3 +73,35 @@ msgstr "Export" msgctxt "model:account_invoice_xrechnung.export,name:" msgid "eDocument Export" msgstr "eDocument Export" + + +######################### +# account.configuration # +######################### +msgctxt "view:account.configuration:" +msgid "ZUGFeRD - e-Invoice" +msgstr "ZUGFeRD - e-Rechnung" + +msgctxt "field:account.configuration,xrechn_zugferd_report:" +msgid "ZUGFeRD-Report" +msgstr "ZUGFeRD-Report" + +msgctxt "help:account.configuration,xrechn_zugferd_report:" +msgid "Report that is to be used to generate the ZUGFeRD PDF." +msgstr "Report, welcher zum erzeugen der ZUGFeRD-PDF verwendet werden soll." + + +########################################### +# account_invoice_xrechnung.configuration # +########################################### +msgctxt "model:account_invoice_xrechnung.configuration:" +msgid "Account Configuration XRechnung Export" +msgstr "Buchhaltung Konfiguration XRechnung Export" + +msgctxt "field:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" +msgid "ZUGFeRD-Report" +msgstr "ZUGFeRD-Report" + +msgctxt "help:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" +msgid "Report that is to be used to generate the ZUGFeRD PDF." +msgstr "Report, welcher zum erzeugen der ZUGFeRD-PDF verwendet werden soll." diff --git a/locale/en.po b/locale/en.po index cd77d2b..c6ad0ce 100644 --- a/locale/en.po +++ b/locale/en.po @@ -58,3 +58,26 @@ msgctxt "model:account_invoice_xrechnung.export,name:" msgid "eDocument Export" msgstr "eDocument Export" +msgctxt "view:account.configuration:" +msgid "ZUGFeRD - e-Invoice" +msgstr "ZUGFeRD - e-Invoice" + +msgctxt "field:account.configuration,xrechn_zugferd_report:" +msgid "ZUGFeRD-Report" +msgstr "ZUGFeRD-Report" + +msgctxt "help:account.configuration,xrechn_zugferd_report:" +msgid "Report that is to be used to generate the ZUGFeRD PDF." +msgstr "Report that is to be used to generate the ZUGFeRD PDF." + +msgctxt "model:account_invoice_xrechnung.configuration:" +msgid "Account Configuration XRechnung Export" +msgstr "Account Configuration XRechnung Export" + +msgctxt "field:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" +msgid "ZUGFeRD-Report" +msgstr "ZUGFeRD-Report" + +msgctxt "help:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" +msgid "Report that is to be used to generate the ZUGFeRD PDF." +msgstr "Report that is to be used to generate the ZUGFeRD PDF." diff --git a/tryton.cfg b/tryton.cfg index 8e71a4a..272e243 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -6,5 +6,6 @@ depends: edocument_xrechnung xml: message.xml + configuration.xml wizard_runreport.xml xreport.xml diff --git a/view/configuration_form.xml b/view/configuration_form.xml new file mode 100644 index 0000000..94b22b3 --- /dev/null +++ b/view/configuration_form.xml @@ -0,0 +1,16 @@ + + + + + + + + + + From 3385e55c639a7ca5f32fb55c494140a19207948f Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 5 Dec 2024 17:32:40 +0100 Subject: [PATCH 07/15] add selection for factur-x --- locale/de.po | 8 ++++++++ locale/en.po | 8 ++++++++ setup.py | 2 +- versiondep.txt | 2 +- wizard_runreport.py | 4 ++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/locale/de.po b/locale/de.po index 00f6e09..ff22ba4 100644 --- a/locale/de.po +++ b/locale/de.po @@ -46,6 +46,14 @@ msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" msgid "CII CrossIndustryInvoice D16B" msgstr "CII CrossIndustryInvoice D16B" +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + msgctxt "field:account_invoice_xrechnung.runrep.start,as_zip:" msgid "ZIP-File" msgstr "ZIP-Datei" diff --git a/locale/en.po b/locale/en.po index c6ad0ce..ad72eda 100644 --- a/locale/en.po +++ b/locale/en.po @@ -38,6 +38,14 @@ msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" msgid "CII CrossIndustryInvoice D16B" msgstr "CII CrossIndustryInvoice D16B" +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account_invoice_xrechnung.runrep.start,edocument:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + msgctxt "field:account_invoice_xrechnung.runrep.start,as_zip:" msgid "ZIP-File" msgstr "ZIP-File" diff --git a/setup.py b/setup.py index fa92fb4..645635e 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f: major_version = 7 minor_version = 0 -requires = ['python-slugify'] +requires = ['python-slugify', 'pypdf', 'factur-x'] for dep in info.get('depends', []): if not re.match(r'(ir|res|webdav)(\W|$)', dep): if dep in modversion.keys(): diff --git a/versiondep.txt b/versiondep.txt index 32b59fc..258b3ff 100644 --- a/versiondep.txt +++ b/versiondep.txt @@ -1 +1 @@ -edocument_xrechnung;7.0.3;7.0.999;mds +edocument_xrechnung;7.0.5;7.0.999;mds diff --git a/wizard_runreport.py b/wizard_runreport.py index d182832..f84f2a8 100644 --- a/wizard_runreport.py +++ b/wizard_runreport.py @@ -15,6 +15,8 @@ sel_edocument = [ ('edocument.xrechnung.invoice-2.2', 'XRechnung UBL Invoice 2.2'), ('edocument.xrechnung.invoice-2.3', 'XRechnung UBL Invoice 2.3'), ('edocument.xrechnung.invoice-3.0', 'XRechnung UBL Invoice 3.0'), + ('edocument.facturxext.invoice', 'Factur-X Extended'), + ('edocument.facturxext.invoice-ferd', 'ZUGFeRD 2.3.2'), ('edocument.uncefact.invoice', 'CII CrossIndustryInvoice D16B'), ] @@ -22,6 +24,8 @@ edoc_versions = { 'edocument.xrechnung.invoice-2.2': 'XRechnung-2.2', 'edocument.xrechnung.invoice-2.3': 'XRechnung-2.3', 'edocument.xrechnung.invoice-3.0': 'XRechnung-3.0', + 'edocument.facturxext.invoice': 'Factur-X-1.07.2-extended', + 'edocument.facturxext.invoice-ferd': 'Factur-X-1.07.2-extended', 'edocument.uncefact.invoice': '16B-CII'} From 34f3922a44bfe27d787e50b4ef71dddc7a9907cd Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Thu, 5 Dec 2024 17:32:56 +0100 Subject: [PATCH 08/15] prepare zugferd --- tests/test_invoice.py | 136 ++++++++++++++++++++++++++++++++++++++++-- xreport.py | 27 +++++++-- 2 files changed, 155 insertions(+), 8 deletions(-) diff --git a/tests/test_invoice.py b/tests/test_invoice.py index a30b98f..9ecaf34 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -3,18 +3,146 @@ # from m-ds for Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +from decimal import Decimal +from datetime import date from trytond.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.pool import Pool +from trytond.transaction import Transaction +from trytond.modules.company.tests import create_company, set_company +from trytond.modules.account.tests import create_chart, get_fiscalyear + + +def set_invoice_sequences(fiscalyear): + pool = Pool() + Sequence = pool.get('ir.sequence.strict') + SequenceType = pool.get('ir.sequence.type') + InvoiceSequence = pool.get('account.fiscalyear.invoice_sequence') + ModelData = pool.get('ir.model.data') + + sequence = Sequence( + name=fiscalyear.name, + sequence_type=SequenceType(ModelData.get_id( + 'account_invoice', 'sequence_type_account_invoice')), + company=fiscalyear.company, + ) + sequence.save() + fiscalyear.invoice_sequences = [] + invoice_sequence = InvoiceSequence() + invoice_sequence.fiscalyear = fiscalyear + invoice_sequence.in_invoice_sequence = sequence + invoice_sequence.in_credit_note_sequence = sequence + invoice_sequence.out_invoice_sequence = sequence + invoice_sequence.out_credit_note_sequence = sequence + invoice_sequence.save() + return fiscalyear class InvoiceTestCase(ModuleTestCase): 'Test invoice module' module = 'account_invoice_xrechnung' - @with_transaction() - def test_xrechnung(self): - """ run default tests + def prep_fiscalyear(self, company1): + """ prepare fiscal year, sequences... """ - pass + pool = Pool() + FiscalYear = pool.get('account.fiscalyear') + + fisc_year = get_fiscalyear(company1, today=date(2024, 1, 15)) + set_invoice_sequences(fisc_year) + self.assertEqual(len(fisc_year.invoice_sequences), 1) + FiscalYear.create_period([fisc_year]) + + def prep_invoice(self, party_customer): + """ add invoice + """ + pool = Pool() + Invoice = pool.get('account.invoice') + Taxes = pool.get('account.tax') + Account = pool.get('account.account') + Journal = pool.get('account.journal') + Currency = pool.get('currency.currency') + Uom = pool.get('product.uom') + + currency1, = Currency.search([('code', '=', 'usd')]) + + tax_lst = Taxes.search([('name', '=', '20% VAT')]) + self.assertEqual(len(tax_lst), 1) + + account_lst = Account.search([ + ('name', 'in', ['Main Revenue', 'Main Receivable']) + ], order=[('name', 'ASC')]) + self.assertEqual(len(account_lst), 2) + self.assertEqual(account_lst[0].name, 'Main Receivable') + + journ_lst = Journal.search([('name', '=', 'Revenue')]) + self.assertEqual(len(journ_lst), 1) + + to_create_invoice = [{ + 'type': 'out', + 'description': 'Parts', + 'invoice_date': date(2024, 7, 1), + 'party': party_customer.id, + 'invoice_address': party_customer.addresses[0].id, + 'account': account_lst[0].id, + 'journal': journ_lst[0].id, + 'currency': currency1.id, + 'lines': [('create', [{ + 'type': 'line', + 'quantity': 2.0, + 'unit': Uom.search([('symbol', '=', 'u')])[0].id, + 'unit_price': Decimal('50.0'), + 'taxes': [('add', [tax_lst[0].id])], + 'account': account_lst[1].id, + 'currency': currency1.id, + }])], + }] + inv_lst, = Invoice.create(to_create_invoice) + inv_lst.on_change_lines() + inv_lst.save() + Invoice.validate_invoice([inv_lst]) + Invoice.post([inv_lst]) + self.assertEqual(inv_lst.currency.code, 'usd') + self.assertEqual(len(inv_lst.move.lines), 3) + return inv_lst + + @with_transaction() + def test_xrechnung_configuration(self): + """ test configuration + """ + pool = Pool() + Configuration = pool.get('account.configuration') + Party = pool.get('party.party') + ActionReport = pool.get('ir.action.report') + + pty1, = Party.create([{ + 'name': 'Payee', + 'addresses': [('create', [{ + 'invoice': True, + 'street': 'Applicant Street 1', + 'postal_code': '12345', + 'city': 'Usertown', + }])], + }]) + + company1 = create_company('m-ds') + with set_company(company1): + with Transaction().set_context({'company': company1.id}): + + # update report to 'pdf' + inv_report, = ActionReport.search([ + ('model', '=', 'account.invoice'), + ('report_name', '=', 'account.invoice')]) + self.assertEqual(inv_report.extension, '') + ActionReport.write(*[ + [inv_report], {'extension': 'pdf'}]) + + cfg1 = Configuration(xrechn_zugferd_report=inv_report) + cfg1.save() + self.assertEqual(cfg1.xrechn_zugferd_report.name, 'Invoice') + create_chart(company=company1, tax=True) + self.prep_fiscalyear(company1) + invoice = self.prep_invoice(pty1) + # end InvoiceTestCase diff --git a/xreport.py b/xreport.py index 4d68e82..77715ad 100644 --- a/xreport.py +++ b/xreport.py @@ -4,6 +4,7 @@ # this repository contains the full copyright notices and license terms. import zipfile +from facturx import generate_from_binary from io import BytesIO from trytond.report import Report from trytond.pool import Pool @@ -31,27 +32,45 @@ class XReport(Report): pool = Pool() IrDate = pool.get('ir.date') Invoice = pool.get('account.invoice') - EDocument = pool.get(data['edocument'].split('-')[0]) + document_para = pool.get(data['edocument'].split('-')[0]) + + EDocument = document_para[0] + document_var = document_para[1] if len(document_para) > 1 else None invoice, = Invoice.browse([data['invoice']]) template = EDocument(invoice) - invoice_string = template.render(edoc_versions[data['edocument']]) + 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 + # pdf_data = generate_from_binary( + # pdf_file='pdf_content', + # xml=invoice_xml, + # check_xsd=True, + # pdf_metadata={ + # 'author': invoice.company.rec_name, + # 'keywords': 'Factur-X, Invoice', + # 'title': invoice.number, + # 'subject': invoice.description}, + # lang='de-DE') + if data['as_zip'] is True: return ( 'zip', cls.compress_as_zip('%(fname)s.%(ext)s' % { 'fname': file_name, 'ext': 'xml', - }, invoice_string), + }, invoice_xml), False, file_name) else: - return ('xml', invoice_string, False, file_name) + return ('xml', invoice_xml, False, file_name) # end XReport From 26388d3816716aff85292af49d52392ff38a0ffa Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Fri, 6 Dec 2024 14:03:51 +0100 Subject: [PATCH 09/15] configuration - add erechnung default report --- configuration.py | 18 +++++++++-- locale/de.po | 64 +++++++++++++++++++++++++++++++++++++ locale/en.po | 64 +++++++++++++++++++++++++++++++++++++ view/configuration_form.xml | 3 +- 4 files changed, 146 insertions(+), 3 deletions(-) diff --git a/configuration.py b/configuration.py index b308c5e..f4bedb2 100644 --- a/configuration.py +++ b/configuration.py @@ -7,11 +7,15 @@ from trytond.pool import PoolMeta, Pool from trytond.model import ModelSQL, fields from trytond.modules.company.model import CompanyValueMixin +from .wizard_runreport import sel_edocument class Configuration(metaclass=PoolMeta): __name__ = 'account.configuration' + xrechn_default = fields.MultiValue(fields.Selection( + string='Export mode', selection=sel_edocument, + help='Pre-set export format for e-invoices.')) xrechn_zugferd_report = fields.MultiValue(fields.Many2One( model_name='ir.action.report', domain=[ @@ -25,11 +29,14 @@ class Configuration(metaclass=PoolMeta): """ select table """ pool = Pool() - if field in { - 'xrechn_zugferd_report'}: + if field in {'xrechn_zugferd_report', 'xrechn_default'}: return pool.get('account_invoice_xrechnung.configuration') return super(Configuration, cls).multivalue_model(field) + @classmethod + def default_xrechn_default(cls, **pattern): + return cls.multivalue_model('xrechn_default').default_xrechn_default() + # end Configuration @@ -37,6 +44,9 @@ class ConfigurationXRechnungexport(ModelSQL, CompanyValueMixin): "Account Configuration XRechnung Export" __name__ = 'account_invoice_xrechnung.configuration' + xrechn_default = fields.Selection( + string='Export mode', selection=sel_edocument, + help='Pre-set export format for e-invoices.') xrechn_zugferd_report = fields.Many2One( model_name='ir.action.report', string='ZUGFeRD-Report', @@ -45,4 +55,8 @@ class ConfigurationXRechnungexport(ModelSQL, CompanyValueMixin): ('extension', '=', 'pdf')], help='Report that is to be used to generate the ZUGFeRD PDF.') + @classmethod + def default_xrechn_default(cls, **pattern): + return 'edocument.facturxext.invoice-ferd' + # end ConfigurationXRechnungexport diff --git a/locale/de.po b/locale/de.po index ff22ba4..ee1a86c 100644 --- a/locale/de.po +++ b/locale/de.po @@ -98,6 +98,38 @@ msgctxt "help:account.configuration,xrechn_zugferd_report:" msgid "Report that is to be used to generate the ZUGFeRD PDF." msgstr "Report, welcher zum erzeugen der ZUGFeRD-PDF verwendet werden soll." +msgctxt "field:account.configuration,xrechn_default:" +msgid "Export mode" +msgstr "Exportformat" + +msgctxt "help:account.configuration,xrechn_default:" +msgid "Pre-set export format for e-invoices." +msgstr "Voreingstelltes Exportformat für die eRechnung." + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" + ########################################### # account_invoice_xrechnung.configuration # @@ -113,3 +145,35 @@ msgstr "ZUGFeRD-Report" msgctxt "help:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" msgid "Report that is to be used to generate the ZUGFeRD PDF." msgstr "Report, welcher zum erzeugen der ZUGFeRD-PDF verwendet werden soll." + +msgctxt "field:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Export mode" +msgstr "Exportformat" + +msgctxt "help:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Pre-set export format for e-invoices." +msgstr "Voreingstelltes Exportformat für die eRechnung." + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" diff --git a/locale/en.po b/locale/en.po index ad72eda..305b6db 100644 --- a/locale/en.po +++ b/locale/en.po @@ -78,6 +78,38 @@ msgctxt "help:account.configuration,xrechn_zugferd_report:" msgid "Report that is to be used to generate the ZUGFeRD PDF." msgstr "Report that is to be used to generate the ZUGFeRD PDF." +msgctxt "field:account.configuration,xrechn_default:" +msgid "Export mode" +msgstr "Export mode" + +msgctxt "help:account.configuration,xrechn_default:" +msgid "Pre-set export format for e-invoices." +msgstr "Pre-set export format for e-invoices." + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + +msgctxt "selection:account.configuration,xrechn_default:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" + msgctxt "model:account_invoice_xrechnung.configuration:" msgid "Account Configuration XRechnung Export" msgstr "Account Configuration XRechnung Export" @@ -89,3 +121,35 @@ msgstr "ZUGFeRD-Report" msgctxt "help:account_invoice_xrechnung.configuration,xrechn_zugferd_report:" msgid "Report that is to be used to generate the ZUGFeRD PDF." msgstr "Report that is to be used to generate the ZUGFeRD PDF." + +msgctxt "field:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Export mode" +msgstr "Export mode" + +msgctxt "help:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Pre-set export format for e-invoices." +msgstr "Pre-set export format for e-invoices." + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.2" +msgstr "XRechnung UBL Invoice 2.2" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 2.3" +msgstr "XRechnung UBL Invoice 2.3" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "XRechnung UBL Invoice 3.0" +msgstr "XRechnung UBL Invoice 3.0" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "Factur-X Extended" +msgstr "Factur-X Extended" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "ZUGFeRD 2.3.2" +msgstr "ZUGFeRD 2.3.2" + +msgctxt "selection:account_invoice_xrechnung.configuration,xrechn_default:" +msgid "CII CrossIndustryInvoice D16B" +msgstr "CII CrossIndustryInvoice D16B" diff --git a/view/configuration_form.xml b/view/configuration_form.xml index 94b22b3..9e4b01f 100644 --- a/view/configuration_form.xml +++ b/view/configuration_form.xml @@ -9,7 +9,8 @@