[IMP] base_vat,l10n_br: depend on l10n_latam_base to categorize id types

This adds the two main identification types we use in Brazil. CNPJ is
used the standard VAT type. The custom check_vat logic was removed
because stdnum supports this out of the box.

Another non-VAT CPF type was added that is checked for validity using
stdnum as well.

task-3475609

closes odoo/odoo#132773

Related: odoo/enterprise#46127
Related: odoo/upgrade#5062
Signed-off-by: Josse Colpaert <jco@odoo.com>
This commit is contained in:
Joren Van Onder
2023-09-05 19:58:04 +00:00
parent aa8b60a0c8
commit d4e8c88da6
7 changed files with 15 additions and 49 deletions
+1
View File
@@ -32,6 +32,7 @@ _ref_vat = {
'au': '83 914 571 673',
'be': 'BE0477472701',
'bg': 'BG1234567892',
'br': '48.906.308/0001-27',
'ch': 'CHE-123.456.788 TVA or CHE-123.456.788 MWST or CHE-123.456.788 IVA', # Swiss by Yannick Vaucher @ Camptocamp
'cl': 'CL76086428-5',
'co': 'CO213123432-1 or CO213.123.432-1',
+2
View File
@@ -46,9 +46,11 @@ come with any additional paid permission for online use of 'private modules'.
'depends': [
'account',
'base_vat',
'l10n_latam_base',
],
'data': [
'data/account_tax_report_data.xml',
'data/l10n_latam.identification.type.csv',
'views/account_view.xml',
'views/account_fiscal_position_views.xml',
'views/res_company_views.xml',
@@ -0,0 +1,3 @@
id,name,country_id:id,is_vat
cnpj,CNPJ,base.br,True
cpf,CPF,base.br,False
1 id name country_id:id is_vat
2 cnpj CNPJ base.br True
3 cpf CPF base.br False
+1 -8
View File
@@ -243,14 +243,7 @@ msgstr ""
#. odoo-python
#: code:addons/l10n_br/models/res_partner.py:0
#, python-format
msgid "Invalid CNPJ. Make sure that all the typs are entered correctly."
msgstr ""
#. module: l10n_br
#. odoo-python
#: code:addons/l10n_br/models/res_partner.py:0
#, python-format
msgid "Invalid CNPJ. Make sure that the CNPJ is a 14 digits number."
msgid "CPF number %s for %s is not valid."
msgstr ""
#. module: l10n_br
+2 -9
View File
@@ -230,15 +230,8 @@ msgstr "Interstate Fiscal Position Type"
#. odoo-python
#: code:addons/l10n_br/models/res_partner.py:0
#, python-format
msgid "Invalid CNPJ. Make sure that all the typs are entered correctly."
msgstr "Invalid CNPJ. Make sure that all the digits are entered correctly."
#. module: l10n_br
#. odoo-python
#: code:addons/l10n_br/models/res_partner.py:0
#, python-format
msgid "Invalid CNPJ. Make sure that the CNPJ is a 14 digits number."
msgstr "Invalid CNPJ. Make sure that the CNPJ is a 14 digits number."
msgid "CPF number %s for %s is not valid."
msgstr "O número de CPF %s para %s não é válido."
#. module: l10n_br
#: model:ir.model.fields,field_description:l10n_br.field_account_tax__amount_mva
+6 -31
View File
@@ -1,45 +1,20 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import stdnum.br.cpf
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
import re
class ResPartner(models.Model):
_inherit = 'res.partner'
l10n_br_cpf_code = fields.Char(string="CPF", help="Natural Persons Register.")
l10n_br_ie_code = fields.Char(string="IE", help="State Tax Identification Number. Should contain 9-14 digits.")
l10n_br_im_code = fields.Char(string="IM", help="Municipal Tax Identification Number")
l10n_br_isuf_code = fields.Char(string="SUFRAMA code", help="SUFRAMA registration number.")
@api.constrains("vat")
def check_vat(self):
'''
Example of a Brazilian CNPJ number: 76.634.583/0001-74.
The 13th digit is the check digit of the previous 12 digits.
The check digit is calculated by multiplying the first 12 digits by weights and calculate modulo 11 of the result.
The 14th digit is the check digit of the previous 13 digits. Calculated the same way.
Both remainders are appended to the first 12 digits.
'''
def _l10n_br_calculate_mod_11(check, weights):
result = (sum([i*j for (i, j) in zip(check, weights)])) % 11
if result <= 1:
return 0
return 11 - result
for partner in self:
if not partner.vat:
return
if not partner.country_code == 'BR':
return super().check_vat()
weights = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
vat_clean = list(map(int, re.sub("[^0-9]", "", partner.vat)))
if len(vat_clean) != 14:
raise ValidationError(_("Invalid CNPJ. Make sure that the CNPJ is a 14 digits number."))
vat_check = vat_clean[:12]
vat_check.append(_l10n_br_calculate_mod_11(vat_check, weights[1:]))
vat_check.append(_l10n_br_calculate_mod_11(vat_check, weights))
if vat_check != vat_clean:
raise ValidationError(_("Invalid CNPJ. Make sure that all the digits are entered correctly."))
@api.constrains('vat', 'l10n_latam_identification_type_id')
def check_cpf(self):
for partner in self.filtered(lambda partner: partner.l10n_latam_identification_type_id == self.env.ref('l10n_br.cpf')):
if partner.vat and not stdnum.br.cpf.is_valid(partner.vat):
raise ValidationError(_('CPF number %s for %s is not valid.') % (partner.vat, partner.display_name))
@@ -7,7 +7,6 @@
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='vat']" position="after">
<field name="l10n_br_cpf_code" invisible="'BR'.lower() not in (fiscal_country_codes or '').lower()"/>
<field name="l10n_br_ie_code" invisible="'BR'.lower() not in (fiscal_country_codes or '').lower()"/>
<field name="l10n_br_im_code" invisible="'BR'.lower() not in (fiscal_country_codes or '').lower()"/>
<field name="l10n_br_isuf_code" invisible="'BR'.lower() not in (fiscal_country_codes or '').lower()"/>