Skip to content

Commit bb45367

Browse files
CristianoMafraJuniorantoniospneto
authored andcommitted
[IMP] l10n_br_cnpj_search: add a wizard for verification of the data
1 parent 00bb13e commit bb45367

13 files changed

+252
-44
lines changed

l10n_br_cnpj_search/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
22

33
from . import models
4+
from . import wizard

l10n_br_cnpj_search/__manifest__.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
],
1717
"data": [
1818
"security/ir.model.access.csv",
19+
"wizard/partner_cnpj_search_wizard.xml",
1920
"views/res_partner_view.xml",
2021
"views/res_company_view.xml",
2122
"views/res_config_settings_view.xml",

l10n_br_cnpj_search/models/l10n_br_base_party_mixin.py

+22-20
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# Copyright 2022 KMEE
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3-
4-
from erpbrasil.base.misc import punctuation_rm
5-
from requests import get
3+
# Copyright (C) 2024-Today - Engenere (<https://engenere.one>).
4+
# @author Cristiano Mafra Junior
65

76
from odoo import _, api, models
87
from odoo.exceptions import UserError
@@ -11,29 +10,32 @@
1110
class PartyMixin(models.AbstractModel):
1211
_inherit = "l10n_br_base.party.mixin"
1312

14-
def search_cnpj(self):
15-
"""Search CNPJ by the chosen API"""
13+
def action_open_cnpj_search_wizard(self):
1614
if not self.cnpj_cpf:
17-
raise UserError(_("Por favor insira o CNPJ"))
18-
15+
raise UserError(_("Please enter your CNPJ"))
1916
if self.cnpj_validation_disabled():
2017
raise UserError(
2118
_(
22-
"It is necessary to activate the option to validate de CNPJ to use this "
23-
+ "functionality."
19+
"It is necessary to activate the option to validate de CNPJ to use"
20+
" this functionality."
2421
)
2522
)
26-
27-
cnpj_cpf = punctuation_rm(self.cnpj_cpf)
28-
webservice = self.env["l10n_br_cnpj_search.webservice.abstract"]
29-
response = get(
30-
webservice.get_api_url(cnpj_cpf), headers=webservice.get_headers()
31-
)
32-
33-
data = webservice.validate(response)
34-
values = webservice.import_data(data)
35-
values["company_type"] = "company"
36-
self.write(values)
23+
if self._name == "res.partner":
24+
default_partner_id = self.id
25+
else:
26+
default_partner_id = self.partner_id.id
27+
28+
return {
29+
"name": "Search Data by CNPJ",
30+
"type": "ir.actions.act_window",
31+
"res_model": "partner.search.wizard",
32+
"view_type": "form",
33+
"view_mode": "form",
34+
"context": {
35+
"default_partner_id": default_partner_id,
36+
},
37+
"target": "new",
38+
}
3739

3840
@api.model
3941
def cnpj_validation_disabled(self):

l10n_br_cnpj_search/models/res_partner.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright 2022 KMEE - Luis Felipe Mileo
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

4-
54
from odoo import fields, models
65

76

l10n_br_cnpj_search/security/ir.model.access.csv

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
22
access_l10n_br_cnpj_search_webservice,access_l10n_br_cnpj_search_webservice,model_l10n_br_cnpj_search_webservice_abstract,base.group_user,1,1,1,1
33
"l10n_br_fiscal_partner_profile_user","l10n_br_fiscal.partner_profile","l10n_br_fiscal.model_l10n_br_fiscal_partner_profile","base.group_user",1,0,0,0
44
"l10n_br_fiscal_cnae","l10n_br_fiscal.cnae","l10n_br_fiscal.model_l10n_br_fiscal_cnae","base.group_user",1,0,0,0
5+
access_partner_search_wizard,res_partner_wizard,model_partner_search_wizard,base.group_user,1,1,1,1

l10n_br_cnpj_search/static/description/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
23
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
34
<head>

l10n_br_cnpj_search/tests/test_receitaws.py

+23-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Copyright 2022 KMEE
2+
# Copyright (C) 2024-Today - Engenere (<https://engenere.one>).
3+
# @author Cristiano Mafra Junior
24
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
35

46
import os
5-
import time # You can't send multiple requests at the same time in trial version
67

78
import vcr
89

@@ -25,11 +26,19 @@ def setUp(self):
2526
ignore_localhost=True,
2627
)
2728
def test_receita_ws_success(self):
28-
kilian = self.model.create({"name": "Kilian", "cnpj_cpf": "44.356.113/0001-08"})
29-
30-
kilian._onchange_cnpj_cpf()
31-
kilian.search_cnpj()
29+
kilian = self.model.create(
30+
{
31+
"name": "Kilian",
32+
"cnpj_cpf": "44.356.113/0001-08",
33+
}
34+
)
3235

