From 6e0405740199b643e3ff0657a8e0b0e19908b855 Mon Sep 17 00:00:00 2001 From: "Benjamin Frantzen (bfr)" Date: Tue, 13 Jul 2021 14:21:37 +0000 Subject: [PATCH] [IMP] l10n_it_edi_sdicoop: normalize codice fiscale. Codice Fiscale can be 16 length (letters + digits) for physical people. Codice Fiscale can be 11 digits prefixed or not with 'IT' for companies. An error is raised if the codice fiscale is not saved in the correct format. When registering to l10n_it_edi_proxy, we try to normalize the Codice Fiscale if possible. Also, when entering the vat in the partner, the Codice Fiscale is automatically set normalized. closes odoo/odoo#73774 X-original-commit: 3741e141e5a468b8ce0413f4f7d7fc05751b0c1b Signed-off-by: Josse Colpaert Signed-off-by: bfr-o --- .../l10n_it_edi/models/account_edi_format.py | 16 +++++++++--- addons/l10n_it_edi/models/res_partner.py | 25 +++++++++++++++++-- .../l10n_it_edi/tests/test_ir_mail_server.py | 2 +- .../models/account_edi_format.py | 2 +- addons/l10n_it_stock_ddt/tests/test_ddt.py | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/addons/l10n_it_edi/models/account_edi_format.py b/addons/l10n_it_edi/models/account_edi_format.py index 9492c9defc6..27722283319 100644 --- a/addons/l10n_it_edi/models/account_edi_format.py +++ b/addons/l10n_it_edi/models/account_edi_format.py @@ -4,14 +4,13 @@ from odoo import api, models, fields, _ from odoo.tests.common import Form from odoo.exceptions import UserError -from odoo.tools import float_repr from odoo.addons.l10n_it_edi.tools.remove_signature import remove_signature +from odoo.osv.expression import OR, AND from lxml import etree -from datetime import date, datetime +from datetime import datetime import re import logging -import base64 _logger = logging.getLogger(__name__) @@ -289,7 +288,15 @@ class AccountEdiFormat(models.Model): partner = elements and self.env['res.partner'].search(['&', ('vat', 'ilike', elements[0].text), '|', ('company_id', '=', company.id), ('company_id', '=', False)], limit=1) if not partner: elements = tree.xpath('//CedentePrestatore//CodiceFiscale') - partner = elements and self.env['res.partner'].search(['&', ('l10n_it_codice_fiscale', '=', elements[0].text), '|', ('company_id', '=', company.id), ('company_id', '=', False)], limit=1) + if elements: + codice = elements[0].text + domains = [[('l10n_it_codice_fiscale', '=', codice)]] + if re.match(r'^[0-9]{11}$', codice): + domains.append([('l10n_it_codice_fiscale', '=', 'IT' + codice)]) + elif re.match(r'^IT[0-9]{11}$', codice): + domains.append([('l10n_it_codice_fiscale', '=', self.env['res.partner']._l10n_it_normalize_codice_fiscale(codice))]) + partner = elements and self.env['res.partner'].search( + AND([OR(domains), OR([[('company_id', '=', company.id)], [('company_id', '=', False)]])]), limit=1) if not partner: elements = tree.xpath('//DatiTrasmissione//Email') partner = elements and self.env['res.partner'].search(['&', '|', ('email', '=', elements[0].text), ('l10n_it_pec_email', '=', elements[0].text), '|', ('company_id', '=', company.id), ('company_id', '=', False)], limit=1) @@ -595,4 +602,5 @@ class AccountEdiFormat(models.Model): new_invoice.message_post(body=message) invoices += new_invoice + return invoices diff --git a/addons/l10n_it_edi/models/res_partner.py b/addons/l10n_it_edi/models/res_partner.py index e0a78f24d58..da7d1dd4c13 100644 --- a/addons/l10n_it_edi/models/res_partner.py +++ b/addons/l10n_it_edi/models/res_partner.py @@ -1,8 +1,11 @@ # -*- coding:utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import api, fields, models -from odoo.exceptions import ValidationError +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +import re + class ResPartner(models.Model): _name = 'res.partner' @@ -26,3 +29,21 @@ class ResPartner(models.Model): "CHECK(l10n_it_pa_index IS NULL OR LENGTH(l10n_it_pa_index) >= 6)", "PA index must have between 6 and 7 characters."), ] + + @api.model + def _l10n_it_normalize_codice_fiscale(self, codice): + if re.match(r'^IT[0-9]{11}$', codice): + return codice[2:13] + return codice + + @api.onchange('vat') + def _l10n_it_onchange_vat(self): + if not self.l10n_it_codice_fiscale: + self.l10n_it_codice_fiscale = self._l10n_it_normalize_codice_fiscale(self.vat) + + @api.constrains('l10n_it_codice_fiscale') + def validate_codice_fiscale(self): + p = re.compile(r'^([A-Za-z]{6}[0-9]{2}[A-Za-z]{1}[0-9]{2}[A-Za-z]{1}[0-9]{3}[A-Za-z]{1}$)|([0-9]{11})|(IT[0-9]{11})$') + for record in self: + if record.l10n_it_codice_fiscale and not p.match(record.l10n_it_codice_fiscale): + raise UserError(_("Invalid Codice Fiscale '%s': should be like 'MRTMTT91D08F205J' for physical person and '12345678901' or 'IT12345678901' for businesses.", record.l10n_it_codice_fiscale)) diff --git a/addons/l10n_it_edi/tests/test_ir_mail_server.py b/addons/l10n_it_edi/tests/test_ir_mail_server.py index 199a63f9a56..734c7246f3b 100644 --- a/addons/l10n_it_edi/tests/test_ir_mail_server.py +++ b/addons/l10n_it_edi/tests/test_ir_mail_server.py @@ -113,7 +113,7 @@ class PecMailServerTests(AccountEdiTestCommon): invoices = self._create_invoice(self.signed_invoice_content, self.signed_invoice_filename) self.assertRecordValues(invoices, [{ 'company_id': self.company.id, - 'name': 'BILL/2020/04/0001', + 'name': 'BILL/2014/12/0001', 'invoice_date': datetime.date(2014, 12, 18), 'ref': '01234567890', }]) diff --git a/addons/l10n_it_edi_sdicoop/models/account_edi_format.py b/addons/l10n_it_edi_sdicoop/models/account_edi_format.py index 5b78e3ff4c2..95db0adaa29 100644 --- a/addons/l10n_it_edi_sdicoop/models/account_edi_format.py +++ b/addons/l10n_it_edi_sdicoop/models/account_edi_format.py @@ -253,7 +253,7 @@ class AccountEdiFormat(models.Model): if not company.l10n_it_codice_fiscale: raise UserError(_('Please fill your codice fiscale to be able to receive invoices from FatturaPA')) - return company.l10n_it_codice_fiscale + return self.env['res.partner']._l10n_it_normalize_codice_fiscale(company.l10n_it_codice_fiscale) def _l10n_it_edi_upload(self, files, proxy_user): '''Upload files to fatturapa. diff --git a/addons/l10n_it_stock_ddt/tests/test_ddt.py b/addons/l10n_it_stock_ddt/tests/test_ddt.py index 94ba8205394..d9125888d51 100644 --- a/addons/l10n_it_stock_ddt/tests/test_ddt.py +++ b/addons/l10n_it_stock_ddt/tests/test_ddt.py @@ -13,7 +13,7 @@ class TestDDT(TestSaleCommon): cls.company_data['company'].write({ 'vat':"IT12345670017", 'country_id': cls.env.ref('base.it'), - 'l10n_it_codice_fiscale': '0123456789987654', + 'l10n_it_codice_fiscale': '01234560157', 'l10n_it_tax_system': 'RF01', 'street': 'Via Giovanni Maria Platina 66', 'zip': '26100',