Skip to content

Commit

Permalink
[REF] l10n_br_base: use vat field for CNPJ
Browse files Browse the repository at this point in the history
  • Loading branch information
rvalyi committed Sep 28, 2024
1 parent e9aba88 commit 6bd980d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 35 deletions.
30 changes: 3 additions & 27 deletions l10n_br_base/models/party_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,6 @@ class PartyMixin(models.AbstractModel):
_name = "l10n_br_base.party.mixin"
_description = "Brazilian partner and company data mixin"

cnpj_cpf_stripped = fields.Char(
string="CNPJ/CPF Stripped",
help="CNPJ/CPF without special characters",
compute="_compute_cnpj_cpf_stripped",
store=True,
index=True,
)

cnpj_cpf = fields.Char(
string="CNPJ/CPF",
size=18,
unaccent=False,
)

inscr_est = fields.Char(
string="State Tax Number",
size=17,
Expand Down Expand Up @@ -74,19 +60,9 @@ class PartyMixin(models.AbstractModel):
size=32,
)

@api.depends("cnpj_cpf")
def _compute_cnpj_cpf_stripped(self):
for record in self:
if record.cnpj_cpf:
record.cnpj_cpf_stripped = "".join(
char for char in record.cnpj_cpf if char.isalnum()
)
else:
record.cnpj_cpf_stripped = False

@api.onchange("cnpj_cpf")
def _onchange_cnpj_cpf(self):
self.cnpj_cpf = cnpj_cpf.formata(str(self.cnpj_cpf))
@api.onchange("vat")
def _onchange_vat(self):
self.vat = cnpj_cpf.formata(str(self.vat))

@api.onchange("zip")
def _onchange_zip(self):
Expand Down
21 changes: 21 additions & 0 deletions l10n_br_base/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ def _inverse_suframa(self):
for company in self:
company.partner_id.suframa = company.suframa

# this helps maintaining the compatibility with the existing codebase:
cnpj_cpf = fields.Char(related="vat", readonly=False, string="CNPJ/CPF")

cnpj_cpf_stripped = fields.Char(
string="CNPJ/CPF Stripped",
help="CNPJ/CPF without special characters",
compute="_compute_cnpj_cpf_stripped",
store=True,
index=True,
)

legal_name = fields.Char(
compute="_compute_address",
inverse="_inverse_legal_name",
Expand Down Expand Up @@ -143,6 +154,16 @@ def _inverse_suframa(self):
inverse="_inverse_suframa",
)

@api.depends("cnpj_cpf")
def _compute_cnpj_cpf_stripped(self):
for record in self:
if record.cnpj_cpf:
record.cnpj_cpf_stripped = "".join(
char for char in record.cnpj_cpf if char.isalnum()
)
else:
record.cnpj_cpf_stripped = False

@api.model
def _fields_view_get(
self, view_id=None, view_type="form", toolbar=False, submenu=False
Expand Down
114 changes: 108 additions & 6 deletions l10n_br_base/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,22 @@ def _inverse_street_data(self):
partner.street = street
return super(Partner, not_br_partner)._inverse_street_data()

vat = fields.Char(related="cnpj_cpf")
# this helps maintaining the compatibility with the existing codebase:
cnpj_cpf = fields.Char(
string="CNPJ/CPF",
inverse="_inverse_cnpj_cpf",
compute="_compute_cnpj_cpf",
)

cnpj_cpf_stripped = fields.Char(
string="CNPJ/CPF Stripped",
help="CNPJ/CPF without special characters",
compute="_compute_cnpj_cpf_stripped",
store=True,
index=True,
)

l10n_br_cpf_code = fields.Char(string="CPF", help="Natural Persons Register.")

is_accountant = fields.Boolean(string="Is accountant?")

Expand Down Expand Up @@ -61,7 +76,82 @@ def _inverse_street_data(self):
help="Indicate if is a Brazilian partner",
)

@api.constrains("cnpj_cpf", "inscr_est")
@api.onchange("cnpj_cpf")
def _inverse_cnpj_cpf(self):
for partner in self:
if len(partner.cnpj_cpf) > 11:
partner.vat = partner.cnpj_cpf
else:
partner.l10n_br_cpf_code = partner.cnpj_cpf

@api.depends("vat")
def _compute_cnpj_cpf(self):
for partner in self:
partner.cnpj_cpf = partner.vat or partner.l10n_br_cpf_code