36+
action_wizard = kilian.action_open_cnpj_search_wizard()
37+
wizard_context = action_wizard.get("context")
38+
wizard = (
39+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
40+
)
41+
wizard.action_update_partner()
3342
self.assertEqual(kilian.company_type, "company")
3443
self.assertEqual(kilian.legal_name, "Kilian Macedo Melcher 08777131460")
3544
self.assertEqual(kilian.name, "Kilian Macedo Melcher 08777131460")
@@ -54,9 +63,10 @@ def test_receita_ws_fail(self):
5463
invalido = self.model.create({"name": "invalido", "cnpj_cpf": "00000000000000"})
5564
invalido._onchange_cnpj_cpf()
5665

57-
time.sleep(2) # Pause
5866
with self.assertRaises(ValidationError):
59-
invalido.search_cnpj()
67+
action_wizard = invalido.action_open_cnpj_search_wizard()
68+
wizard_context = action_wizard.get("context")
69+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
6070

6171
@vcr.use_cassette(
6272
os.path.dirname(__file__) + "/fixtures/test_receitaws_multiplos_telefones.yaml",
@@ -67,9 +77,12 @@ def test_receita_ws_multiple_phones(self):
6777
isla = self.model.create({"name": "Isla", "cnpj_cpf": "92.666.056/0001-06"})
6878
isla._onchange_cnpj_cpf()
6979

70-
time.sleep(2) # Pause
71-
isla.search_cnpj()
72-
80+
action_wizard = isla.action_open_cnpj_search_wizard()
81+
wizard_context = action_wizard.get("context")
82+
wizard = (
83+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
84+
)
85+
wizard.action_update_partner()
7386
self.assertEqual(isla.name.strip(), "Isla Sementes Ltda.")
7487
self.assertEqual(isla.phone.strip(), "(51) 9852-9561")
7588
self.assertEqual(isla.mobile.strip(), "(51) 2136-6600")

l10n_br_cnpj_search/tests/test_serpro.py

+25-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Copyright 2022 KMEE
2+
# Copyright (C) 2024-Today - Engenere (<https://engenere.one>).
3+
# @author Cristiano Mafra Junior
24
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
35

46
import logging
57
import os
6-
import time # You can't send multiple requests at the same time in trial version
78

89
import vcr
910

@@ -34,15 +35,19 @@ def test_serpro_basica(self):
3435
dummy_basica = self.model.create(
3536
{"name": "Dummy Basica", "cnpj_cpf": "34.238.864/0001-68"}
3637
)
37-
time.sleep(3)
3838
dummy_basica._onchange_cnpj_cpf()
39-
dummy_basica.search_cnpj()
4039

41-
self.assertEqual(dummy_basica.company_type, "company")
40+
action_wizard = dummy_basica.action_open_cnpj_search_wizard()
41+
wizard_context = action_wizard.get("context")
42+
wizard = (
43+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
44+
)
45+
wizard.action_update_partner()
4246
self.assertEqual(
4347
dummy_basica.legal_name,
4448
"Uhieqkx Whnhiwd Nh Fixkhuuwphmvx Nh Nwnxu (Uhifix)",
4549
)
50+
self.assertEqual(dummy_basica.company_type, "company")
4651
self.assertEqual(dummy_basica.name, "Uhifix Uhnh")
4752
self.assertEqual(dummy_basica.email, "EMPRESA@XXXXXX.BR")
4853
self.assertEqual(dummy_basica.street_name, "Nh Biwmnh Wihw Mxivh")
@@ -62,15 +67,16 @@ def test_serpro_basica(self):
6267
ignore_localhost=True,
6368
)
6469
def test_serpro_not_found(self):
65-
# Na versão Trial só há alguns registros de CNPJ cadastrados
70+
# In the Trial version there are only a few registered CNPJ records
6671
invalid = self.model.create(
6772
{"name": "invalid", "cnpj_cpf": "44.356.113/0001-08"}
6873
)
6974
invalid._onchange_cnpj_cpf()
7075

