From 265e38c24f305c462a121f80faed74b2999a59c2 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Mon, 17 Oct 2022 17:20:25 +0200 Subject: [PATCH] xml erzeugen bei 40% --- .hgignore | 6 + __init__.py | 6 + edocument.py | 26 ++++ locale/de.po | 20 +++ locale/en.po | 8 ++ message.xml | 12 ++ party.py | 37 ++++++ setup.py | 2 +- template/XRechnung-2.2/XRechnung.xml | 176 +++++++++++++++++++++++++++ tests/__init__.py | 23 ++++ tests/test_edocument.py | 38 ++++++ tryton.cfg | 4 + 12 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 .hgignore create mode 100644 edocument.py create mode 100644 locale/de.po create mode 100644 locale/en.po create mode 100644 message.xml create mode 100644 party.py create mode 100644 template/XRechnung-2.2/XRechnung.xml create mode 100644 tests/__init__.py create mode 100644 tests/test_edocument.py diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..154f62a --- /dev/null +++ b/.hgignore @@ -0,0 +1,6 @@ +syntax: glob +build/* +dist/* +mds_edocument_xrechnung.egg-info/* +__pycache__/* +locale/convert_de2en.py diff --git a/__init__.py b/__init__.py index dda7be0..84ce866 100644 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,13 @@ # full copyright notices and license terms. from trytond.pool import Pool +from .edocument import Invoice +from .party import PartyConfiguration, Party + def register(): Pool.register( + Invoice, + Party, + PartyConfiguration, module='edocument_xrechnung', type_='model') diff --git a/edocument.py b/edocument.py new file mode 100644 index 0000000..57c77c6 --- /dev/null +++ b/edocument.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# This file is part of the edcoment-module for Tryton. +# The COPYRIGHT file at the top level of this repository contains the +# full copyright notices and license terms. + +import genshi.template +import os +from trytond.modules.edocument_uncefact.edocument import Invoice + + +class Invoice(Invoice): + 'EDocument XRechnung' + __name__ = 'edocument.xrechnung.invoice' + + def _get_template(self, version): + """ load our own template if 'version' is ours + """ + if version == 'XRechnung-2.2': + loader = genshi.template.TemplateLoader( + os.path.join(os.path.dirname(__file__), 'template'), + auto_reload=True) + return loader.load(os.path.join(version, 'XRechnung.xml')) + else : + return super(Invoice, self)._get_template(version) + +# end Invoice diff --git a/locale/de.po b/locale/de.po new file mode 100644 index 0000000..c06b9e6 --- /dev/null +++ b/locale/de.po @@ -0,0 +1,20 @@ +# +msgid "" +msgstr "Content-Type: text/plain; charset=utf-8\n" + + +############## +# ir.message # +############## +msgctxt "model:ir.message,text:msg_missing_xrechnung_route_id" +msgid "No XRechnung routing ID is stored for the party '%(partyname)s'." +msgstr "Für die Partei '%(partyname)s' ist keine XRechnung-Leitweg-ID hinterlegt." + + +####################### +# party.configuration # +####################### +msgctxt "selection:party.configuration,identifier_types:" +msgid "X-Rechnung Route-ID" +msgstr "X-Rechnung Leitweg-ID" + diff --git a/locale/en.po b/locale/en.po new file mode 100644 index 0000000..e074035 --- /dev/null +++ b/locale/en.po @@ -0,0 +1,8 @@ +# +msgid "" +msgstr "Content-Type: text/plain; charset=utf-8\n" + +msgctxt "selection:party.configuration,identifier_types:" +msgid "X-Rechnung Route-ID" +msgstr "X-Rechnung Route-ID" + diff --git a/message.xml b/message.xml new file mode 100644 index 0000000..7d38804 --- /dev/null +++ b/message.xml @@ -0,0 +1,12 @@ + + + + + + + No XRechnung routing ID is stored for the party '%(partyname)s'. + + + diff --git a/party.py b/party.py new file mode 100644 index 0000000..7079640 --- /dev/null +++ b/party.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# This file is part of the edcoment-module 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 +from trytond.exceptions import UserError +from trytond.i18n import gettext + + +class Party(metaclass=PoolMeta): + __name__ = 'party.party' + + def get_xrechnung_route_id(self): + """ search for route-id at party, fire-exception if missing + """ + for ident in self.identifiers: + if ident.type == 'edoc_route_id': + return ident.code + raise UserError(gettext( + 'edocument_xrechnung.msg_missing_xrechnung_route_id', + partyname = self.rec_name, + )) +# end Party + + +class PartyConfiguration(metaclass=PoolMeta): + __name__ = 'party.configuration' + + @classmethod + def __setup__(cls): + super(PartyConfiguration, cls).__setup__() + cls.identifier_types.selection.append( + ('edoc_route_id', 'X-Rechnung Route-ID') + ) + +# end Configuration diff --git a/setup.py b/setup.py index a986302..fa1f0fa 100644 --- a/setup.py +++ b/setup.py @@ -97,7 +97,7 @@ setup(name='%s_%s' % (PREFIX, MODULE), package_data={ 'trytond.modules.%s' % MODULE: (info.get('xml', []) + ['tryton.cfg', 'locale/*.po', 'tests/*.py', - 'template/*.xml','versiondep.txt', 'README.rst']), + 'template/*/*.xml','versiondep.txt', 'README.rst']), }, install_requires=requires, diff --git a/template/XRechnung-2.2/XRechnung.xml b/template/XRechnung-2.2/XRechnung.xml new file mode 100644 index 0000000..d43aa45 --- /dev/null +++ b/template/XRechnung-2.2/XRechnung.xml @@ -0,0 +1,176 @@ + + + + + ${', '.join((getattr(value, 'street', None) or '').split('\n'))} + ${getattr(value, 'city', None) or ''} + ${getattr(value, 'postal_code', None) or ''} + + ${getattr(getattr(value, 'country', None), 'code', None)} + + + + ${getattr(value, 'code', None)} + + VAT + + + + ${value.name} + ${value.phone} + ${value.email} + + + ${value.name} + ${getattr(value.tax_identifier, 'code', None)} + + + urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.1 + ${this.invoice.number} + ${this.invoice.invoice_date.isoformat()} + ${(getattr(this.invoice, 'payment_term_date', None) or this.invoice.invoice_date).isoformat()} + ${this.type_code} + ${this.invoice.currency.code} + ${this.invoice.party.get_xrechnung_route_id()} + + bestell-nr + auftrags-nr + + + vertrags-nr + + + proj-referenz + + + + + ${PostalAddress(this.seller_trade_address)} + + + ${PartyTaxScheme(this.seller_trade_tax_identifier)} + + + ${PartyLegalEntity(this.invoice.company.party)} + + + ${Contact(this.seller_trade_party)} + + + + + + + ${this.buyer_trade_party.code} + + + ${PostalAddress(this.buyer_trade_address)} + + + ${PartyTaxScheme(this.buyer_trade_tax_identifier)} + + + ${PartyLegalEntity(this.buyer_trade_party, False)} + + + ${Contact(this.buyer_trade_party)} + + + + + 30 + ${this.payment_reference} + + DE00 1234 5678 0000 1234 56 + ${this.invoice.company.party.name} + + + + ${this.invoice.payment_term.rec_name} + + + false + Neukundenrabatt + 5.00 + + S + 19.00 + + VAT + + + + + ${this.invoice.total_amount} + + 35.25 + 6.70 + + S + 19.00 + + VAT + + + + + + 40.25 + 35.25 + 41.95 + 5.00 + 0.00 + 0.00 + 41.95 + + + 1 + 0.5 + 35.00 + + Reparaturdienstleistung in Stunden + + REP-012 + + + S + 19.00 + + VAT + + + + + 70.00 + + + + 2 + 3 + 5.25 + + Material + + MAT-987 + + + S + 19.00 + + VAT + + + + + 1.75 + + + diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..173e725 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,23 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +import trytond.tests.test_tryton +import unittest + +from trytond.modules.edocument_xrechnung.tests.test_edocument import EdocTestCase + +__all__ = ['suite'] + + +class EDocumentTestCase(\ + EdocTestCase,\ + ): + 'Test edocument module' + module = 'edocument_xrechnung' + +# end EDocumentTestCase + +def suite(): + suite = trytond.tests.test_tryton.suite() + suite.addTests(unittest.TestLoader().loadTestsFromTestCase(EDocumentTestCase)) + return suite diff --git a/tests/test_edocument.py b/tests/test_edocument.py new file mode 100644 index 0000000..fcae41f --- /dev/null +++ b/tests/test_edocument.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# This file is part of the cashbook-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.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.pool import Pool +from trytond.modules.edocument_uncefact.tests.test_edocument_uncefact import get_invoice +from unittest.mock import Mock, MagicMock + + +class EdocTestCase(ModuleTestCase): + 'Test e-rechnung module' + module = 'edocument_xrechnung' + + @with_transaction() + def test_xrechn_export_xml(self): + """ run export + """ + pool = Pool() + Template = pool.get('edocument.xrechnung.invoice') + Address = pool.get('party.address') + Identifier = pool.get('party.identifier') + + invoice = get_invoice() + invoice.party.get_xrechnung_route_id = Mock(return_value='xrechn-route-id-123') + invoice.identifiers = [ + Mock(spec=Identifier, + type='edoc_route_id', + code='xrechn-route-id-123') + ] + + template = Template(invoice) + invoice_string = template.render('XRechnung-2.2') + with open('xrechnung-test.xml', 'wt') as fhdl: + fhdl.write(invoice_string.decode('utf8')) + +# end EdocTestCase diff --git a/tryton.cfg b/tryton.cfg index 913582b..fec7d8f 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -2,4 +2,8 @@ version=6.0.0 depends: edocument_uncefact + party +#extras_depend: + account_invoice xml: + message.xml