Compare commits

..

1 commit

Author SHA1 Message Date
Frederik Jaeckel
a5bf930e55 update license 2025-05-02 14:16:47 +02:00
20 changed files with 76 additions and 96 deletions

View file

@ -1,7 +1,5 @@
Copyright (C) 2015-2023 Cédric Krier.
Copyright (C) 2015-2023 B2CK SPRL.
Copyright (C) 2021-2024 martin-data services.
Copyright (C) 2024 Mathias Behrle
Copyright (C) 2021-2025 martin-data services.
Copyright (C) 2024-2025 Mathias Behrle
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View file

@ -9,38 +9,37 @@ pip install mds-edocument-xrechnung
Requires
========
- Tryton 5.0
- Tryton 7.0
Changes
=======
- handle tax childs (Jan Grasnick <jan@mittelwind.de>)
- fix: rounding of unit_price at invoice-line
*5.0.14 - 29.01.2025*
- updt: optimize rounding of unit_price
*5.0.11 - 19.12.2024*
- Lookup parent taxes for unece tax codes.
- Improve the help text of xrechnung_routeid. Correct a translation.
(Mathias Behrle <mathiasb@m9s.biz>)
*5.0.10 - 17.12.2024*
*7.0.10 - 12.12.2024*
- fix missing views
- Remove arguments in super() calls. (Mathias Behrle)
*5.0.9 - 11.12.2024*
*7.0.9 - 11.12.2024*
- fix name of party in exceptions
*5.0.8 - 11.12.2024*
*7.0.7 - 10.12.2024*
- fix setup
- add iban to xml-export
*5.0.7 - 10.12.2024*
*7.0.6 - 09.12.2024*
- compatibility to Tryton 5.0
- add: export of factur-x 1.07.2, XRechnung 2.3 + 3.0
- add: check for valid data to generate xml
*7.0.5 - 05.12.2024*
- add: export Factur-X 1.07.2
*7.0.4 - 05.12.2024*
- add: export XRechnung 2.3 + 3.0
- updt: xrechnung-route-id optional
*7.0.3 - 22.12.2023*
- compatibility to Tryton 7.0

View file

@ -6,7 +6,7 @@
from trytond.pool import Pool
from .edocument import XRechnung, FacturX
from .bank import AccountNumber
from .party import Party, PartyIdentifier
from .party import PartyConfiguration, Party
from .configuration import Configuration, BankEdocumentRel
@ -18,5 +18,5 @@ def register():
BankEdocumentRel,
FacturX,
Party,
PartyIdentifier,
PartyConfiguration,
module='edocument_xrechnung', type_='model')

View file

@ -46,7 +46,7 @@ msgstr "Für die Adresse der Partei '%(party)s' ist kein Land festgelegt."
#######################
# party.configuration #
#######################
msgctxt "selection:party.identifier,type:"
msgctxt "selection:party.configuration,identifier_types:"
msgid "X-Rechnung Route-ID"
msgstr "X-Rechnung Leitweg-ID"

View file

@ -38,7 +38,7 @@ msgctxt "model:ir.message,text:msg_no_address_country"
msgid "No country is specified for the address of the party '%(party)s'."
msgstr "No country is specified for the address of the party '%(party)s'."
msgctxt "selection:party.identifier,type:"
msgctxt "selection:party.configuration,identifier_types:"
msgid "X-Rechnung Route-ID"
msgstr "X-Rechnung Route-ID"
@ -50,6 +50,10 @@ msgctxt "field:party.party,xrechnung_routeid:"
msgid "X-Rechnung Route-ID"
msgstr "X-Rechnung Route-ID"
msgctxt "help:party.party,xrechnung_routeid:"
msgid "Enables the need for an XRechnung route ID at the party for exporting the XRechnung."
msgstr "Enables the need for an XRechnung route ID at the party for exporting the XRechnung."
msgctxt "field:account.tax,xrtax_category:"
msgid "Tax Category"
msgstr "Tax Category"

View file

@ -7,18 +7,10 @@
from decimal import Decimal
import html
from trytond.exceptions import UserError
from trytond.modules.tryton6_backport.i18n import gettext
from cached_property import cached_property
from trytond.i18n import gettext
from trytond.tools import cached_property
from trytond.pool import Pool
from trytond.modules.product import price_digits
def round_price(value, rounding=None):
"Round price using the price digits"
if isinstance(value, int):
return Decimal(value)
return value.quantize(
Decimal(1) / 10 ** price_digits[1], rounding=rounding)
from trytond.modules.product import round_price
class EdocumentMixin(object):

View file

@ -5,22 +5,10 @@
from trytond.pool import PoolMeta
from trytond.exceptions import UserError
from trytond.modules.tryton6_backport.i18n import gettext
from trytond.i18n import gettext
from trytond.model import fields
class PartyIdentifier(metaclass=PoolMeta):
__name__ = 'party.identifier'
@classmethod
def __setup__(cls):
super(PartyIdentifier, cls).__setup__()
cls.type.selection.append(
('edoc_route_id', 'X-Rechnung Route-ID'))
# end PartyIdentifier
class Party(metaclass=PoolMeta):
__name__ = 'party.party'
@ -64,3 +52,15 @@ class Party(metaclass=PoolMeta):
record.get_xrechnung_route_id()
# end Party
class PartyConfiguration(metaclass=PoolMeta):
__name__ = 'party.configuration'
@classmethod
def __setup__(cls):
super().__setup__()
cls.identifier_types.selection.append(
('edoc_route_id', 'X-Rechnung Route-ID'))
# end Configuration

View file

