Skip to content

Commit c465322

Browse files
feat: add Natureza Jurídica utilities (#653)
* commits iniciais * organizing feature * organizing init file * adjusting test names and conflicts
1 parent 178ebd9 commit c465322

6 files changed

Lines changed: 402 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Utilitário `convert_name_to_uf`
13+
- Utilitário `is_valid_legal_nature` [#641](https://github.com/brazilian-utils/python/issues/641)
14+
- Utilitário `get_legal_nature_description` [#641](https://github.com/brazilian-utils/python/issues/641)
15+
- Utilitário `list_all_legal_nature` [#641](https://github.com/brazilian-utils/python/issues/641)
1316
- Utilitário `is_valid_cnh` [#651](https://github.com/brazilian-utils/brutils-python/pull/651)
1417
- Utilitário `is_valid_renavam` [#652](https://github.com/brazilian-utils/brutils-python/pull/652)
1518

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ False
105105
- [Monetário](#monetário)
106106
- [format\_currency](#format_currency)
107107
- [convert\_real\_to\_text](#convert_real_to_text)
108+
- [Natureza Jurídica](#natureza-jurídica)
109+
- [is_valid_legal_nature](#is_valid_legal_nature)
110+
- [get_legal_nature_description](#get_legal_nature_description)
111+
- [list_all_legal_nature](#list_all_legal_nature)
108112

109113
## CPF
110114

@@ -1377,6 +1381,71 @@ Exemplo:
13771381
None
13781382
```
13791383

1384+
## Natureza Jurídica
1385+
1386+
### is_valid_legal_nature
1387+
1388+
Valida se o código informado existe na tabela oficial. Aceita `NNNN` ou `NNN-N`.
1389+
O valor é **normalizado** antes da checagem: remove espaços, mantém apenas dígitos e aceita hífen entre o 3º e 4º dígitos.
1390+
1391+
**Argumentos**
1392+
- `code (str)`: Código de 4 dígitos (ex.: `"2062"` ou `"206-2"`)
1393+
1394+
**Retorna**
1395+
- `bool`: `True` se existir na tabela, `False` caso contrário.
1396+
1397+
**Exemplo**
1398+
```python
1399+
>>> from brutils import legal_nature
1400+
>>> legal_nature.is_valid("2062")
1401+
True
1402+
>>> legal_nature.is_valid("206-2")
1403+
True
1404+
>>> legal_nature.is_valid("9999")
1405+
False
1406+
```
1407+
1408+
### get_legal_nature_description
1409+
1410+
Retorna a **descrição oficial** do código de Natureza Jurídica. Aceita `NNNN` ou `NNN-N`. Aplica a mesma normalização do `is_valid`.
1411+
1412+
**Argumentos**
1413+
1414+
* `code (str)`: Código de 4 dígitos
1415+
1416+
**Retorna**
1417+
1418+
* `str | None`: Descrição correspondente ou `None` se o código for inválido ou inexistente.
1419+
1420+
**Exemplo**
1421+
1422+
```python
1423+
>>> from brutils import legal_nature
1424+
>>> legal_nature.get_description("2062")
1425+
'Sociedade Empresária Limitada'
1426+
>>> legal_nature.get_description("101-5")
1427+
'Órgão Público do Poder Executivo Federal'
1428+
>>> legal_nature.get_description("0000")
1429+
None
1430+
```
1431+
1432+
### list_all_legal_nature
1433+
1434+
Retorna uma cópia do dicionário completo `{codigo: descricao}`.
1435+
1436+
**Retorna**
1437+
1438+
* `dict[str, str]`: Mapeamento de todos os códigos para suas descrições.
1439+
1440+
**Exemplo**
1441+
1442+
```python
1443+
>>> from brutils import legal_nature
1444+
>>> data = legal_nature.list_all()
1445+
>>> len(data) > 0
1446+
True
1447+
>>> data["2062"]
1448+
'Sociedade Empresária Limitada'
13801449
## RENAVAM
13811450

13821451
### is_valid_renavam

README_EN.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ False
104104
- [Monetary](#monetary)
105105
- [format_currency](#format_currency)
106106
- [convert\_real\_to\_text](#convert_real_to_text)
107+
- [Legal Nature](#legal-nature)
108+
- [is_valid_legal_nature](#is_valid_legal_nature)
109+
- [get_legal_nature_description](#get_legal_nature_description)
110+
- [list_all_legal_nature](#list_all_legal_nature)
107111

108112
## CPF
109113

@@ -1381,6 +1385,72 @@ Example:
13811385
None
13821386
```
13831387

1388+
## Legal Nature
1389+
1390+
### is_valid_legal_nature
1391+
1392+
Validates if the given code exists in the official table. Accepts `NNNN` or `NNN-N`.
1393+
The value is **normalized** before checking: removes spaces, keeps only digits, and accepts a hyphen between the 3rd and 4th digits.
1394+
1395+
**Arguments**
1396+
- `code (str)`: 4-digit code (e.g.: `"2062"` or `"206-2"`)
1397+
1398+
**Returns**
1399+
- `bool`: `True` if it exists in the table, `False` otherwise.
1400+
1401+
**Example**
1402+
```python
1403+
>>> from brutils import legal_nature
1404+
>>> legal_nature.is_valid("2062")
1405+
True
1406+
>>> legal_nature.is_valid("206-2")
1407+
True
1408+
>>> legal_nature.is_valid("9999")
1409+
False
1410+
```
1411+
1412+
### get_legal_nature_description
1413+
1414+
Returns the **official description** for the Legal Nature code. Accepts `NNNN` or `NNN-N`. Applies the same normalization as `is_valid`.
1415+
1416+
**Arguments**
1417+
1418+
* `code (str)`: 4-digit code
1419+
1420+
**Returns**
1421+
1422+
* `str | None`: The corresponding description or `None` if the code is invalid or non-existent.
1423+
1424+
**Example**
1425+
1426+
```python
1427+
>>> from brutils import legal_nature
1428+
>>> legal_nature.get_description("2062")
1429+
'Sociedade Empresária Limitada'
1430+
>>> legal_nature.get_description("101-5")
1431+
'Órgão Público do Poder Executivo Federal'
1432+
>>> legal_nature.get_description("0000")
1433+
None
1434+
```
1435+
1436+
### list_all_legal_nature
1437+
1438+
Returns a copy of the complete dictionary `{code: description}`.
1439+
1440+
**Returns**
1441+
1442+
* `dict[str, str]`: Mapping of all codes to their descriptions.
1443+
1444+
**Example**
1445+
1446+
```python
1447+
>>> from brutils import legal_nature
1448+
>>> data = legal_nature.list_all()
1449+
>>> len(data) > 0
1450+
True
1451+
>>> data["2062"]
1452+
'Sociedade Empresária Limitada'
1453+
```
13841454
## RENAVAM
13851455

13861456
### is_valid_renavam

brutils/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
convert_uf_to_name,
4444
)
4545

46+
# Legal Nature imports
47+
from brutils.legal_nature import get_description as get_natureza_legal_nature
48+
from brutils.legal_nature import is_valid as is_valid_legal_nature
49+
from brutils.legal_nature import list_all as list_all_legal_nature
50+
4651
# Legal Process Imports
4752
from brutils.legal_process import format_legal_process
4853
from brutils.legal_process import generate as generate_legal_process
@@ -146,4 +151,8 @@
146151
# Currency
147152
"format_currency",
148153
"convert_real_to_text",
154+
# Legal Nature
155+
"is_valid_legal_nature",
156+
"get_natureza_legal_nature",
157+
"list_all_legal_nature",
149158
]

brutils/legal_nature.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
"""
2+
brutils.legal_nature
3+
~~~~~~~~~~~~~~~~~~~~~~~~~
4+
5+
Utilities for consulting and validating the official
6+
*Natureza Jurídica* (Legal Nature) codes defined by the
7+
Receita Federal do Brasil (RFB).
8+
9+
.. note::
10+
The codes and descriptions in this module are sourced from the
11+
official **Tabela de Natureza Jurídica** (RFB), as provided in the
12+
document used by the Cadastro Nacional (e.g., FCN).
13+
14+
This module offers simple lookups and validation helpers based on
15+
the official table. It does not infer the current legal/registration
16+
status of any entity.
17+
18+
Source: https://www.gov.br/empresas-e-negocios/pt-br/drei/links-e-downloads/arquivos/TABELADENATUREZAJURDICA.pdf
19+
"""
20+
21+
from typing import Dict, Optional
22+
23+
# FORMATTING
24+
############
25+
26+
27+
# Helper to normalize inputs like "101-5" => "1015"
28+
def _normalize(code: str) -> Optional[str]:
29+
if not isinstance(code, str):
30+
return None
31+
32+
digits = "".join(ch for ch in code.strip() if ch.isdigit())
33+
34+
return digits if len(digits) == 4 else None
35+
36+
37+
LEGAL_NATURE: Dict[str, str] = {
38+
# 1. ADMINISTRAÇÃO PÚBLICA
39+
"1015": "Órgão Público do Poder Executivo Federal",
40+
"1023": "Órgão Público do Poder Executivo Estadual ou do Distrito Federal",
41+
"1031": "Órgão Público do Poder Executivo Municipal",
42+
"1040": "Órgão Público do Poder Legislativo Federal",
43+
"1058": "Órgão Público do Poder Legislativo Estadual ou do Distrito Federal",
44+
"1066": "Órgão Público do Poder Legislativo Municipal",
45+
"1074": "Órgão Público do Poder Judiciário Federal",
46+
"1082": "Órgão Público do Poder Judiciário Estadual",
47+
"1104": "Autarquia Federal",
48+
"1112": "Autarquia Estadual ou do Distrito Federal",
49+
"1120": "Autarquia Municipal",
50+
"1139": "Fundação Federal",
51+
"1147": "Fundação Estadual ou do Distrito Federal",
52+
"1155": "Fundação Municipal",
53+
"1163": "Órgão Público Autônomo da União",
54+
"1171": "Órgão Público Autônomo Estadual ou do Distrito Federal",
55+
"1180": "Órgão Público Autônomo Municipal",
56+
# 2. ENTIDADES EMPRESARIAIS
57+
"2011": "Empresa Pública",
58+
"2038": "Sociedade de Economia Mista",
59+
"2046": "Sociedade Anônima Aberta",
60+
"2054": "Sociedade Anônima Fechada",
61+
"2062": "Sociedade Empresária Limitada",
62+
"2076": "Sociedade Empresária em Nome Coletivo",
63+
"2089": "Sociedade Empresária em Comandita Simples",
64+
"2097": "Sociedade Empresária em Comandita por Ações",
65+
"2100": "Sociedade Mercantil de Capital e Indústria (extinta pelo NCC/2002)",
66+
"2127": "Sociedade Empresária em Conta de Participação",
67+
"2135": "Empresário (Individual)",
68+
"2143": "Cooperativa",
69+
"2151": "Consórcio de Sociedades",
70+
"2160": "Grupo de Sociedades",
71+
"2178": "Estabelecimento, no Brasil, de Sociedade Estrangeira",
72+
"2194": "Estabelecimento, no Brasil, de Empresa Binacional Argentino-Brasileira",
73+
"2208": "Entidade Binacional Itaipu",
74+
"2216": "Empresa Domiciliada no Exterior",
75+
"2224": "Clube/Fundo de Investimento",
76+
"2232": "Sociedade Simples Pura",
77+
"2240": "Sociedade Simples Limitada",
78+
"2259": "Sociedade em Nome Coletivo",
79+
"2267": "Sociedade em Comandita Simples",
80+
"2275": "Sociedade Simples em Conta de Participação",
81+
"2305": "Empresa Individual de Responsabilidade Limitada",
82+
# 3. ENTIDADES SEM FINS LUCRATIVOS
83+
"3034": "Serviço Notarial e Registral (Cartório)",
84+
"3042": "Organização Social",
85+
"3050": "Organização da Sociedade Civil de Interesse Público (Oscip)",
86+
"3069": "Outras Formas de Fundações Mantidas com Recursos Privados",
87+
"3077": "Serviço Social Autônomo",
88+
"3085": "Condomínio Edilícios",
89+
"3093": "Unidade Executora (Programa Dinheiro Direto na Escola)",
90+
"3107": "Comissão de Conciliação Prévia",
91+
"3115": "Entidade de Mediação e Arbitragem",
92+
"3123": "Partido Político",
93+
"3131": "Entidade Sindical",
94+
"3204": "Estabelecimento, no Brasil, de Fundação ou Associação Estrangeiras",
95+
"3212": "Fundação ou Associação Domiciliada no Exterior",
96+
"3999": "Outras Formas de Associação",
97+
# 4. PESSOAS FÍSICAS
98+
"4014": "Empresa Individual Imobiliária",
99+
"4022": "Segurado Especial",
100+
"4081": "Contribuinte individual",
101+
# 5. ORGANIZAÇÕES INTERNACIONAIS E OUTRAS INSTITUIÇÕES EXTRATERRITORIAIS
102+
"5002": "Organização Internacional e Outras Instituições Extraterritoriais",
103+
}
104+
105+
# OPERATIONS
106+
############
107+
108+
109+
def is_valid(code: str) -> bool:
110+
"""
111+
Check if a string corresponds to a valid *Natureza Jurídica* code.
112+
113+
Args:
114+
code (str): The code to be validated. Accepts either "NNNN" or "NNN-N".
115+
116+
Returns:
117+
bool: True if the normalized code exists in the official table, False otherwise.
118+
119+
Example:
120+
>>> is_valid("2062")
121+
True
122+
>>> is_valid("206-2")
123+
True
124+
>>> is_valid("9999")
125+
False
126+
127+
.. note::
128+
Validation is based solely on the presence of the code in the
129+
official RFB table. It does not verify the current legal status
130+
or registration of the entity.
131+
"""
132+
normalized = _normalize(code)
133+
return normalized in LEGAL_NATURE if normalized else False
134+
135+
136+
def get_description(code: str) -> Optional[str]:
137+
"""
138+
Retrieve the description of a *Natureza Jurídica* code.
139+
140+
Args:
141+
code (str): The code to look up. Accepts either "NNNN" or "NNN-N".
142+
143+
Returns:
144+
str | None: The full description if the code is valid, otherwise None.
145+
146+
Example:
147+
>>> get_description("2062")
148+
'Sociedade Empresária Limitada'
149+
>>> get_description("101-5")
150+
'Órgão Público do Poder Executivo Federal'
151+
>>> get_description("0000")
152+
None
153+
"""
154+
normalized = _normalize(code)
155+
return LEGAL_NATURE.get(normalized) if normalized else None
156+
157+
158+
def list_all() -> Dict[str, str]:
159+
"""
160+
Return a copy of the full *Natureza Jurídica* table.
161+
162+
Returns:
163+
dict[str, str]: Mapping from "NNNN" codes to descriptions.
164+
"""
165+
return dict(LEGAL_NATURE)

0 commit comments

Comments
 (0)