Skip to content

Commit 7b2b3e5

Browse files
feat: Support for the new alphanumeric CNPJ
1 parent 24f4dc8 commit 7b2b3e5

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ Exemplo:
228228
True
229229
>>> is_valid_cnpj('00111222000133')
230230
False
231+
>>> is_valid_cnpj('12ABC34501DE35')
232+
True
231233
```
232234

233235
### format_cnpj
@@ -276,6 +278,8 @@ Exemplo:
276278
>>> from brutils import remove_symbols_cnpj
277279
>>> remove_symbols_cnpj('00.111.222/0001-00')
278280
'00111222000100'
281+
>>> remove_symbols_cnpj('12.ABC.345/01DE-35')
282+
'12ABC34501DE35'
279283
```
280284

281285
### generate_cnpj

README_EN.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ Example:
229229
True
230230
>>> is_valid_cnpj('00111222000133')
231231
False
232+
>>> is_valid_cnpj('12ABC34501DE35')
233+
True
232234
```
233235

234236
### format_cnpj
@@ -278,6 +280,8 @@ Example:
278280
>>> from brutils import remove_symbols_cnpj
279281
>>> remove_symbols_cnpj('00.111.222/0001-00')
280282
'00111222000100'
283+
>>> remove_symbols_cnpj('12.ABC.345/01DE-35')
284+
'12ABC34501DE35'
281285
```
282286

283287
### generate_cnpj

brutils/cnpj.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def validate(cnpj: str) -> bool:
151151
backward compatibility.
152152
"""
153153

154-
if not cnpj.isdigit() or len(cnpj) != 14 or len(set(cnpj)) == 1:
154+
if len(cnpj) != 14 or len(set(cnpj)) == 1:
155155
return False
156156
return all(
157157
_hashdigit(cnpj, i + 13) == int(v) for i, v in enumerate(cnpj[12:])
@@ -230,7 +230,11 @@ def _hashdigit(cnpj: str, position: int) -> int:
230230

231231
weightgen = chain(range(position - 8, 1, -1), range(9, 1, -1))
232232
val = (
233-
sum(int(digit) * weight for digit, weight in zip(cnpj, weightgen)) % 11
233+
sum(
234+
(ord(char) - 48) * weight
235+
for char, weight in zip(cnpj, weightgen)
236+
)
237+
% 11
234238
)
235239
return 0 if val < 2 else 11 - val
236240

tests/test_cnpj.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def test_validate(self):
3535
self.assertIs(validate("34665388000161"), True)
3636
self.assertIs(validate("52599927000100"), False)
3737
self.assertIs(validate("00000000000"), False)
38+
self.assertIs(validate("12ABC34501DE35"), True)
39+
self.assertIs(validate("12ABC34501DE00"), False)
40+
self.assertIs(validate("AAAAAAAAAAAAAA"), False)
41+
self.assertIs(validate("12ABC34501DE3"), False)
3842

3943
def test_is_valid(self):
4044
# When CNPJ is not string, returns False
@@ -66,6 +70,7 @@ def test_is_valid(self):
6670
# When CNPJ is valid
6771
self.assertIs(is_valid("34665388000161"), True)
6872
self.assertIs(is_valid("01838723000127"), True)
73+
self.assertIs(is_valid("12ABC34501DE35"), True)
6974

7075
def test_generate(self):
7176
for _ in range(10_000):
@@ -77,10 +82,15 @@ def test__hashdigit(self):
7782
self.assertEqual(_hashdigit("00000000000000", 14), 0)
7883
self.assertEqual(_hashdigit("52513127000292", 13), 9)
7984
self.assertEqual(_hashdigit("52513127000292", 14), 9)
85+
self.assertEqual(_hashdigit("12ABC34501DE", 13), 3)
86+
self.assertEqual(_hashdigit("12ABC34501DE3", 14), 5)
8087

8188
def test__checksum(self):
8289
self.assertEqual(_checksum("00000000000000"), "00")
8390
self.assertEqual(_checksum("52513127000299"), "99")
91+
self.assertEqual(_checksum("12ABC34501DE35"), "35")
92+
self.assertEqual(_checksum("1345C3A50001"), "06")
93+
self.assertEqual(_checksum("R55231B30007"), "57")
8494

8595

8696
@patch("brutils.cnpj.sieve")
@@ -89,6 +99,8 @@ def test_remove_symbols(self, mock_sieve):
8999
# When call remove_symbols, it calls sieve
90100
remove_symbols("12.345.678/0001-90")
91101
mock_sieve.assert_called()
102+
remove_symbols("12.ABC.345/01DE-35")
103+
mock_sieve.assert_called()
92104

93105

94106
@patch("brutils.cnpj.is_valid")
@@ -102,6 +114,13 @@ def test_when_cnpj_is_valid_returns_true_to_format(self, mock_is_valid):
102114
# Checks if function is_valid_cnpj is called
103115
mock_is_valid.assert_called_once_with("01838723000127")
104116

117+
mock_is_valid.reset_mock()
118+
# When cnpj is_valid, returns formatted cnpj
119+
self.assertEqual(format_cnpj("12ABC34501DE35"), "12.ABC.345/01DE-35")
120+
121+
# Checks if function is_valid_cnpj is called
122+
mock_is_valid.assert_called_once_with("12ABC34501DE35")
123+
105124
def test_when_cnpj_is_not_valid_returns_none(self, mock_is_valid):
106125
mock_is_valid.return_value = False
107126

0 commit comments

Comments
 (0)