Minha primeira pergunta: como calculo o dígito verificador? Descobri, por contato telefônico, que é pelo módulo 11.
Desta forma, encontrei uma referência no Wikipedia. Porém, ao calcular, não batia (eu possuo poupança na CEF e serviu para testes...).
Após mais alguns passos no Google, achei uma referência interessante (role direto para a página 3). É necessário considerar, também, a agência e operação de conta!
Agora, com o algoritmo claramente definido, implementei a função em PostgreSQL (pl/pgsql), que ficou assim (a formatação foi perdida quando colei... mais tarde tento aprender a fazer isto):
CREATE OR REPLACE FUNCTION calculaDigitoCaixa(_dados varchar) RETURNS int2 AS $$
DECLARE
 i integer;
   peso integer;
   base integer;
   total integer;
   resto integer;
   dados varchar;
BEGIN
   -- Verificar a consistência dos dados!
   dados := COALESCE(_dados, '');
   IF (LENGTH(COALESCE(_dados, '')) != 15) THEN
       RAISE WARNING 'Dados não contém um tamanho válido! Tamanho: % Nulo: % Entrada: %', LENGTH(dados), _dados IS NULL, dados;
   END IF;
   peso := null;
   total := 0;
   -- Iniciar cálculo...
   FOR i IN REVERSE LENGTH(dados)..1 LOOP
       -- Qual peso?
       IF (COALESCE(peso, 10) >= 9) THEN
           peso := 2;
       ELSE
           peso := peso + 1;END IF;
       -- Qual base?
       base := SUBSTR(dados, i, 1)::int;
 
       RAISE NOTICE 'Peso % * Base %', peso, base;
       -- multiplica base * peso e acumula total
       total := total + base * peso;
   END LOOP;
   RAISE NOTICE 'Total: %', total;
   -- Multiplicar total por 10
   total := total * 10;
   -- O resultado então é o resto da divisão por 11. Caso seja 10, então é 0.
   resto := total % 11;
   RAISE NOTICE 'Resto: %', resto;
   IF (resto = 10) THEN
       resto := 0;
   END IF;
   RETURN resto;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
Coloquei a mesma IMMUTABLE, pois sempre haverá o mesmo retorno para uma mesma entrada (documentação)...
Agora basta validar, por exemplo:
SELECT calculaDigitoCaixa(agencia, operacao_conta, conta) FROM fornecedor ...
Um comentário:
Obrigado pelas infos! Estou procurando algo para todos os bancos.
Abs
Postar um comentário