71-
time.sleep(3) # Pause
7276
with self.assertRaises(ValidationError):
73-
invalid.search_cnpj()
77+
action_wizard = invalid.action_open_cnpj_search_wizard()
78+
wizard_context = action_wizard.get("context")
79+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
7480

7581
def assert_socios(self, partner, expected_cnpjs):
7682
socios = self.model.search_read(
@@ -126,9 +132,13 @@ def test_serpro_empresa(self):
126132
{"name": "Dummy Empresa", "cnpj_cpf": "34.238.864/0001-68"}
127133
)
128134

129-
time.sleep(3) # Pause
130135
dummy_empresa._onchange_cnpj_cpf()
131-
dummy_empresa.search_cnpj()
136+
action_wizard = dummy_empresa.action_open_cnpj_search_wizard()
137+
wizard_context = action_wizard.get("context")
138+
wizard = (
139+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
140+
)
141+
wizard.action_update_partner()
132142

133143
expected_cnpjs = {
134144
"Joana": "23982012600",
@@ -155,9 +165,13 @@ def test_serpro_qsa(self):
155165
{"name": "Dummy QSA", "cnpj_cpf": "34.238.864/0001-68"}
156166
)
157167

158-
time.sleep(3) # Pause
159168
dummy_qsa._onchange_cnpj_cpf()
160-
dummy_qsa.search_cnpj()
169+
action_wizard = dummy_qsa.action_open_cnpj_search_wizard()
170+
wizard_context = action_wizard.get("context")
171+
wizard = (
172+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
173+
)
174+
wizard.action_update_partner()
161175