@api.depends("cnpj_cpf")
def _compute_cnpj_cpf_stripped(self):
for record in self:
if record.cnpj_cpf:
record.cnpj_cpf_stripped = "".join(
char for char in record.cnpj_cpf if char.isalnum()
)
else:
record.cnpj_cpf_stripped = False

def _commercial_sync_from_company(self):
"""
Overriden to avoid copying the CNPJ (vat field) to children companies
"""
if not self.is_br_partner:
return super()._commercial_sync_from_company()

commercial_partner = self.commercial_partner_id
if commercial_partner != self:
sync_vals = commercial_partner._update_fields_values(
[field for field in self._commercial_fields() if field != "vat"]
)
self.write(sync_vals)
self._commercial_sync_to_children()

def _commercial_sync_to_children(self, fields_to_sync=None):
"""
Overriden to avoid copying the CNPJ (vat field) to parent partners
"""
if not self.is_br_partner:
return super()._commercial_sync_to_children()

commercial_partner = self.commercial_partner_id
if fields_to_sync is None:
fields_to_sync = self._commercial_fields()
sync_vals = commercial_partner._update_fields_values(
[field for field in self._commercial_fields() if field != "vat"]
)
sync_children = self.child_ids.filtered(lambda c: not c.is_company)
for child in sync_children:
child._commercial_sync_to_children(fields_to_sync)
res = sync_children.write(sync_vals)
return res

def _children_sync(self, values):
if not self.is_br_partner:
return super()._children_sync()

if not self.child_ids:
return
# 2a. Commercial Fields: sync if commercial entity
if self.commercial_partner_id == self:
fields_to_sync = values.keys() & [
field for field in self._commercial_fields() if field != "vat"
]
self.sudo()._commercial_sync_to_children(fields_to_sync)
# 2b. Address fields: sync if address changed
address_fields = self._address_fields()
if any(field in values for field in address_fields):
contacts = self.child_ids.filtered(lambda c: c.type == "contact")
contacts.update_address(values)

@api.constrains("vat", "inscr_est")
def _check_cnpj_inscr_est(self):
for record in self:
domain = []
Expand All @@ -88,7 +178,8 @@ def _check_cnpj_inscr_est(self):
domain += [("cnpj_cpf", "=", record.cnpj_cpf), ("id", "!=", record.id)]

# se encontrar CNPJ iguais
if record.env["res.partner"].search(domain):
matches = record.env["res.partner"].search(domain)
if matches:
if cnpj_cpf.validar_cnpj(record.cnpj_cpf):
if allow_cnpj_multi_ie == "True":
for partner in record.env["res.partner"].search(domain):
Expand All @@ -104,14 +195,25 @@ def _check_cnpj_inscr_est(self):
)
else:
raise ValidationError(
_("There is already a partner record with this CNPJ !")
_(
"There is already a partner %(name)s "
"(ID %(partner_id)s) with this CNPJ %(vat)s!",
name=matches[0].name,
partner_id=matches[0].id,
vat=self.vat,
)
)
else:
raise ValidationError(
_("There is already a partner record with this CPF/RG!")
_(
"There is already a partner %(name)s (ID %(partner_id)s) "
"with this CPF/RG!",
name=matches[0].name,
partner_id=matches[0].id,
)
)

@api.constrains("cnpj_cpf", "country_id")
@api.constrains("vat", "country_id")
def _check_cnpj_cpf(self):
for record in self:
check_cnpj_cpf(
Expand Down
4 changes: 2 additions & 2 deletions l10n_br_base/tests/test_base_onchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_onchange(self):
"""
Call all the onchange methods in l10n_br_base
"""
self.company_01._onchange_cnpj_cpf()
self.company_01._onchange_vat()
self.company_01._onchange_city_id()
self.company_01._onchange_zip()
self.company_01._onchange_state()
Expand All @@ -53,7 +53,7 @@ def test_onchange(self):
# chamado, por isso existe outro metodo com o final _id
self.company_01._onchange_state_id()

self.partner_01._onchange_cnpj_cpf()
self.partner_01._onchange_vat()
self.partner_01._onchange_city_id()
self.partner_01._onchange_zip()
self.partner_01._onchange_state()
Expand Down

0 comments on commit 6bd980d

Please sign in to comment.