210 lines
10 KiB
Python
210 lines
10 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
import re
|
||
|
from stdnum.fr import siret
|
||
|
|
||
|
from odoo import models, fields, api, _
|
||
|
from odoo.exceptions import ValidationError
|
||
|
from odoo.addons.account_edi_ubl_cii.models.account_edi_common import EAS_MAPPING
|
||
|
|
||
|
|
||
|
class ResPartner(models.Model):
|
||
|
_inherit = 'res.partner'
|
||
|
|
||
|
ubl_cii_format = fields.Selection(
|
||
|
string="Format",
|
||
|
selection=[
|
||
|
('facturx', "Factur-X (CII)"),
|
||
|
('ubl_bis3', "BIS Billing 3.0"),
|
||
|
('xrechnung', "XRechnung CIUS"),
|
||
|
('nlcius', "NLCIUS"),
|
||
|
('ubl_a_nz', "BIS Billing 3.0 A-NZ"),
|
||
|
('ubl_sg', "BIS Billing 3.0 SG"),
|
||
|
],
|
||
|
compute='_compute_ubl_cii_format',
|
||
|
store=True,
|
||
|
readonly=False,
|
||
|
)
|
||
|
peppol_endpoint = fields.Char(
|
||
|
string="Peppol Endpoint",
|
||
|
help="Unique identifier used by the BIS Billing 3.0 and its derivatives, also known as 'Endpoint ID'.",
|
||
|
compute="_compute_peppol_endpoint",
|
||
|
store=True,
|
||
|
readonly=False,
|
||
|
tracking=True,
|
||
|
)
|
||
|
peppol_eas = fields.Selection(
|
||
|
string="Peppol e-address (EAS)",
|
||
|
help="""Code used to identify the Endpoint for BIS Billing 3.0 and its derivatives.
|
||
|
List available at https://docs.peppol.eu/poacc/billing/3.0/codelist/eas/""",
|
||
|
compute="_compute_peppol_eas",
|
||
|
store=True,
|
||
|
readonly=False,
|
||
|
tracking=True,
|
||
|
selection=[
|
||
|
('0002', "0002 - System Information et Repertoire des Entreprise et des Etablissements: SIRENE"),
|
||
|
('0007', "0007 - Organisationsnummer (Swedish legal entities)"),
|
||
|
('0009', "0009 - SIRET-CODE"),
|
||
|
('0037', "0037 - LY-tunnus"),
|
||
|
('0060', "0060 - Data Universal Numbering System (D-U-N-S Number)"),
|
||
|
('0088', "0088 - EAN Location Code"),
|
||
|
('0096', "0096 - DANISH CHAMBER OF COMMERCE Scheme (EDIRA compliant)"),
|
||
|
('0097', "0097 - FTI - Ediforum Italia, (EDIRA compliant)"),
|
||
|
('0106', "0106 - Association of Chambers of Commerce and Industry in the Netherlands, (EDIRA compliant)"),
|
||
|
('0130', "0130 - Directorates of the European Commission"),
|
||
|
('0135', "0135 - SIA Object Identifiers"),
|
||
|
('0142', "0142 - SECETI Object Identifiers"),
|
||
|
('0151', "0151 - Australian Business Number (ABN) Scheme"),
|
||
|
('0183', "0183 - Swiss Unique Business Identification Number (UIDB)"),
|
||
|
('0184', "0184 - DIGSTORG"),
|
||
|
('0188', "0188 - Corporate Number of The Social Security and Tax Number System"),
|
||
|
('0190', "0190 - Dutch Originator's Identification Number"),
|
||
|
('0191', "0191 - Centre of Registers and Information Systems of the Ministry of Justice"),
|
||
|
('0192', "0192 - Enhetsregisteret ved Bronnoysundregisterne"),
|
||
|
('0193', "0193 - UBL.BE party identifier"),
|
||
|
('0195', "0195 - Singapore UEN identifier"),
|
||
|
('0196', "0196 - Kennitala - Iceland legal id for individuals and legal entities"),
|
||
|
('0198', "0198 - ERSTORG"),
|
||
|
('0199', "0199 - Legal Entity Identifier (LEI)"),
|
||
|
('0200', "0200 - Legal entity code (Lithuania)"),
|
||
|
('0201', "0201 - Codice Univoco Unità Organizzativa iPA"),
|
||
|
('0202', "0202 - Indirizzo di Posta Elettronica Certificata"),
|
||
|
('0204', "0204 - Leitweg-ID"),
|
||
|
('0208', "0208 - Numero d'entreprise / ondernemingsnummer / Unternehmensnummer"),
|
||
|
('0209', "0209 - GS1 identification keys"),
|
||
|
('0210', "0210 - CODICE FISCALE"),
|
||
|
('0211', "0211 - PARTITA IVA"),
|
||
|
('0212', "0212 - Finnish Organization Identifier"),
|
||
|
('0213', "0213 - Finnish Organization Value Add Tax Identifier"),
|
||
|
('0215', "0215 - Net service ID"),
|
||
|
('0216', "0216 - OVTcode"),
|
||
|
('0221', "0221 - The registered number of the qualified invoice issuer (Japan)"),
|
||
|
('0230', "0230 - National e-Invoicing Framework (Malaysia)"),
|
||
|
('9901', "9901 - Danish Ministry of the Interior and Health"),
|
||
|
('9910', "9910 - Hungary VAT number"),
|
||
|
('9913', "9913 - Business Registers Network"),
|
||
|
('9914', "9914 - Österreichische Umsatzsteuer-Identifikationsnummer"),
|
||
|
('9915', "9915 - Österreichisches Verwaltungs bzw. Organisationskennzeichen"),
|
||
|
('9918', "9918 - SOCIETY FOR WORLDWIDE INTERBANK FINANCIAL, TELECOMMUNICATION S.W.I.F.T"),
|
||
|
('9919', "9919 - Kennziffer des Unternehmensregisters"),
|
||
|
('9920', "9920 - Agencia Española de Administración Tributaria"),
|
||
|
('9922', "9922 - Andorra VAT number"),
|
||
|
('9923', "9923 - Albania VAT number"),
|
||
|
('9924', "9924 - Bosnia and Herzegovina VAT number"),
|
||
|
('9925', "9925 - Belgium VAT number"),
|
||
|
('9926', "9926 - Bulgaria VAT number"),
|
||
|
('9927', "9927 - Switzerland VAT number"),
|
||
|
('9928', "9928 - Cyprus VAT number"),
|
||
|
('9929', "9929 - Czech Republic VAT number"),
|
||
|
('9930', "9930 - Germany VAT number"),
|
||
|
('9931', "9931 - Estonia VAT number"),
|
||
|
('9932', "9932 - United Kingdom VAT number"),
|
||
|
('9933', "9933 - Greece VAT number"),
|
||
|
('9934', "9934 - Croatia VAT number"),
|
||
|
('9935', "9935 - Ireland VAT number"),
|
||
|
('9936', "9936 - Liechtenstein VAT number"),
|
||
|
('9937', "9937 - Lithuania VAT number"),
|
||
|
('9938', "9938 - Luxemburg VAT number"),
|
||
|
('9939', "9939 - Latvia VAT number"),
|
||
|
('9940', "9940 - Monaco VAT number"),
|
||
|
('9941', "9941 - Montenegro VAT number"),
|
||
|
('9942', "9942 - Macedonia, the former Yugoslav Republic of VAT number"),
|
||
|
('9943', "9943 - Malta VAT number"),
|
||
|
('9944', "9944 - Netherlands VAT number"),
|
||
|
('9945', "9945 - Poland VAT number"),
|
||
|
('9946', "9946 - Portugal VAT number"),
|
||
|
('9947', "9947 - Romania VAT number"),
|
||
|
('9948', "9948 - Serbia VAT number"),
|
||
|
('9949', "9949 - Slovenia VAT number"),
|
||
|
('9950', "9950 - Slovakia VAT number"),
|
||
|
('9951', "9951 - San Marino VAT number"),
|
||
|
('9952', "9952 - Turkey VAT number"),
|
||
|
('9953', "9953 - Holy See (Vatican City State) VAT number"),
|
||
|
('9955', "9955 - Swedish VAT number"),
|
||
|
('9957', "9957 - French VAT number"),
|
||
|
('9959', "9959 - Employer Identification Number (EIN, USA)"),
|
||
|
]
|
||
|
)
|
||
|
|
||
|
@api.constrains('peppol_endpoint')
|
||
|
def _check_peppol_fields(self):
|
||
|
for partner in self:
|
||
|
if partner.peppol_endpoint and partner.peppol_eas:
|
||
|
error = self._build_error_peppol_endpoint(partner.peppol_eas, partner.peppol_endpoint)
|
||
|
if error:
|
||
|
raise ValidationError(error)
|
||
|
|
||
|
@api.depends('country_code')
|
||
|
def _compute_ubl_cii_format(self):
|
||
|
for partner in self:
|
||
|
if partner.country_code == 'DE':
|
||
|
partner.ubl_cii_format = 'xrechnung'
|
||
|
elif partner.country_code in ('AU', 'NZ'):
|
||
|
partner.ubl_cii_format = 'ubl_a_nz'
|
||
|
elif partner.country_code == 'NL':
|
||
|
partner.ubl_cii_format = 'nlcius'
|
||
|
elif partner.country_code == 'FR':
|
||
|
partner.ubl_cii_format = 'facturx'
|
||
|
elif partner.country_code == 'SG':
|
||
|
partner.ubl_cii_format = 'ubl_sg'
|
||
|
elif partner.country_code in EAS_MAPPING:
|
||
|
partner.ubl_cii_format = 'ubl_bis3'
|
||
|
else:
|
||
|
partner.ubl_cii_format = partner.ubl_cii_format
|
||
|
|
||
|
@api.depends('peppol_eas')
|
||
|
def _compute_peppol_endpoint(self):
|
||
|
""" If the EAS changes and a valid endpoint is available, set it. Otherwise, keep the existing value."""
|
||
|
for partner in self:
|
||
|
partner.peppol_endpoint = partner.peppol_endpoint
|
||
|
if partner.country_code in EAS_MAPPING:
|
||
|
field = EAS_MAPPING[partner.country_code].get(partner.peppol_eas)
|
||
|
if field \
|
||
|
and field in partner._fields \
|
||
|
and partner[field] \
|
||
|
and not partner._build_error_peppol_endpoint(partner.peppol_eas, partner[field]):
|
||
|
partner.peppol_endpoint = partner[field]
|
||
|
|
||
|
@api.depends('country_code')
|
||
|
def _compute_peppol_eas(self):
|
||
|
"""
|
||
|
If the country_code changes, recompute the EAS only if there is a country_code, it exists in the
|
||
|
EAS_MAPPING, and the current EAS is not consistent with the new country_code.
|
||
|
"""
|
||
|
for partner in self:
|
||
|
partner.peppol_eas = partner.peppol_eas
|
||
|
if partner.country_code and partner.country_code in EAS_MAPPING:
|
||
|
eas_to_field = EAS_MAPPING[partner.country_code]
|
||
|
if partner.peppol_eas not in eas_to_field.keys():
|
||
|
new_eas = list(EAS_MAPPING[partner.country_code].keys())[0]
|
||
|
# Iterate on the possible EAS until a valid one is found
|
||
|
for eas, field in eas_to_field.items():
|
||
|
if field and field in partner._fields and partner[field]:
|
||
|
if not partner._build_error_peppol_endpoint(eas, partner[field]):
|
||
|
new_eas = eas
|
||
|
break
|
||
|
partner.peppol_eas = new_eas
|
||
|
|
||
|
def _build_error_peppol_endpoint(self, eas, endpoint):
|
||
|
""" This function contains all the rules regarding the peppol_endpoint."""
|
||
|
if eas == '0208' and not re.match(r"^\d{10}$", endpoint):
|
||
|
return _("The Peppol endpoint is not valid. The expected format is: 0239843188")
|
||
|
if eas == '0009' and not siret.is_valid(endpoint):
|
||
|
return _("The Peppol endpoint is not valid. The expected format is: 73282932000074")
|
||
|
|
||
|
def _get_edi_builder(self):
|
||
|
self.ensure_one()
|
||
|
if self.ubl_cii_format == 'xrechnung':
|
||
|
return self.env['account.edi.xml.ubl_de']
|
||
|
if self.ubl_cii_format == 'facturx':
|
||
|
return self.env['account.edi.xml.cii']
|
||
|
if self.ubl_cii_format == 'ubl_a_nz':
|
||
|
return self.env['account.edi.xml.ubl_a_nz']
|
||
|
if self.ubl_cii_format == 'nlcius':
|
||
|
return self.env['account.edi.xml.ubl_nl']
|
||
|
if self.ubl_cii_format == 'ubl_bis3':
|
||
|
return self.env['account.edi.xml.ubl_bis3']
|
||
|
if self.ubl_cii_format == 'ubl_sg':
|
||
|
return self.env['account.edi.xml.ubl_sg']
|