UNPKG

@mrmgomes/boleto-utils

Version:

Biblioteca com funções úteis para a validação de todos os tipos de boleto

830 lines (735 loc) 27.4 kB
/** * Identifica o tipo de código inserido (se baseando na quantidade de dígitos). * * ------------ * * @param {string} codigo Numeração do boleto * * ------------ * * @return {string} CODIGO_DE_BARRAS * @return {string} LINHA_DIGITAVEL */ exports.identificarTipoCodigo = (codigo) => { if (typeof codigo !== 'string') throw new TypeError('Insira uma string válida!'); codigo = codigo.replace(/[^0-9]/g, ''); if (codigo.length == 44) { return 'CODIGO_DE_BARRAS' } else if (codigo.length == 46 || codigo.length == 47 || codigo.length == 48) { return 'LINHA_DIGITAVEL' } else { return 'TAMANHO_INCORRETO'; } } /** * Identifica o tipo de boleto inserido a partir da validação de seus dois dígitos iniciais. * * ------------- * * @param {string} codigo Numeração do boleto * * ------------- * * @return {string} BANCO * @return {string} ARRECADACAO_PREFEITURA * @return {string} ARRECADACAO_ORGAOS_GOVERNAMENTAIS * @return {string} ARRECADACAO_TAXAS_DE_TRANSITO * @return {string} CONVENIO_SANEAMENTO * @return {string} CONVENIO_ENERGIA_ELETRICA_E_GAS * @return {string} CONVENIO_TELECOMUNICACOES * @return {string} OUTROS * @return {string} CARTAO_DE_CREDITO */ exports.identificarTipoBoleto = (codigo) => { codigo = codigo.replace(/[^0-9]/g, ''); if (typeof codigo !== 'string') throw new TypeError('Insira uma string válida!'); if (codigo.substr(-14) == '00000000000000' || codigo.substr(5, 14) == '00000000000000') { return 'CARTAO_DE_CREDITO'; } else if (codigo.substr(0, 1) == '8') { if (codigo.substr(1, 1) == '1') { return 'ARRECADACAO_PREFEITURA'; } else if (codigo.substr(1, 1) == '2') { return 'CONVENIO_SANEAMENTO'; } else if (codigo.substr(1, 1) == '3') { return 'CONVENIO_ENERGIA_ELETRICA_E_GAS'; } else if (codigo.substr(1, 1) == '4') { return 'CONVENIO_TELECOMUNICACOES'; } else if (codigo.substr(1, 1) == '5') { return 'ARRECADACAO_ORGAOS_GOVERNAMENTAIS'; } else if (codigo.substr(1, 1) == '6' || codigo.substr(1, 1) == '9') { return 'OUTROS'; } else if (codigo.substr(1, 1) == '7') { return 'ARRECADACAO_TAXAS_DE_TRANSITO'; } } else { return 'BANCO'; } } /** * Identifica o o código de referência do boleto para determinar qual módulo * será utilizado para calcular os dígitos verificadores * * ------------- * * @param {string} codigo Numeração do boleto * * ------------- * * @return {json} {mod, efetivo} */ exports.identificarReferencia = (codigo) => { codigo = codigo.replace(/[^0-9]/g, ''); const referencia = codigo.substr(2, 1); if (typeof codigo !== 'string') throw new TypeError('Insira uma string válida!'); switch (referencia) { case '6': return { mod: 10, efetivo: true }; break; case '7': return { mod: 10, efetivo: false }; break; case '8': return { mod: 11, efetivo: true }; break; case '9': return { mod: 11, efetivo: false }; break; default: break; } } /** * Identifica e retorna o fator data do boleto * * ------------- * * @param {string} codigo Numeração do boleto * @param {string} tipoCodigo tipo de código inserido (CODIGO_DE_BARRAS / LINHA_DIGITAVEL) * * ------------- * * @return {number} fatorData */ exports.obtemFatorData = ({ codigo, tipoCodigo }) => { codigo = codigo.replace(/[^0-9]/g, ''); const tipoBoleto = this.identificarTipoBoleto(codigo); let fatorData = '' if (tipoCodigo === 'CODIGO_DE_BARRAS') { if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { fatorData = codigo.substr(5, 4) } else { fatorData = '0'; } } else if (tipoCodigo === 'LINHA_DIGITAVEL') { if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { fatorData = codigo.substr(33, 4) } else { fatorData = '0'; } } return fatorData } /** * Identifica a data de vencimento do boleto * * ------------- * * @param {string} codigo Numeração do boleto * @param {string} tipoCodigo tipo de código inserido (CODIGO_DE_BARRAS / LINHA_DIGITAVEL) * * ------------- * * @return {Date} dataBoleto */ exports.identificarData = (codigo, tipoCodigo) => { var moment = require('moment-timezone'); let dataBoleto = moment.tz("1997-10-07 20:54:59.000Z", "UTC"); const fatorData = this.obtemFatorData({ codigo, tipoCodigo }) dataBoleto.add(Number(fatorData), 'days'); return dataBoleto.toDate(); } /** * Identifica a data de vencimento do boleto após 22/05/2025 * O novo fator já tem seu início em 1000, logo fator 1000 representa 22/05/2025 * * ------------- * * @param {string} codigo Numeração do boleto * @param {string} tipoCodigo tipo de código inserido (CODIGO_DE_BARRAS / LINHA_DIGITAVEL) * * ------------- * * @return {Date} dataBoleto */ exports.identificarDataComNovoFator2025 = (codigo, tipoCodigo) => { var moment = require('moment-timezone'); let fatorData = this.obtemFatorData({ codigo, tipoCodigo }); let dataBoleto = moment.tz("2025-02-22 20:54:59.000Z", "UTC"); dataBoleto.add(Number(fatorData) - 1000, 'days'); return dataBoleto.toDate(); } /** * Identifica o valor no CÓDIGO DE BARRAS do boleto do tipo 'Arrecadação' * * ------------- * * @param {string} codigo Numeração do boleto * @param {string} tipoCodigo tipo de código inserido (CODIGO_DE_BARRAS / LINHA_DIGITAVEL) * * ------------- * * @return {string} valorFinal */ exports.identificarValorCodBarrasArrecadacao = (codigo, tipoCodigo) => { codigo = codigo.replace(/[^0-9]/g, ''); const isValorEfetivo = this.identificarReferencia(codigo).efetivo; let valorBoleto = ''; let valorFinal; if (isValorEfetivo) { if (tipoCodigo == 'LINHA_DIGITAVEL') { valorBoleto = codigo.substr(4, 14); valorBoleto = codigo.split(''); valorBoleto.splice(11, 1); valorBoleto = valorBoleto.join(''); valorBoleto = valorBoleto.substr(4, 11); } else if (tipoCodigo == 'CODIGO_DE_BARRAS') { valorBoleto = codigo.substr(4, 11); } valorFinal = valorBoleto.substr(0, 9) + '.' + valorBoleto.substr(9, 2); let char = valorFinal.substr(1, 1); while (char === '0') { valorFinal = substringReplace(valorFinal, '', 0, 1); char = valorFinal.substr(1, 1); } } else { valorFinal = 0; } return valorFinal; } /** * Identifica o valor no boleto inserido * * ------------- * * @param {string} codigo Numeração do boleto * @param {string} tipoCodigo tipo de código inserido (CODIGO_DE_BARRAS / LINHA_DIGITAVEL) * * ------------- * * @return {float} valorFinal */ exports.identificarValor = (codigo, tipoCodigo) => { const tipoBoleto = this.identificarTipoBoleto(codigo); let valorBoleto = ''; let valorFinal; if (tipoCodigo == 'CODIGO_DE_BARRAS') { if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { valorBoleto = codigo.substr(9, 10); valorFinal = valorBoleto.substr(0, 8) + '.' + valorBoleto.substr(8, 2); let char = valorFinal.substr(1, 1); while (char === '0') { valorFinal = substringReplace(valorFinal, '', 0, 1); char = valorFinal.substr(1, 1); } } else { valorFinal = this.identificarValorCodBarrasArrecadacao(codigo, 'CODIGO_DE_BARRAS'); } } else if (tipoCodigo == 'LINHA_DIGITAVEL') { if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { valorBoleto = codigo.substr(37); valorFinal = valorBoleto.substr(0, 8) + '.' + valorBoleto.substr(8, 2); let char = valorFinal.substr(1, 1); while (char === '0') { valorFinal = substringReplace(valorFinal, '', 0, 1); char = valorFinal.substr(1, 1); } } else { valorFinal = this.identificarValorCodBarrasArrecadacao(codigo, 'LINHA_DIGITAVEL'); } } return parseFloat(valorFinal); } /** * Define qual módulo deverá ser utilizado para calcular os dígitos verificadores * * ------------- * * @param {string} codigo Numeração do boleto * @param {int} mod Modulo 10 ou Modulo 11 * * ------------- * * @return {string} digitoVerificador */ exports.digitosVerificadores = (codigo, mod) => { codigo = codigo.replace(/[^0-9]/g, ''); switch (mod) { case 10: return (codigo + this.calculaMod10(codigo)).toString(); break; case 11: return (codigo + this.calculaMod11(codigo)).toString(); break; default: break; } } /** * Converte a numeração do código de barras em linha digitável * * ------------- * * @param {string} codigo Numeração do boleto * @param {boolean} formatada Gerar numeração convertida com formatação (formatado = true / somente números = false) * * ------------- * * @return {string} resultado */ exports.codBarras2LinhaDigitavel = (codigo, formatada) => { codigo = codigo.replace(/[^0-9]/g, ''); const tipoBoleto = this.identificarTipoBoleto(codigo); let resultado = ''; if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { const novaLinha = codigo.substr(0, 4) + codigo.substr(19, 25) + codigo.substr(4, 1) + codigo.substr(5, 14); const bloco1 = novaLinha.substr(0, 9) + this.calculaMod10(novaLinha.substr(0, 9)); const bloco2 = novaLinha.substr(9, 10) + this.calculaMod10(novaLinha.substr(9, 10)); const bloco3 = novaLinha.substr(19, 10) + this.calculaMod10(novaLinha.substr(19, 10)); const bloco4 = novaLinha.substr(29); resultado = (bloco1 + bloco2 + bloco3 + bloco4).toString(); if (formatada) { resultado = resultado.slice(0, 5) + '.' + resultado.slice(5, 10) + ' ' + resultado.slice(10, 15) + '.' + resultado.slice(15, 21) + ' ' + resultado.slice(21, 26) + '.' + resultado.slice(26, 32) + ' ' + resultado.slice(32, 33) + ' ' + resultado.slice(33); } } else { const identificacaoValorRealOuReferencia = this.identificarReferencia(codigo); let bloco1; let bloco2; let bloco3; let bloco4; if (identificacaoValorRealOuReferencia.mod == 10) { bloco1 = codigo.substr(0, 11) + this.calculaMod10(codigo.substr(0, 11)); bloco2 = codigo.substr(11, 11) + this.calculaMod10(codigo.substr(11, 11)); bloco3 = codigo.substr(22, 11) + this.calculaMod10(codigo.substr(22, 11)); bloco4 = codigo.substr(33, 11) + this.calculaMod10(codigo.substr(33, 11)); } else if (identificacaoValorRealOuReferencia.mod == 11) { bloco1 = codigo.substr(0, 11) + this.calculaMod11(codigo.substr(0, 11)); bloco2 = codigo.substr(11, 11) + this.calculaMod11(codigo.substr(11, 11)); bloco3 = codigo.substr(22, 11) + this.calculaMod11(codigo.substr(22, 11)); bloco4 = codigo.substr(33, 11) + this.calculaMod11(codigo.substr(33, 11)); } resultado = bloco1 + bloco2 + bloco3 + bloco4; } return resultado; } /** * Converte a numeração da linha digitável em código de barras * * ------------- * * @param {string} codigo Numeração do boleto * * ------------- * * @return {string} resultado */ exports.linhaDigitavel2CodBarras = (codigo) => { codigo = codigo.replace(/[^0-9]/g, ''); const tipoBoleto = this.identificarTipoBoleto(codigo); let resultado = ''; if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { resultado = codigo.substr(0, 4) + codigo.substr(32, 1) + codigo.substr(33, 14) + codigo.substr(4, 5) + codigo.substr(10, 10) + codigo.substr(21, 10); } else { codigo = codigo.split(''); codigo.splice(11, 1); codigo.splice(22, 1); codigo.splice(33, 1); codigo.splice(44, 1); codigo = codigo.join(''); resultado = codigo; } return resultado; } /** * Calcula o dígito verificador de toda a numeração do código de barras * * ------------- * * @param {string} codigo Numeração do boleto * @param {int} posicaoCodigo Posição onde deve se encontrar o dígito verificador * @param {int} mod Módulo 10 ou Módulo 11 * * ------------- * * @return {string} numero */ exports.calculaDVCodBarras = (codigo, posicaoCodigo, mod) => { codigo = codigo.replace(/[^0-9]/g, ''); codigo = codigo.split(''); codigo.splice(posicaoCodigo, 1); codigo = codigo.join(''); if (mod === 10) { return this.calculaMod10(codigo); } else if (mod === 11) { return this.calculaMod11(codigo); } } /** * Informa se o código de barras inserido é válido, calculando seu dígito verificador. * * ------------- * * @param {string} codigo Numeração do boleto * * ------------- * * @return {boolean} true = boleto válido / false = boleto inválido */ exports.validarCodigoComDV = (codigo, tipoCodigo) => { codigo = codigo.replace(/[^0-9]/g, ''); let tipoBoleto; let resultado; if (tipoCodigo === 'LINHA_DIGITAVEL') { tipoBoleto = this.identificarTipoBoleto(codigo, 'LINHA_DIGITAVEL'); if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { const bloco1 = codigo.substr(0, 9) + this.calculaMod10(codigo.substr(0, 9)); const bloco2 = codigo.substr(10, 10) + this.calculaMod10(codigo.substr(10, 10)); const bloco3 = codigo.substr(21, 10) + this.calculaMod10(codigo.substr(21, 10)); const bloco4 = codigo.substr(32, 1); const bloco5 = codigo.substr(33); resultado = (bloco1 + bloco2 + bloco3 + bloco4 + bloco5).toString(); } else { const identificacaoValorRealOuReferencia = this.identificarReferencia(codigo); let bloco1; let bloco2; let bloco3; let bloco4; if (identificacaoValorRealOuReferencia.mod == 10) { bloco1 = codigo.substr(0, 11) + this.calculaMod10(codigo.substr(0, 11)); bloco2 = codigo.substr(12, 11) + this.calculaMod10(codigo.substr(12, 11)); bloco3 = codigo.substr(24, 11) + this.calculaMod10(codigo.substr(24, 11)); bloco4 = codigo.substr(36, 11) + this.calculaMod10(codigo.substr(36, 11)); } else if (identificacaoValorRealOuReferencia.mod == 11) { bloco1 = codigo.substr(0, 11); bloco2 = codigo.substr(12, 11); bloco3 = codigo.substr(24, 11); bloco4 = codigo.substr(36, 11); let dv1 = parseInt(codigo.substr(11, 1)); let dv2 = parseInt(codigo.substr(23, 1)); let dv3 = parseInt(codigo.substr(35, 1)); let dv4 = parseInt(codigo.substr(47, 1)); //console.log(dv1) //console.log(this.calculaMod11(bloco1)) //console.log(dv2) //console.log(this.calculaMod11(bloco2)) //console.log(dv3) //console.log(this.calculaMod11(bloco3)) //console.log(dv4) //console.log(this.calculaMod11(bloco4)) let valid = (this.calculaMod11(bloco1) == dv1 && this.calculaMod11(bloco2) == dv2 && this.calculaMod11(bloco3) == dv3 && this.calculaMod11(bloco4) == dv4) return valid; } resultado = bloco1 + bloco2 + bloco3 + bloco4; } } else if (tipoCodigo === 'CODIGO_DE_BARRAS') { tipoBoleto = this.identificarTipoBoleto(codigo); if (tipoBoleto == 'BANCO' || tipoBoleto == 'CARTAO_DE_CREDITO') { const DV = this.calculaDVCodBarras(codigo, 4, 11); resultado = codigo.substr(0, 4) + DV + codigo.substr(5); } else { const identificacaoValorRealOuReferencia = this.identificarReferencia(codigo); resultado = codigo.split(''); resultado.splice(3, 1); resultado = resultado.join(''); const DV = this.calculaDVCodBarras(codigo, 3, identificacaoValorRealOuReferencia.mod); resultado = resultado.substr(0, 3) + DV + resultado.substr(3); } } return codigo === resultado; } /** * Gerar código de barras já realizando o cálculo do dígito verificador * * ------------- * * @param {string} novoCodigo Numeração do boleto * * ------------- * * @return {string} numero */ exports.geraCodBarras = (codigo) => { codigo = codigo.replace(/[^0-9]/g, ''); const tipoBoleto = this.identificarTipoBoleto(codigo); let novoCodigo; novoCodigo = this.linhaDigitavel2CodBarras(codigo); novoCodigo = novoCodigo.split(''); novoCodigo.splice(4, 1); novoCodigo = novoCodigo.join(''); let dv = this.calculaMod11(novoCodigo); novoCodigo = novoCodigo.substr(0, 4) + dv + novoCodigo.substr(4); return novoCodigo; } /** * ## __`BOLETO COBRANÇA`__ * ### __AS POSIÇÕES AQUI MENCIONADAS PARTEM DO NÚMERO 0 E NÃO DO 1, A FIM DE FACILITAR O ENTENDIMENTO LÓGICO__ * --------------------------------------------------------- * * ### __TIPO:__ CÓDIGO DE BARRAS (44 POSIÇÕES NUMÉRICAS) * * --------------------------------------------------------- * * #### __EXEMPLO:__ 11123444455555555556666666666666666666666666 * * Bloco | Posições | Definição * --- | --- | --- * __1__ | **0 a 2** | `Código do Banco na Câmara de Compensação` * __2__ | **3 a 3** | `Código da Moeda = 9 (Real)` * __3__ | **4 a 4** | `Digito Verificador (DV) do código de Barras` * __4__ | **5 a 8** | `Fator de Vencimento` * __5__ | **9 a 18** | `Valor com 2 casas de centavos` * __6__ | **19 a 43** | `Campo Livre (De uso da instituição bancária)` * * --------------------------------------------------------- * * ### __TIPO:__ LINHA DIGITÁVEL (47 POSIÇÕES NUMÉRICAS) * * --------------------------------------------------------- * * #### __EXEMPLO__: AAABC.CCCCX DDDDD.DDDDDY EEEEE.EEEEEZ K UUUUVVVVVVVVVV * * Campo | Posições linha dig. | Definição * --- | --- | --- * __A__ | **0 a 2** (0 a 2 do cód. barras) | `Código do Banco na Câmara de compensação` * __B__ | **3 a 3** (3 a 3 do cód. barras) | `Código da moeda` * __C__ | **4 a 8** (19 a 23 do cód. barras) | `Campo Livre` * __X__ | **9 a 9** | `Dígito verificador do Bloco 1 (Módulo 10)` * __D__ | **10 a 19** (24 a 33 do cód. barras) | `Campo Livre` * __Y__ | **20 a 20** | `Dígito verificador do Bloco 2 (Módulo 10)` * __E__ | **21 a 30** (24 a 43 do cód. barras) | `Campo Livre` * __Z__ | **31 a 31** | `Dígito verificador do Bloco 3 (Módulo 10)` * __K__ | **32 a 32** (4 a 4 do cód. barras) | `Dígito verificador do código de barras` * __U__ | **33 a 36** (5 a 8 do cód. barras) | `Fator de Vencimento` * __V__ | **37 a 43** (9 a 18 do cód. barras) | `Valor` * * ## __`CONTA CONVÊNIO / ARRECADAÇÃO`__ * * --------------------------------------------------------- * * ### __TIPO:__ CÓDIGO DE BARRAS (44 POSIÇÕES NUMÉRICAS) * * --------------------------------------------------------- * * #### __EXEMPLO__: 12345555555555566667777777777777777777777777 * * Campo | Posições | Definição * --- | --- | --- * __1__ | **0 a 0** | `"8" Identificação da Arrecadação/convênio` * __2__ | **1 a 1** | `Identificação do segmento` * __3__ | **2 a 2** | `Identificação do valor real ou referência` * __4__ | **3 a 3** | `Dígito verificador geral (módulo 10 ou 11)` * __5__ | **4 a 14** | `Valor efetivo ou valor referência` * __6__ | **15 a 18** | `Identificação da empresa/órgão` * __7__ | **19 a 43** | `Campo livre de utilização da empresa/órgão` * * --------------------------------------------------------- * * ### __TIPO:__ LINHA DIGITÁVEL (48 POSIÇÕES NUMÉRICAS) * * --------------------------------------------------------- * * #### __EXEMPLO__: ABCDEEEEEEE-W EEEEFFFFGGG-X GGGGGGGGGGG-Y GGGGGGGGGGG-Z * * Campo | Posições | Definição * --- | --- | --- * __A__ | **0 a 0** | `"8" Identificação da Arrecadação/convênio` * __B__ | **1 a 1** | `Identificação do segmento` * __C__ | **2 a 2** | `Identificação do valor real ou referência` * __D__ | **3 a 3** | `Dígito verificador geral (módulo 10 ou 11)` * __E__ | **4 a 14** | `Valor efetivo ou valor referência` * __W__ | **11 a 11** | `Dígito verificador do Bloco 1` * __F__ | **15 a 18** | `Identificação da empresa/órgão` * __G__ | **19 a 43** | `Campo livre de utilização da empresa/órgão` * __X__ | **23 a 23** | `Dígito verificador do Bloco 2` * __Y__ | **35 a 35** | `Dígito verificador do Bloco 3` * __Z__ | **47 a 47** | `Dígito verificador do Bloco 4` */ exports.validarBoleto = (codigo) => { let tipoCodigo = this.identificarTipoCodigo(codigo); let retorno = {}; codigo = codigo.replace(/[^0-9]/g, ''); /** * Boletos de cartão de crédito geralmente possuem 46 dígitos. É necessário adicionar mais um zero no final, para formar 47 caracteres * Alguns boletos de cartão de crédito do Itaú possuem 36 dígitos. É necessário acrescentar 11 zeros no final. */ if (codigo.length == 36) { codigo = codigo + '00000000000'; } else if (codigo.length == 46) { codigo = codigo + '0'; } if (codigo.length != 44 && codigo.length != 46 && codigo.length != 47 && codigo.length != 48) { retorno.sucesso = false; retorno.codigoInput = codigo; retorno.mensagem = 'O código inserido possui ' + codigo.length + ' dígitos. Por favor insira uma numeração válida. Códigos de barras SEMPRE devem ter 44 caracteres numéricos. Linhas digitáveis podem possuir 46 (boletos de cartão de crédito), 47 (boletos bancários/cobrança) ou 48 (contas convênio/arrecadação) caracteres numéricos. Qualquer caractere não numérico será desconsiderado.'; } else if (codigo.substr(0, 1) == '8' && codigo.length == 46 && codigo.length == 47) { retorno.sucesso = false; retorno.codigoInput = codigo; retorno.mensagem = 'Este tipo de boleto deve possuir um código de barras 44 caracteres numéricos. Ou linha digitável de 48 caracteres numéricos.'; } else if (!this.validarCodigoComDV(codigo, tipoCodigo)) { retorno.sucesso = false; retorno.codigoInput = codigo; retorno.mensagem = 'A validação do dígito verificador falhou. Tem certeza que inseriu a numeração correta?'; } else { retorno.sucesso = true; retorno.codigoInput = codigo; retorno.mensagem = 'Boleto válido'; switch (tipoCodigo) { case 'LINHA_DIGITAVEL': retorno.tipoCodigoInput = 'LINHA_DIGITAVEL'; retorno.tipoBoleto = this.identificarTipoBoleto(codigo, 'LINHA_DIGITAVEL'); retorno.codigoBarras = this.linhaDigitavel2CodBarras(codigo); retorno.linhaDigitavel = codigo; retorno.vencimento = this.identificarData(codigo, 'LINHA_DIGITAVEL'); retorno.vencimentoComNovoFator2025 = this.identificarDataComNovoFator2025(codigo, 'LINHA_DIGITAVEL'); retorno.valor = this.identificarValor(codigo, 'LINHA_DIGITAVEL'); break; case 'CODIGO_DE_BARRAS': retorno.tipoCodigoInput = 'CODIGO_DE_BARRAS'; retorno.tipoBoleto = this.identificarTipoBoleto(codigo, 'CODIGO_DE_BARRAS'); retorno.codigoBarras = codigo; retorno.linhaDigitavel = this.codBarras2LinhaDigitavel(codigo, false); retorno.vencimento = this.identificarData(codigo, 'CODIGO_DE_BARRAS'); retorno.vencimentoComNovoFator2025 = this.identificarDataComNovoFator2025(codigo, 'CODIGO_DE_BARRAS'); retorno.valor = this.identificarValor(codigo, 'CODIGO_DE_BARRAS'); break; default: break; } } return retorno; } /** * Calcula o dígito verificador de uma numeração a partir do módulo 10 * * ------------- * * @param {string} numero Numeração * * ------------- * * @return {string} soma */ exports.calculaMod10 = (numero) => { numero = numero.replace(/\D/g, ''); var i; var mult = 2; var soma = 0; var s = ''; for (i = numero.length - 1; i >= 0; i--) { s = (mult * parseInt(numero.charAt(i))) + s; if (--mult < 1) { mult = 2; } } for (i = 0; i < s.length; i++) { soma = soma + parseInt(s.charAt(i)); } soma = soma % 10; if (soma != 0) { soma = 10 - soma; } return soma; } /** * Calcula o dígito verificador de uma numeração a partir do módulo 11 * * ------------- * * @param {string} x Numeração * * ------------- * * @return {string} digito */ exports.calculaMod11 = (x) => { let sequencia = [4, 3, 2, 9, 8, 7, 6, 5]; let digit = 0; let j = 0; let DAC = 0; //FEBRABAN https://cmsportal.febraban.org.br/Arquivos/documentos/PDF/Layout%20-%20C%C3%B3digo%20de%20Barras%20-%20Vers%C3%A3o%205%20-%2001_08_2016.pdf for (var i = 0; i < x.length; i++) { let mult = sequencia[j]; j++; j %= sequencia.length; digit += mult * parseInt(x.charAt(i)); } DAC = digit % 11; if (DAC == 0 || DAC == 1) return 0; if (DAC == 10) return 1; return (11 - DAC); } /** * Função auxiliar para remover os zeros à esquerda dos valores detectados no código inserido * * ------------- * * @param {string} str Texto a ser verificado * @param {string} repl Texto que substituirá * @param {int} inicio Posição inicial * @param {int} tamanho Tamanho * * ------------- * * @return {string} resultado */ function substringReplace(str, repl, inicio, tamanho) { if (inicio < 0) { inicio = inicio + str.length; } tamanho = tamanho !== undefined ? tamanho : str.length; if (tamanho < 0) { tamanho = tamanho + str.length - inicio; } return [ str.slice(0, inicio), repl.substr(0, tamanho), repl.slice(tamanho), str.slice(inicio + tamanho) ].join(''); }