162176
expected_cnpjs = {
163177
"Joana": False,

l10n_br_cnpj_search/views/res_company_view.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<div class="o_row" colspan="1">
1818
<field name="cnpj_cpf" />
1919
<button
20-
name="search_cnpj"
20+
name="action_open_cnpj_search_wizard"
2121
type="object"
2222
class="btn-sm btn-link mb4 fa fa-search oe_edit_only oe_inline"
2323
aria-label="Pesquisar CNPJ"

l10n_br_cnpj_search/views/res_partner_view.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<div class="o_row" colspan="4">
2020
<field name="cnpj_cpf" nolabel="1" />
2121
<button
22-
name="search_cnpj"
22+
name="action_open_cnpj_search_wizard"
2323
type="object"
2424
attrs="{'invisible':
2525
[
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import partner_cnpj_search_wizard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Copyright (C) 2024-Today - Engenere (<https://engenere.one>).
2+
# @author Cristiano Mafra Junior
3+
from erpbrasil.base.fiscal import cnpj_cpf
4+
from erpbrasil.base.misc import punctuation_rm
5+
from requests import get
6+
7+
from odoo import api, fields, models
8+
9+
10+
class PartnerCnpjSearchWizard(models.TransientModel):
11+
_name = "partner.search.wizard"
12+
13+
partner_id = fields.Many2one(comodel_name="res.partner")
14+
provider_name = fields.Char()
15+
cnpj_cpf = fields.Char()
16+
legal_name = fields.Char()
17+
name = fields.Char()
18+
inscr_est = fields.Char()
19+
zip = fields.Char()
20+
street_name = fields.Char()
21+
street_number = fields.Char()
22+
street2 = fields.Char()
23+
district = fields.Char()
24+
state_id = fields.Many2one(comodel_name="res.country.state")
25+
city_id = fields.Many2one(
26+
comodel_name="res.city",
27+
domain="[('state_id', '=', state_id)]",
28+
)
29+
country_id = fields.Many2one(comodel_name="res.country")
30+
phone = fields.Char()
31+
mobile = fields.Char()
32+
email = fields.Char()
33+
legal_nature = fields.Char()
34+
currency_id = fields.Many2one(
35+
comodel_name="res.currency",
36+
default=lambda self: self.env.ref("base.BRL"),
37+
)
38+
equity_capital = fields.Monetary(currency_field="currency_id")
39+
cnae_main_id = fields.Many2one(comodel_name="l10n_br_fiscal.cnae")
40+
cnae_secondary_ids = fields.Many2many(
41+
comodel_name="l10n_br_fiscal.cnae",
42+
relation="wizard_fiscal_cnae_rel",
43+
column1="company_id",
44+
column2="cnae_id",
45+
)
46+
child_ids = fields.Many2many(
47+
comodel_name="res.partner",
48+
relation="parent_id_wizard_id",
49+
column1="parent_id",
50+
column2="wizard_id",
51+
)
52+
53+
@api.onchange("cnpj_cpf")
54+
def _onchange_cnpj_cpf(self):
55+
self.cnpj_cpf = cnpj_cpf.formata(str(self.cnpj_cpf))
56+
57+
def _get_partner_values(self, cnpj_cpf):
58+
webservice = self.env["l10n_br_cnpj_search.webservice.abstract"]
59+
provider_name = webservice.get_provider()
60+
response = get(
61+
webservice.get_api_url(cnpj_cpf), headers=webservice.get_headers()
62+
)
63+
data = webservice.validate(response)
64+
values = webservice.import_data(data)
65+
values["provider_name"] = provider_name
66+
values["cnpj_cpf"] = cnpj_cpf
67+
return values
68+
69+
def default_get(self, fields):
70+
res = super().default_get(fields)
71+
partner_id = self._context.get("default_partner_id")
72+
partner_model = self.env["res.partner"]
73+
partner = partner_model.browse(partner_id)
74+
cnpj_cpf = punctuation_rm(partner.cnpj_cpf)
75+
values = self._get_partner_values(cnpj_cpf)
76+
res.update(values)
77+
return res
78+
79+
def action_update_partner(self):
80+
values_to_update = {
81+
"legal_name": self.legal_name,
82+
"name": self.name,
83+
"inscr_est": self.inscr_est,
84+
"zip": self.zip,
85+
"street_name": self.street_name,
86+
"street_number": self.street_number,
87+
"street2": self.street2,
88+
"district": self.district,
89+
"state_id": self.state_id.id,
90+
"city_id": self.city_id.id,
91+
"country_id": self.country_id.id,
92+
"phone": self.phone,
93+
"mobile": self.mobile,
94+
"email": self.email,
95+
"legal_nature": self.legal_nature,
96+
"equity_capital": self.equity_capital,
97+
"cnae_main_id": self.cnae_main_id,
98+
"cnae_secondary_ids": self.cnae_secondary_ids,
99+
"child_ids": [(6, 0, self.child_ids.ids)],
100+
"company_type": "company",
101+
}
102+
non_empty_values = {
103+
key: value for key, value in values_to_update.items() if value
104+
}
105+
if non_empty_values:
106+
# Update partner only if there are non-empty values
107+
self.partner_id.write(non_empty_values)
108+
return {"type": "ir.actions.act_window_close"}

0 commit comments

Comments
 (0)