Django

Code

Changeset 5089

Show
Ignore:
Timestamp:
04/26/07 08:11:07 (1 year ago)
Author:
mtredinnick
Message:

Fixed #3957, #3945 -- Added CPF and CNPJ (some Brazilian identity numbers)
fields to the Brazilian localflavor. Thanks, onaiort@gmail.com and
danielvaz@gmail.com.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r5087 r5089  
    169169    Neal Norwitz <nnorwitz@google.com> 
    170170    oggie rob <oz.robharvey@gmail.com> 
     171    onaiort@gmail.com 
    171172    Jay Parlar <parlar@gmail.com> 
    172173    pavithran s <pavithran.s@gmail.com> 
  • django/trunk/django/contrib/localflavor/br/forms.py

    r4918 r5089  
    55 
    66from django.newforms import ValidationError 
    7 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES 
     7from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES 
    88from django.utils.encoding import smart_unicode 
    99from django.utils.translation import gettext 
     
    1616        super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$', 
    1717            max_length=None, min_length=None, 
    18             error_message=gettext(u'Enter a zip code in the format XXXXX-XXX.'), 
     18            error_message=gettext('Enter a zip code in the format XXXXX-XXX.'), 
    1919            *args, **kwargs) 
    2020 
     
    3838        from br_states import STATE_CHOICES # relative import 
    3939        super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES) 
     40 
     41 
     42def DV_maker(v): 
     43    if v >= 2: 
     44        return 11 - v 
     45    return 0 
     46 
     47class BRCPFField(CharField): 
     48    """ 
     49    This field validate a CPF number or a CPF string. A CPF number is 
     50    compounded by XXX.XXX.XXX-VD, the two last digits are check digits. 
     51 
     52    More information: 
     53    http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas 
     54    """ 
     55    def __init__(self, *args, **kwargs): 
     56        super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs) 
     57 
     58    def clean(self, value): 
     59        """ 
     60        Value can be either a string in the format XXX.XXX.XXX-XX or an 
     61        11-digit number. 
     62        """ 
     63        value = super(BRCPFField, self).clean(value) 
     64        if value in EMPTY_VALUES: 
     65            return u'' 
     66        orig_value = value[:] 
     67        if not value.isdigit(): 
     68            value = re.sub("[-\.]", "", value) 
     69        try: 
     70            int(value) 
     71        except ValueError: 
     72            raise ValidationError(gettext("This field requires only numbers")) 
     73        if len(value) != 11: 
     74            raise ValidationError(gettext("This field requires at most 11 digits or 14 characters.")) 
     75        orig_dv = value[-2:] 
     76 
     77        new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))]) 
     78        new_1dv = DV_maker(new_1dv % 11) 
     79        value = value[:-2] + str(new_1dv) + value[-1] 
     80        new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(11, 1, -1))]) 
     81        new_2dv = DV_maker(new_2dv % 11) 
     82        value = value[:-1] + str(new_2dv) 
     83        if value[-2:] != orig_dv: 
     84            raise ValidationError(gettext("Invalid CPF number.")) 
     85 
     86        return orig_value 
     87 
     88class BRCNPJField(Field): 
     89    def clean(self, value): 
     90        """ 
     91        Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a 
     92        group of 14 characters. 
     93        """ 
     94        value = super(BRCNPJField, self).clean(value) 
     95        if value in EMPTY_VALUES: 
     96            return u'' 
     97        orig_value = value[:] 
     98        if not value.isdigit(): 
     99            value = re.sub("[-/\.]", "", value) 
     100        try: 
     101            int(value) 
     102        except ValueError: 
     103            raise ValidationError("This field requires only numbers") 
     104        if len(value) != 14: 
     105            raise ValidationError( 
     106                gettext("This field requires at least 14 digits")) 
     107        orig_dv = value[-2:] 
     108 
     109        new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))]) 
     110        new_1dv = DV_maker(new_1dv % 11) 
     111        value = value[:-2] + str(new_1dv) + value[-1] 
     112        new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))]) 
     113        new_2dv = DV_maker(new_2dv % 11) 
     114        value = value[:-1] + str(new_2dv) 
     115        if value[-2:] != orig_dv: 
     116            raise ValidationError(gettext("Invalid CNPJ number")) 
     117 
     118        return orig_value 
     119 
  • django/trunk/tests/regressiontests/forms/localflavor.py

    r5087 r5089  
    841841u'12345-123' 
    842842 
     843# BRCNPJField ############################################################ 
     844 
     845>>> from django.contrib.localflavor.br.forms import BRCNPJField 
     846>>> f = BRCNPJField(required=True) 
     847>>> f.clean('') 
     848Traceback (most recent call last): 
     849... 
     850ValidationError: [u'This field is required.'] 
     851>>> f.clean('12-345-678/9012-10') 
     852Traceback (most recent call last): 
     853... 
     854ValidationError: [u'Invalid CNPJ number'] 
     855>>> f.clean('12.345.678/9012-10') 
     856Traceback (most recent call last): 
     857... 
     858ValidationError: [u'Invalid CNPJ number'] 
     859>>> f.clean('12345678/9012-10') 
     860Traceback (most recent call last): 
     861... 
     862ValidationError: [u'Invalid CNPJ number'] 
     863>>> f.clean('64.132.916/0001-88') 
     864'64.132.916/0001-88' 
     865>>> f.clean('64-132-916/0001-88') 
     866'64-132-916/0001-88' 
     867>>> f.clean('64132916/0001-88') 
     868'64132916/0001-88' 
     869>>> f.clean('64.132.916/0001-XX') 
     870Traceback (most recent call last): 
     871... 
     872ValidationError: [u'This field requires only numbers'] 
     873>>> f = BRCNPJField(required=False) 
     874>>> f.clean('') 
     875u'' 
     876 
    843877# BRPhoneNumberField ######################################################### 
    844878