Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

- Fix validation for new alphanumeric CNPJ

## [2.21.0] - 2024-09-18

### Added
Expand Down
52 changes: 52 additions & 0 deletions react/__tests__/BRA.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import BRA from '../rules/BRA'

const getCnpjField = () =>
BRA.businessFields.find(field => field.name === 'corporateDocument')

describe('BRA corporateDocument (CNPJ)', () => {
const { mask, validate } = getCnpjField()

describe('mask', () => {
it('masks numeric CNPJ', () => {
expect(mask('11222333000181')).toBe('11.222.333/0001-81')
})

it('masks alphanumeric CNPJ', () => {
expect(mask('12ABC34501DE35')).toBe('12.ABC.345/01DE-35')
})

it('masks lowercase alphanumeric input', () => {
expect(mask('12abc34501de35')).toBe('12.abc.345/01de-35')
})
})

describe('validate', () => {
it('accepts valid numeric CNPJ', () => {
expect(validate('11.222.333/0001-81')).toBe(true)
})

it('accepts valid alphanumeric CNPJ', () => {
expect(validate('12.ABC.345/01DE-35')).toBe(true)
})

it('accepts unformatted valid CNPJ', () => {
expect(validate('11222333000181')).toBe(true)
})

it('rejects CNPJ with wrong length', () => {
expect(validate('11.222.333/0001')).toBe(false)
})

it('rejects numeric CNPJ with invalid check digits', () => {
expect(validate('11.222.333/0001-00')).toBe(false)
})

it('rejects alphanumeric CNPJ with invalid check digits', () => {
expect(validate('12.ABC.345/01DE-00')).toBe(false)
})

it('rejects repeated characters', () => {
expect(validate('00.000.000/0000-00')).toBe(false)
})
})
})
43 changes: 17 additions & 26 deletions react/rules/BRA.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,37 +91,28 @@ export default {
name: 'corporateDocument',
maxLength: 30,
label: 'BRA_cnpj',
mask: value => msk.fit(value, '99.999.999/9999-99'),
mask: value => msk.fit(value, 'SS.SSS.SSS/SSSS-99'),
validate: value => {
const cleanValue = value.replace(/[^\d]/g, '')
if (cleanValue.length != 14) return false

const isRepeatedNum = '0123456789'
.split('')
.some(digit => digit.repeat(14) === cleanValue)
if (isRepeatedNum) return false

const firstWeights = '543298765432'.split('')
const firstReduce = cleanValue
.split('')
const cleanValue = value.replace(/[.\/-]/g, '').toUpperCase()
if (cleanValue.length !== 14) return false
if (!/^[A-Z0-9]{12}\d{2}$/.test(cleanValue)) return false

if (/^(.)\1+$/.test(cleanValue)) return false

const getCharValue = char => char.charCodeAt(0) - 48
const values = cleanValue.split('').map(getCharValue)

const firstWeights = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
const firstReduce = values
.slice(0, 12)
.reduce(
(acc, cur, index) =>
acc + parseInt(cur) * parseInt(firstWeights[index]),
0,
)
.reduce((acc, cur, index) => acc + cur * firstWeights[index], 0)
const firstDigit = firstReduce % 11 < 2 ? 0 : 11 - (firstReduce % 11)
if (firstDigit != cleanValue.charAt(12)) return false

const secondWeights = ['6', ...firstWeights]
const secondReduce = cleanValue
.split('')

const secondWeights = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
Comment thread
sheilagomes marked this conversation as resolved.
Outdated
const secondReduce = values
.slice(0, 13)
.reduce(
(acc, cur, index) =>
acc + parseInt(cur) * parseInt(secondWeights[index]),
0,
)
.reduce((acc, cur, index) => acc + cur * secondWeights[index], 0)
const secondDigit = secondReduce % 11 < 2 ? 0 : 11 - (secondReduce % 11)
return secondDigit == cleanValue.charAt(13)
},
Expand Down