Validador genérico
authorEduardo Elias Camponez <camponez@gmail.com>
Mon, 8 Jul 2013 10:55:16 +0000 (07:55 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Fri, 12 Jul 2013 11:06:25 +0000 (08:06 -0300)
Validador genérico para:
- CPF
- CNPJ
- Recibo IRPF

[cascardo]: Não permite valores com número de dígitos diferente de 11

src/contribuinte.py

index 80c17c0..a9e055b 100644 (file)
@@ -68,31 +68,48 @@ class Contribuinte:
 
     # CPF minimizado se parece com 01234567890
     def _minimize_cpf(self, cpf):
-        ncpf = bytearray(self._normalize_cpf(cpf))
-        del ncpf[11]
-        del ncpf[7]
-        del ncpf[3]
-        return str(ncpf)
+        return self._minimize_valor(cpf)
+
+    def _minimize_valor(self, valor):
+        nvalor = ''.join(e for e in valor if e.isalnum())
+        return str(nvalor)
 
     def _validate_cpf(self, cpf):
-        ncpf = self._minimize_cpf(cpf)
-        if len(ncpf) != 11:
-            return False
-        v = (11 - sum(map(lambda x: x[0]*x[1], zip(range(10, 1, -1), map(lambda x: ord(x) - ord('0'), ncpf[0:9]))))) % 11
-        if v >= 10:
-            v = 0
-        if v != ord(ncpf[9]) - ord('0'):
-            return False
-        v = (11 - sum(map(lambda x: x[0]*x[1], zip(range(11, 1, -1), map(lambda x: ord(x) - ord('0'), ncpf[0:10]))))) % 11
-        if v >= 10:
-            v = 0
-        if v != ord(ncpf[10]) - ord('0'):
+        if len(cpf) != 11:
             return False
-        return True
+        return self._validate_generico(cpf)
+
+    def _validate_generico(self, valor):
+        def calcula_digito_verificador(numero):
+            n = len(numero) + 1
+
+            soma = 0
+            for i in range(n):
+                if i > len(numero) - 1:
+                    break
+                soma = soma + int(numero[i]) * ( n - i)
+
+            dv =  soma % 11
+
+            if dv < 2:
+                dv = 0
+            else:
+                dv = 11 - dv
+
+            return numero + str(dv)
+
+        mcpf = self._minimize_valor(valor)
+        cpf_sem_dv = mcpf[:-2]
+
+        primeiro_dv = str(calcula_digito_verificador(cpf_sem_dv))
+        segundo_dv = calcula_digito_verificador(primeiro_dv)
+
+        return segundo_dv == mcpf
 
     def save(self):
         self.dados.writexml(open(self.cpf_file, "w"))
         self.declaracoes.writexml(open(self.iddecl_file, "w"))
+
     def _get_attr(self, el, attr):
         if attr in el.attributes.keys():
             return el.attributes[attr].nodeValue