Skip to content

Commit e615143

Browse files
[IMP] l10n_br_cnpj_search: add a wizard for verification of the data
1 parent 9ed5919 commit e615143

20 files changed

+368
-74
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

+21-20
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,40 @@
11
# Copyright 2022 KMEE
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

4-
from erpbrasil.base.misc import punctuation_rm
5-
from requests import get
6-
74
from odoo import _, api, models
85
from odoo.exceptions import UserError
96

107

118
class PartyMixin(models.AbstractModel):
129
_inherit = "l10n_br_base.party.mixin"
1310

14-
def search_cnpj(self):
15-
"""Search CNPJ by the chosen API"""
11+
def action_open_cnpj_search_wizard(self, mockresponse=False):
1612
if not self.cnpj_cpf:
17-
raise UserError(_("Por favor insira o CNPJ"))
18-
13+
raise UserError(_("Please enter your CNPJ"))
1914
if self.cnpj_validation_disabled():
2015
raise UserError(
2116
_(
22-
"It is necessary to activate the option to validate de CNPJ to use this "
23-
+ "functionality."
17+
"It is necessary to activate the option to validate de CNPJ to use"
18+
" this functionality."
2419
)
2520
)
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)
21+
if self._name == "res.partner":
22+
default_partner_id = self.id
23+
else:
24+
default_partner_id = self.partner_id.id
25+
26+
return {
27+
"name": "Search Data by CNPJ",
28+
"type": "ir.actions.act_window",
29+
"res_model": "partner.search.wizard",
30+
"view_type": "form",
31+
"view_mode": "form",
32+
"context": {
33+
"default_partner_id": default_partner_id,
34+
"mockresponse": mockresponse,
35+
},
36+
"target": "new",
37+
}
3738

3839
@api.model
3940
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

+22-8
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@ def setUp(self):
1717
self.set_param("cnpj_provider", "receitaws")
1818

1919
def test_receita_ws_success(self):
20-
kilian = self.model.create({"name": "Kilian", "cnpj_cpf": "44.356.113/0001-08"})
21-
22-
kilian._onchange_cnpj_cpf()
23-
kilian.search_cnpj()
20+
kilian = self.model.create(
21+
{
22+
"name": "Kilian",
23+
"cnpj_cpf": "44.356.113/0001-08",
24+
}
25+
)
2426

27+
action_wizard = kilian.action_open_cnpj_search_wizard()
28+
wizard_context = action_wizard.get("context")
29+
wizard = (
30+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
31+
)
32+
wizard.action_update_partner()
2533
self.assertEqual(kilian.company_type, "company")
2634
self.assertEqual(kilian.legal_name, "Kilian Macedo Melcher 08777131460")
2735
self.assertEqual(kilian.name, "Kilian Macedo Melcher 08777131460")
@@ -35,23 +43,29 @@ def test_receita_ws_success(self):
3543
self.assertEqual(kilian.state_id.code, "PB")
3644
self.assertEqual(kilian.city_id.name, "Campina Grande")
3745
self.assertEqual(kilian.equity_capital, 3000)
38-
self.assertEqual(kilian.cnae_main_id.code, "4751-2/01")
3946

4047
def test_receita_ws_fail(self):
4148
invalido = self.model.create({"name": "invalido", "cnpj_cpf": "00000000000000"})
4249
invalido._onchange_cnpj_cpf()
4350

4451
time.sleep(2) # Pause
4552
with self.assertRaises(ValidationError):
46-
invalido.search_cnpj()
53+
action_wizard = invalido.action_open_cnpj_search_wizard()
54+
wizard_context = action_wizard.get("context")
55+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
56+
invalido.action_open_cnpj_search_wizard()
4757

4858
def test_receita_ws_multiple_phones(self):
4959
isla = self.model.create({"name": "Isla", "cnpj_cpf": "92.666.056/0001-06"})
5060
isla._onchange_cnpj_cpf()
5161

5262
time.sleep(2) # Pause
53-
isla.search_cnpj()
54-
63+
action_wizard = isla.action_open_cnpj_search_wizard()
64+
wizard_context = action_wizard.get("context")
65+
wizard = (
66+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
67+
)
68+
wizard.action_update_partner()
5569
self.assertEqual(isla.name.strip(), "Isla Sementes Ltda.")
5670
self.assertEqual(isla.phone.strip(), "(51) 9852-9561")
5771
self.assertEqual(isla.mobile.strip(), "(51) 2136-6600")

l10n_br_cnpj_search/tests/test_serpro.py

+23-6
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,18 @@ def test_serpro_basica(self):
3636
)
3737
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,17 @@ 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

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

7582
def assert_socios(self, partner, expected_cnpjs):
7683
socios = self.model.search_read(
@@ -128,7 +135,12 @@ def test_serpro_empresa(self):
128135

129136
time.sleep(3) # Pause
130137
dummy_empresa._onchange_cnpj_cpf()
131-
dummy_empresa.search_cnpj()
138+
action_wizard = dummy_empresa.action_open_cnpj_search_wizard()
139+
wizard_context = action_wizard.get("context")
140+
wizard = (
141+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
142+
)
143+
wizard.action_update_partner()
132144

133145
expected_cnpjs = {
134146
"Joana": "23982012600",
@@ -157,7 +169,12 @@ def test_serpro_qsa(self):
157169

158170
time.sleep(3) # Pause
159171
dummy_qsa._onchange_cnpj_cpf()
160-
dummy_qsa.search_cnpj()
172+
action_wizard = dummy_qsa.action_open_cnpj_search_wizard()
173+
wizard_context = action_wizard.get("context")
174+
wizard = (
175+
self.env["partner.search.wizard"].with_context(wizard_context).create({})
176+
)
177+
wizard.action_update_partner()
161178

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

0 commit comments

Comments
 (0)