@ -13,11 +13,9 @@ here = path.abspath(path.dirname(__file__))
MODULE = 'edocument_xrechnung'
PREFIX = 'mds'
# Get the long description from the README file
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'))
@ -36,7 +34,7 @@ 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 = 5
major_version = 7
minor_version = 0
requires = []
@ -84,11 +82,11 @@ setup(
'Natural Language :: English',
'Operating System :: OS Independent',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
],
keywords='tryton xrechnung edcoument',

View file

@ -24,7 +24,7 @@ this repository contains the full copyright notices and license terms. -->
</ram:SpecifiedTaxRegistration>
</py:def>
<py:def function="TradeAddress(address)">
<ram:PostcodeCode py:if="address.zip">${address.zip}</ram:PostcodeCode>
<ram:PostcodeCode py:if="address.postal_code">${address.postal_code}</ram:PostcodeCode>
<py:with vars="lines = (address.street or '').splitlines()">
<ram:LineOne py:if="len(lines) > 0">${this.quote_text(lines[0])}</ram:LineOne>
<ram:LineTwo py:if="len(lines) > 1">${this.quote_text(lines[1])}</ram:LineTwo>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.amount}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${value.amount}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>
@ -90,7 +90,7 @@
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.1</cbc:CustomizationID>
<cbc:ID>${this.invoice.number}</cbc:ID>
<cbc:IssueDate>${this.invoice.invoice_date.isoformat()}</cbc:IssueDate>
<cbc:DueDate>${this.invoice.invoice_date.isoformat()}</cbc:DueDate>
<cbc:DueDate>${(this.invoice.payment_term_date or this.invoice.invoice_date).isoformat()}</cbc:DueDate>
<cbc:InvoiceTypeCode>${this.type_code}</cbc:InvoiceTypeCode>
<cbc:Note py:if="this.invoice_note()">${this.invoice_note()}</cbc:Note>
<cbc:DocumentCurrencyCode>${this.invoice.currency.code}</cbc:DocumentCurrencyCode>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.amount}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${value.amount}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>
@ -90,7 +90,7 @@
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.3</cbc:CustomizationID>
<cbc:ID>${this.invoice.number}</cbc:ID>
<cbc:IssueDate>${this.invoice.invoice_date.isoformat()}</cbc:IssueDate>
<cbc:DueDate>${this.invoice.invoice_date.isoformat()}</cbc:DueDate>
<cbc:DueDate>${(this.invoice.payment_term_date or this.invoice.invoice_date).isoformat()}</cbc:DueDate>
<cbc:InvoiceTypeCode>${this.type_code}</cbc:InvoiceTypeCode>
<cbc:Note py:if="this.invoice_note()">${this.invoice_note()}</cbc:Note>
<cbc:DocumentCurrencyCode>${this.invoice.currency.code}</cbc:DocumentCurrencyCode>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.base)}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${this.negate_amount(value.amount)}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>

View file

@ -59,8 +59,8 @@
<py:def function="TaxSubTotal(value)">
<cac:TaxSubtotal>
<cbc:TaxableAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.invoice.currency.code}">${value.amount}</cbc:TaxAmount>
<cbc:TaxableAmount py:attrs="{'currencyID': value.currency.code}">${value.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID': value.currency.code}">${value.amount}</cbc:TaxAmount>
<cac:TaxCategory>
${TaxCategory(value.tax, True)}
</cac:TaxCategory>
@ -90,7 +90,7 @@
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0</cbc:CustomizationID>
<cbc:ID>${this.invoice.number}</cbc:ID>
<cbc:IssueDate>${this.invoice.invoice_date.isoformat()}</cbc:IssueDate>
<cbc:DueDate>${this.invoice.invoice_date.isoformat()}</cbc:DueDate>
<cbc:DueDate>${(this.invoice.payment_term_date or this.invoice.invoice_date).isoformat()}</cbc:DueDate>
<cbc:InvoiceTypeCode>${this.type_code}</cbc:InvoiceTypeCode>
<cbc:Note py:if="this.invoice_note()">${this.invoice_note()}</cbc:Note>
<cbc:DocumentCurrencyCode>${this.invoice.currency.code}</cbc:DocumentCurrencyCode>

View file

@ -2,17 +2,3 @@
# This file is part of the edocument-module for Tryton from m-ds.de.
# 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 .test_edocument import EdocTestCase
__all__ = ['suite']
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
EdocTestCase))
return suite

View file

@ -17,10 +17,15 @@ from trytond.exceptions import UserError
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, code='account.invoice')
sequence.company = fiscalyear.company
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()
@ -100,7 +105,7 @@ class EdocTestCase(ModuleTestCase):
'addresses': [('create', [{
'invoice': True,
'street': 'Customer Street 1',
'zip': '12345',
'postal_code': '12345',
'city': 'Usertown',
'country': country_de.id,
}])],

View file

@ -1,11 +1,10 @@
[tryton]
version=5.0.14
version=7.0.10
depends:
edocument_uncefact
party
bank
account_invoice
tryton6_backport
xml:
message.xml
configuration.xml

View file

@ -1,2 +1 @@
tryton6_backport;5.0.3;5.0.999;mds
edocument_uncefact;5.0.6;5.0.999;mds

View file

@ -4,7 +4,7 @@
full copyright notices and license terms. -->
<data>
<xpath expr="/form/separator[@id='invoice']" position="before">
<xpath expr="/form/separator[@id='currency_exchange']" position="before">
<separator id="edocument" colspan="4" string="eDocument"/>
<field name="edocument_bank" colspan="2" height="200"/>