class IS_CPF_OR_CNPJ(object):
def __init__(self, format=False, error_message=T('Número incorreto!')):
self.error_message = error_message
self.format = format
def __call__(self, value):
try:
cl = str(''.join(c for c in value if c.isdigit()))
if len(cl) == 11:
cpf = cl
cnpj = None
elif len(cl) == 14:
cpf = None
cnpj = cl
else:
return value, self.error_message
if cpf:
def calcdv(numb):
result = int()
seq = reversed(
((range(9, -1, -1)*2)[:len(numb)])
)
for digit, base in zip(numb, seq):
result += int(digit)*int(base)
dv = result % 11
return (dv-10) and dv or 0
numb, xdv = cpf[:-2], cpf[-2:]
dv1 = calcdv(numb)
dv2 = calcdv(numb + str(dv1))
if '%d%d' % (dv1, dv2) == xdv:
return self.doformat(cpf) if self.format else cpf, None
else:
return cpf, T('CPF inválido')
elif cnpj:
intmap = map(int, cnpj)
validate = intmap[:12]
prod = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
while len(validate) < 14:
r = sum([x*y for (x, y) in zip(validate, prod)]) % 11
f = 11 - r if r > 1 else 0
validate.append(f)
prod.insert(0, 6)
if validate == intmap:
return self.doformat(cnpj) if self.format else cnpj, None
else:
return cnpj, T('CNPJ inválido')
except:
return value, self.error_message
def doformat(self, value):
if len(value) == 11:
result = value[0:3] + '.' + value[3:6] + '.' + value[6:9] + \
'-' + value[9:11]
elif len(value) == 14:
result = value[0:2] + '.' + value[2:5] + '.' + value[5:8] + \
'/' + value[8:12] + '-' + value[12:14]
else:
result = value
return result
Simple validator.
Put the code in some model (db.py for example) and call it from requires when creating a table of form:
Field('ident', 'string', length=20, requires=IS_CPF_OR_CNPJ())
Original: http://alexandremas.blogspot.com.br/



Comments (3)
0
wellington-faria-10451 11 years ago
Salvou minha vida! haha Obrigado!
0
diogo-munaro-10988 11 years ago
parabéns pelo trabalho!!
0
fernando-vieira-10469 12 years ago
Valeu André, usei o validador e funcionou 100%