[FIX] l10n_it_edi: fiscal code format
According to www.agenziaentrate.gov.it/portale/web/guest/schede/istanze/richiesta-ts_cf/informazioni-codificazione-pf The tax identification number of natural persons consists of an alphanumeric expression of sixteen characters. The first fifteen characters are indicative of the master data of each individual in the following order: - 3 alphabetic characters for the surname; - 3 alphabetic characters for the first name; - 2 numeric characters for the year of birth; - 1 alphabetic character for the month of birth; - 2 numeric characters for the day of birth and sex; - 4 characters, 1 alphabetic and 3 numeric for the Italian municipality or foreign state of birth. The sixteenth character, alphabetic, serves as a control. The main fix is about this part: When two or more individuals have master data generating the same tax code (homocodes), the tax code is differentiated for each of them. For this purpose, systematic substitutions of one or more digits starting from the right one are made within the seven numeric characters contained in the code with corresponding alphabetic characters according to the following table: 0 = L 4 = Q 8 = U 1 = M 5 = R 9 = V 2 = N 6 = S 3 = P 7 = T Also the check for iva number format was incomplete. Indeed, The three penultimate digits correspond to the region of the VAT office and must be between 001 and 100 inclusive, or equal to 120, 121, 888 or 999. We use the stdnum library's methods for the validation of fiscal code and iva number format. opw-2797408 closes odoo/odoo#97633 X-original-commit: 262eb7bd021d177d9a05397f9cda3fc76a21d4cb Signed-off-by: Josse Colpaert <jco@odoo.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from stdnum.it import codicefiscale, iva
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
@@ -45,7 +46,6 @@ class ResPartner(models.Model):
|
||||
|
||||
@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))
|
||||
if record.l10n_it_codice_fiscale and (not codicefiscale.is_valid(record.l10n_it_codice_fiscale) and not iva.is_valid(record.l10n_it_codice_fiscale)):
|
||||
raise UserError(_("Invalid Codice Fiscale '%s': should be like 'MRTMTT91D08F205J' for physical person and '12345670546' or 'IT12345670546' for businesses.", record.l10n_it_codice_fiscale))
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_ir_mail_server
|
||||
from . import test_res_partner
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestResPartner(TransactionCase):
|
||||
|
||||
def test_validate_fiscal_code(self):
|
||||
valid_codes = [
|
||||
"AORTHV05P30V295L",
|
||||
"SPDTHB43S93F42VH",
|
||||
"MDRTUV99H14X2MNU",
|
||||
"XPTDRX73R64YPLUD",
|
||||
"LOLXDR40T3MZRTSV",
|
||||
"GJTIUG55DLQZRTSS",
|
||||
"CDEOTG5PBLQZRTSE",
|
||||
"PERTLELPALQZRTSN",
|
||||
"IT12345678887",
|
||||
"IT12345670546",
|
||||
"IT95286931217",
|
||||
"IT95867361206",
|
||||
"IT94567689990",
|
||||
"12345670546",
|
||||
"95286931217",
|
||||
"95867361206",
|
||||
"94567689990",
|
||||
]
|
||||
|
||||
invalid_codes = [
|
||||
"AORTHV05P34V295U",
|
||||
"SPDTHB43O93F42VH",
|
||||
"MDRTUVV9H14X2MNU",
|
||||
"XPTDRX73RS4YPLUD",
|
||||
"LOLXDRQ0T3QZRTSJ",
|
||||
"GJTIUGR5DLQZRTSS",
|
||||
"CDEOTG5PBLQZRTSS",
|
||||
"PERTLEZPALQZRTSN",
|
||||
"IT12345678901",
|
||||
"IT12345678885",
|
||||
"IT45689349992",
|
||||
"IT78239131204",
|
||||
"IT45692151219",
|
||||
"12345678901",
|
||||
"12345678885",
|
||||
"45689349992",
|
||||
"78239131204",
|
||||
"45692151219",
|
||||
]
|
||||
|
||||
partners = self.env['res.partner']
|
||||
|
||||
for i, code in enumerate(invalid_codes):
|
||||
with self.assertRaises(UserError):
|
||||
partners += self.env['res.partner'].create({'name': f'partner_{i}', 'l10n_it_codice_fiscale': code})
|
||||
|
||||
for i, code in enumerate(valid_codes):
|
||||
partners += self.env['res.partner'].create({'name': f'partner_{i}', 'l10n_it_codice_fiscale': code})
|
||||
|
||||
self.assertEqual(len(partners), len(valid_codes))
|
||||
Reference in New Issue
Block a user