caelum / caelum-stella

O Caelum Stella visa suprir as necessidades do dia a dia do desenvolvedor brasileiro
http://stella.caelum.com.br
663 stars 340 forks source link

Cálculo do digito verificador Febraban #258

Closed lcallegari closed 4 years ago

lcallegari commented 4 years ago

Olá pessoal! Identifiquei uma situação com o cálculo do dígito verificador de códigos de barra, ao menos de acordo com as regras do manual da Febraban (https://portal.febraban.org.br/pagina/3166/33/pt-br/layour-arrecadacao). No manual a regra para o cálculo do mod 11 é a seguinte:

O DAC (Dígito de Auto-Conferência) módulo 11, de um número é calculado multiplicando cada algarismo, pela seqüência de multiplicadores 2,3,4,5,6,7,8,9,2,3,4.... posicionados da direita para a esquerda. A soma dos produtos dessa multiplicação é dividida por 11, obtém-se o resto da divisão, este resto deve ser subtraído de 11, o produto da subtração é o DAC. Observação: Quando o resto da divisão for igual a 0 ou 1, atribuí-se ao DV o digito “0”, e quando for 10, atribuí-se ao DV o digito “1”.

Note que na observação, que trata das condições especiais para os valores do dígito verificador, é considerado o resto da divisão, e não o resultado da subtração. Assim sendo, seria necessário fazer a validação das substituições antes do cálculo complementar.

Segue um código de barras cujo dígito verificador do último grupo foi calculado errado. 85860000000 4 20000278120 7 20012102000 5 03623607923 0

O último grupo possui DV 0 (correto), porém a rotina calcula 1, pois o resto da divisão é 1. Segundo o manual, o DV deveria ser 0 quando o resto da divisão for 1, porém o cálculo complementar ocorre antes desta validação (11 - 1) calculando 10 e fixando o DV como 1.

Não sei ao certo se há alguma alternativa para esta situação que eu não tenha encontrado na lib.

Abaixo a configuração que usei para o cálculo do DV pelas regras da Febraban

        return Integer.valueOf(new DigitoPara(codigoDeBarras)
            .comMultiplicadoresDeAte(2, 9)
            .complementarAoModulo()
            .trocandoPorSeEncontrar("0", 0, 1)
            .trocandoPorSeEncontrar("1", 10)
            .mod(11)
            .calcula());
stale[bot] commented 4 years ago

Essa Issue foi marcada automáticamente como obsoleta, devido a um longo periodo de inatividade. Se nenhuma interação ocorrer nos próximos dias, ela será encerrada. Agradecemos a sua contribuição, esse processo é apenas para manter o repositório mais organizado.