[ADD] l10n_es_edi_facturae_invoice_period: invoice periods for EDI

Patch module to add missing fields to the factura-e xml.

task-3673113

closes odoo/odoo#149362

Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
Ali Alfie (alal)
2024-01-23 22:51:50 +00:00
parent ff2906aaf0
commit ba1706eca1
10 changed files with 398 additions and 0 deletions
@@ -0,0 +1 @@
from . import models
@@ -0,0 +1,16 @@
{
'name': 'Spain - Facturae EDI - Invoice Period',
'version': '1.0',
'description': """
Patch module to add the missing Invoice Period in the Facturae EDI.
""",
'license': 'LGPL-3',
'category': 'Accounting/Localizations/EDI',
'depends': [
'l10n_es_edi_facturae',
],
'data': [
'views/account_move_views.xml',
],
'auto_install': True,
}
@@ -0,0 +1,41 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * l10n_es_edi_facturae_invoice_period
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-23 13:35+0000\n"
"PO-Revision-Date: 2024-01-23 13:35+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: l10n_es_edi_facturae_invoice_period
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_facturae_invoice_period.view_move_form
msgid "Factura-e"
msgstr ""
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_bank_statement_line__l10n_es_invoicing_period_end_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_move__l10n_es_invoicing_period_end_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_payment__l10n_es_invoicing_period_end_date
msgid "Invoice Period End Date"
msgstr "Fecha final del periodo de facturación"
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_bank_statement_line__l10n_es_invoicing_period_start_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_move__l10n_es_invoicing_period_start_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_payment__l10n_es_invoicing_period_start_date
msgid "Invoice Period Start Date"
msgstr "Fecha de inicio del periodo de facturación"
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model,name:l10n_es_edi_facturae_invoice_period.model_account_move
msgid "Journal Entry"
msgstr "Asiento contable"
@@ -0,0 +1,40 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * l10n_es_edi_facturae_invoice_period
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-23 13:35+0000\n"
"PO-Revision-Date: 2024-01-23 13:35+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: l10n_es_edi_facturae_invoice_period
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_facturae_invoice_period.view_move_form
msgid "Factura-e"
msgstr ""
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_bank_statement_line__l10n_es_invoicing_period_end_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_move__l10n_es_invoicing_period_end_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_payment__l10n_es_invoicing_period_end_date
msgid "Invoice Period End Date"
msgstr ""
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_bank_statement_line__l10n_es_invoicing_period_start_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_move__l10n_es_invoicing_period_start_date
#: model:ir.model.fields,field_description:l10n_es_edi_facturae_invoice_period.field_account_payment__l10n_es_invoicing_period_start_date
msgid "Invoice Period Start Date"
msgstr ""
#. module: l10n_es_edi_facturae_invoice_period
#: model:ir.model,name:l10n_es_edi_facturae_invoice_period.model_account_move
msgid "Journal Entry"
msgstr ""
@@ -0,0 +1 @@
from . import account_move
@@ -0,0 +1,19 @@
from odoo import fields, models
class AccountMove(models.Model):
_inherit = 'account.move'
l10n_es_invoicing_period_start_date = fields.Date(string="Invoice Period Start Date")
l10n_es_invoicing_period_end_date = fields.Date(string="Invoice Period End Date")
def _l10n_es_edi_facturae_export_facturae(self):
# EXTENDS l10n_es_edi_facturae
template_values, signature_values = super()._l10n_es_edi_facturae_export_facturae()
invoicing_period = {
'StartDate': self.l10n_es_invoicing_period_start_date,
'EndDate': self.l10n_es_invoicing_period_end_date,
} if self.l10n_es_invoicing_period_start_date and self.l10n_es_invoicing_period_end_date else None
template_values['Invoices'][0]['InvoiceIssueData']['InvoicingPeriod'] = invoicing_period
return template_values, signature_values
@@ -0,0 +1 @@
from . import test_edi_xml
@@ -0,0 +1,231 @@
<fac:Facturae xmlns:fac="http://www.facturae.gob.es/formato/Versiones/Facturaev3_2_2.xml">
<FileHeader>
<SchemaVersion>3.2.2</SchemaVersion>
<Modality>I</Modality>
<InvoiceIssuerType>EM</InvoiceIssuerType>
<Batch>
<BatchIdentifier>INV/2023/00001</BatchIdentifier>
<InvoicesCount>1</InvoicesCount>
<TotalInvoicesAmount>
<TotalAmount>121.00</TotalAmount>
</TotalInvoicesAmount>
<TotalOutstandingAmount>
<TotalAmount>121.00</TotalAmount>
</TotalOutstandingAmount>
<TotalExecutableAmount>
<TotalAmount>121.00</TotalAmount>
</TotalExecutableAmount>
<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>
</Batch>
</FileHeader>
<Parties>
<SellerParty>
<TaxIdentification>
<PersonTypeCode>J</PersonTypeCode>
<ResidenceTypeCode>R</ResidenceTypeCode>
<TaxIdentificationNumber>ES59962470K</TaxIdentificationNumber>
</TaxIdentification>
<LegalEntity>
<CorporateName>company_1_data</CorporateName>
<TradeName>company_1_data</TradeName>
<AddressInSpain>
<Address>C. de Embajadores, 68-116</Address>
<PostCode>12345</PostCode>
<Town>Madrid</Town>
<Province>Madrid</Province>
<CountryCode>ESP</CountryCode>
</AddressInSpain>
</LegalEntity>
</SellerParty>
<BuyerParty>
<TaxIdentification>
<PersonTypeCode>F</PersonTypeCode>
<ResidenceTypeCode>U</ResidenceTypeCode>
<TaxIdentificationNumber>BE0477472701</TaxIdentificationNumber>
</TaxIdentification>
<Individual>
<Name>UNKNOWN</Name>
<FirstSurname>UNKNOWN</FirstSurname>
<OverseasAddress>
<Address>Rue de Bruxelles, 15000</Address>
<PostCodeAndTown>5000 Namur</PostCodeAndTown>
<Province>Belgium</Province>
<CountryCode>BEL</CountryCode>
</OverseasAddress>
</Individual>
</BuyerParty>
</Parties>
<Invoices>
<Invoice>
<InvoiceHeader>
<InvoiceNumber>INV/2023/00001</InvoiceNumber>
<InvoiceDocumentType>FC</InvoiceDocumentType>
<InvoiceClass>OO</InvoiceClass>
</InvoiceHeader>
<InvoiceIssueData>
<IssueDate>2023-01-01</IssueDate>
<InvoicingPeriod>
<StartDate>2023-01-01</StartDate>
<EndDate>2023-01-31</EndDate>
</InvoicingPeriod>
<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>
<TaxCurrencyCode>EUR</TaxCurrencyCode>
<LanguageName>en</LanguageName>
</InvoiceIssueData>
<TaxesOutputs>
<Tax>
<TaxTypeCode>01</TaxTypeCode>
<TaxRate>21.000</TaxRate>
<TaxableBase>
<TotalAmount>100.00</TotalAmount>
</TaxableBase>
<TaxAmount>
<TotalAmount>21.00</TotalAmount>
</TaxAmount>
</Tax>
</TaxesOutputs>
<InvoiceTotals>
<TotalGrossAmount>100.00</TotalGrossAmount>
<TotalGrossAmountBeforeTaxes>100.00</TotalGrossAmountBeforeTaxes>
<TotalTaxOutputs>21.00</TotalTaxOutputs>
<TotalTaxesWithheld>0.00</TotalTaxesWithheld>
<InvoiceTotal>121.00</InvoiceTotal>
<TotalOutstandingAmount>121.00</TotalOutstandingAmount>
<TotalExecutableAmount>121.00</TotalExecutableAmount>
</InvoiceTotals>
<Items>
<InvoiceLine>
<ItemDescription>product_a</ItemDescription>
<Quantity>1.0</Quantity>
<UnitOfMeasure>01</UnitOfMeasure>
<UnitPriceWithoutTax>100.00</UnitPriceWithoutTax>
<TotalCost>100.00</TotalCost>
<GrossAmount>100.00</GrossAmount>
<TaxesOutputs>
<Tax>
<TaxTypeCode>01</TaxTypeCode>
<TaxRate>21.000</TaxRate>
<TaxableBase>
<TotalAmount>100.00</TotalAmount>
</TaxableBase>
<TaxAmount>
<TotalAmount>21.00</TotalAmount>
</TaxAmount>
</Tax>
</TaxesOutputs>
</InvoiceLine>
</Items>
</Invoice>
</Invoices>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference Type="http://www.w3.org/2000/09/xmldsig#Object" URI="" Id="Reference-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>JAhNpeZX8by/1HgAFallJjZiJkBrvucV3HsBlYCWKPQ=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#SignatureProperties-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>e1hl1wSxZ4LGKE3NEGEplc9jRwRgQwDqyRoWo7Jx1+Q=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#KeyInfo-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>ey6Kj6XATgVzIh/1+h55n4LfhiBAA4FRGmcNwSs+j6A=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>jDUl6pOeuRuehXDleAz53WCGSoJhXdOHsPzOGDEYWWKI2d3Q4CW26A+4UE7vimrm5cAFt8h6vcks
/q2l/P3eXnn0iLO/SyHN33nUSv1T1UgZWW97BQBh7viol3qohnq97Qei1RgSnET13njdKh+EtQir
lQ/jwKLzggiKMWWj+XsW2LJgM/X+s6rBUQGLyBnIIpKIX9qQLPIJYE0IEuXZ+hGs7BzoGA90USno
UDjZoPwMMF0azY04WBhnSeelghVpjI1b9oVK4if9p0r49mNU9b0tIWT1W2EL0LX5jLJaEK1cOcy0
sMdXvyu5w7J3Q28eAf7c+X9Se+whbHTJCtq21Q==
</ds:SignatureValue>
<ds:KeyInfo Id="KeyInfo-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<ds:X509Data>
<ds:X509Certificate>MIID8jCCAtqgAwIBAgIUYBl+61DsTkNyyUFGveskbaGP/SkwDQYJKoZIhvcNAQELBQAwgYoxCzAJ
BgNVBAYTAkJFMRIwEAYDVQQIDAlXYWxsb25uaWExEjAQBgNVBAcMCVJhbWlsbGllczENMAsGA1UE
CgwET2RvbzEMMAoGA1UECwwDUiZEMRgwFgYDVQQDDA9ydW5ib3Qub2Rvby5jb20xHDAaBgkqhkiG
9w0BCQEWDWluZm9Ab2Rvby5jb20wHhcNMjIwNDI2MDczMTUwWhcNMjMwNDI2MDczMTUwWjCBlTEL
MAkGA1UEBhMCQkUxEjAQBgNVBAgMCVdhbGxvbm5pYTESMBAGA1UEBwwJUmFtaWxsaWVzMRIwEAYD
VQQKDAlPZG9vIFMuQS4xGTAXBgNVBAsMEFImRCAtIEFjY291bnRpbmcxETAPBgNVBAMMCG9kb28u
Y29tMRwwGgYJKoZIhvcNAQkBFg1pbmZvQG9kb28uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAtGUbyNJrA3yyOC01gIMR1A1rWIHCHD+afLCLCddBDZwC4Q034yFBuMqQFNWaxxLc
9s+wFbNZqu5D7rynN3qXvWJj40VZxygoV/09y71IhaspuAZ0rdzYsqjDmTJiPSrEl6iydF2eq6sJ
4J0ItCUFc2e88B25wz7esslAN249C20oQj5ZiGifR4P0CRQSmDy0SPYZGxTurVwtq6IsYbOqEw8/
Wqx6ApOltperFX88DZCdbY59ZedqQrGQh2Z5Au7h/8nhmdbpz7Ixw2zocxVigR0ClNDpKKxvolX1
virQpICkfWcAaWAYAMCL4KhvISclysD+5juDLpGCLHPtKxBXTQIDAQABo0MwQTAfBgNVHSMEGDAW
gBTmxEG4Ub7b5wRXqWea94Vs1hB13zAJBgNVHRMEAjAAMBMGA1UdEQQMMAqCCG9kb28uY29tMA0G
CSqGSIb3DQEBCwUAA4IBAQAFLvTlSELTVWRfIlGthoFOmkv8MrwJuo8y7qTmvsFXeA2hZtsPdNxx
iwAGPobiUO0GCEPUFKZ7NksQa7DAKGXfb5RSwfujDfEMAhgi00+wF1VIKeKqnGt4idzCr+2NtiQY
e9oK+Ee7o82llnNFwbWvRKx55lhHW3bwN6Tl31qUYbxacJyA9z5sQpe2zImWMVsm4g7OAjzg3Cn2
0TFu+0XekB892n7DYh4gHiMWaMOVYmi/aEWLSqxMlbiHQr75FmPftozFvTxW26jU3ALhq+yXPVa4
lg4r/h6HH5TbtSjYzTSJ4MvMyrECgIQYf0zsS4D6K/GvCZbu7LKHRwuC0fis
</ds:X509Certificate>
</ds:X509Data>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>tGUbyNJrA3yyOC01gIMR1A1rWIHCHD+afLCLCddBDZwC4Q034yFBuMqQFNWaxxLc9s+wFbNZqu5D
7rynN3qXvWJj40VZxygoV/09y71IhaspuAZ0rdzYsqjDmTJiPSrEl6iydF2eq6sJ4J0ItCUFc2e8
8B25wz7esslAN249C20oQj5ZiGifR4P0CRQSmDy0SPYZGxTurVwtq6IsYbOqEw8/Wqx6ApOltper
FX88DZCdbY59ZedqQrGQh2Z5Au7h/8nhmdbpz7Ixw2zocxVigR0ClNDpKKxvolX1virQpICkfWcA
aWAYAMCL4KhvISclysD+5juDLpGCLHPtKxBXTQ==
</ds:Modulus>
<ds:Exponent>AQAB
</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
<ds:Object>
<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#Signature-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<xades:SignedProperties Id="SignatureProperties-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<xades:SignedSignatureProperties>
<xades:SigningTime>2023-01-01T00:00:00</xades:SigningTime>
<xades:SigningCertificate>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>FHf2lN+5FALNa7JXV2+pByL92/dr8LeCVhpItYic5oA=</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>C=BE, CN=runbot.odoo.com, L=Ramillies, O=Odoo, OU=R&amp;D, ST=Wallonnia</ds:X509IssuerName>
<ds:X509SerialNumber>548631688851000697209704649636588277530075594025</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
</xades:SigningCertificate>
<xades:SignaturePolicyIdentifier>
<xades:SignaturePolicyId>
<xades:SigPolicyId>
<xades:Identifier>http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdf</xades:Identifier>
<xades:Description>Pol&#237;tica de firma electr&#243;nica para facturaci&#243;n electr&#243;nica con formato Facturae</xades:Description>
</xades:SigPolicyId>
<xades:SigPolicyHash>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>a/vDoueJq9zxWGCFwdsXdlXtkFSEek4XVtmlQCEDaE8=</ds:DigestValue>
</xades:SigPolicyHash>
<xades:SigPolicyQualifiers>
<xades:SigPolicyQualifier>
<xades:SPURI>http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdf</xades:SPURI>
</xades:SigPolicyQualifier>
</xades:SigPolicyQualifiers>
</xades:SignaturePolicyId>
</xades:SignaturePolicyIdentifier>
</xades:SignedSignatureProperties>
<xades:SignedDataObjectProperties>
<xades:DataObjectFormat ObjectReference="#Reference-Document-cad8cfdfae8f532990689077a3f35e417231f58f">
<xades:Description/>
<xades:ObjectIdentifier>
<xades:Identifier Qualifier="OIDAsURN">urn:oid:1.2.840.10003.5.109.10</xades:Identifier>
<xades:Description/>
</xades:ObjectIdentifier>
<xades:MimeType>text/xml</xades:MimeType>
<xades:Encoding/>
</xades:DataObjectFormat>
</xades:SignedDataObjectProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
</ds:Signature>
</fac:Facturae>
@@ -0,0 +1,29 @@
import lxml
from freezegun.api import freeze_time
from odoo.tests import tagged
from odoo.tools import file_open
from odoo.addons.l10n_es_edi_facturae.tests.test_edi_xml import TestEdiFacturaeXmls
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestEdiFacturaeInvoicePeriodXmls(TestEdiFacturaeXmls):
@freeze_time('2023-01-01')
def test_generate_with_invoice_period(self):
invoice = self.create_invoice(
partner_id=self.partner_a.id,
move_type='out_invoice',
invoice_line_ids=[{'price_unit': 100.0, 'tax_ids': [self.tax.id]}],
l10n_es_invoicing_period_start_date='2023-01-01',
l10n_es_invoicing_period_end_date='2023-01-31',
)
invoice.action_post()
generated_file, errors = invoice._l10n_es_edi_facturae_render_facturae()
self.assertFalse(errors)
self.assertTrue(generated_file)
with file_open('l10n_es_edi_facturae_invoice_period/tests/data/expected_invoice_period_document.xml', 'rt') as f:
expected_xml = lxml.etree.fromstring(f.read().encode())
self.assertXmlTreeEqual(lxml.etree.fromstring(generated_file), expected_xml)
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_move_form" model="ir.ui.view">
<field name="name">account.move.form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='other_info']" position="inside">
<group string="Factura-e"
name="l10n_es_facturae_invoicing_period">
<field name="l10n_es_invoicing_period_start_date"/>
<field name="l10n_es_invoicing_period_end_date"/>
</group>
</xpath>
</field>
</record>
</data>
</odoo>