app/django/contrib/localflavor/es/forms.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     1 # -*- coding: utf-8 -*-
     1 # -*- coding: utf-8 -*-
     2 """
     2 """
     3 Spanish-specific Form helpers
     3 Spanish-specific Form helpers
     4 """
     4 """
     5 
     5 
     6 from django.newforms import ValidationError
     6 from django.forms import ValidationError
     7 from django.newforms.fields import RegexField, Select, EMPTY_VALUES
     7 from django.forms.fields import RegexField, Select, EMPTY_VALUES
     8 from django.utils.translation import ugettext as _
     8 from django.utils.translation import ugettext_lazy as _
     9 import re
     9 import re
    10 
    10 
    11 class ESPostalCodeField(RegexField):
    11 class ESPostalCodeField(RegexField):
    12     """
    12     """
    13     A form field that validates its input as a spanish postal code.
    13     A form field that validates its input as a spanish postal code.
    74         self.only_nif = only_nif
    74         self.only_nif = only_nif
    75         self.nif_control = 'TRWAGMYFPDXBNJZSQVHLCKE'
    75         self.nif_control = 'TRWAGMYFPDXBNJZSQVHLCKE'
    76         self.cif_control = 'JABCDEFGHI'
    76         self.cif_control = 'JABCDEFGHI'
    77         self.cif_types = 'ABCDEFGHKLMNPQS'
    77         self.cif_types = 'ABCDEFGHKLMNPQS'
    78         self.nie_types = 'XT'
    78         self.nie_types = 'XT'
    79         super(ESIdentityCardNumberField, self).__init__(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types + self.cif_types.lower() + self.nie_types.lower(), self.nif_control + self.nif_control.lower()),
    79         id_card_re = re.compile(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control + self.cif_control), re.IGNORECASE)
    80                 max_length=None, min_length=None,
    80         super(ESIdentityCardNumberField, self).__init__(id_card_re, max_length=None, min_length=None,
    81                 error_message=self.default_error_messages['invalid%s' % (self.only_nif and '_only_nif' or '')],
    81                 error_message=self.default_error_messages['invalid%s' % (self.only_nif and '_only_nif' or '')],
    82                 *args, **kwargs)
    82                 *args, **kwargs)
    83 
    83 
    84     def clean(self, value):
    84     def clean(self, value):
    85         super(ESIdentityCardNumberField, self).clean(value)
    85         super(ESIdentityCardNumberField, self).clean(value)
    86         if value in EMPTY_VALUES:
    86         if value in EMPTY_VALUES:
    87             return u''
    87             return u''
    88         nif_get_checksum = lambda d: self.nif_control[int(d)%23]
    88         nif_get_checksum = lambda d: self.nif_control[int(d)%23]
    89 
    89 
    90         value = value.upper().replace(' ', '').replace('-', '')
    90         value = value.upper().replace(' ', '').replace('-', '')
    91         m = re.match(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control), value)
    91         m = re.match(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control + self.cif_control), value)
    92         letter1, number, letter2 = m.groups()
    92         letter1, number, letter2 = m.groups()
    93 
    93 
    94         if not letter1 and letter2:
    94         if not letter1 and letter2:
    95             # NIF
    95             # NIF
    96             if letter2 == nif_get_checksum(number):
    96             if letter2 == nif_get_checksum(number):
   106         elif not self.only_nif and letter1 in self.cif_types and len(number) in [7, 8]:
   106         elif not self.only_nif and letter1 in self.cif_types and len(number) in [7, 8]:
   107             # CIF
   107             # CIF
   108             if not letter2:
   108             if not letter2:
   109                 number, letter2 = number[:-1], int(number[-1])
   109                 number, letter2 = number[:-1], int(number[-1])
   110             checksum = cif_get_checksum(number)
   110             checksum = cif_get_checksum(number)
   111             if letter2 in [checksum, self.cif_control[checksum]]:
   111             if letter2 in (checksum, self.cif_control[checksum]):
   112                 return value
   112                 return value
   113             else:
   113             else:
   114                 raise ValidationError, self.error_messages['invalid_cif']
   114                 raise ValidationError, self.error_messages['invalid_cif']
   115         else:
   115         else:
   116             raise ValidationError, self.error_messages['invalid']
   116             raise ValidationError, self.error_messages['invalid']
   178 
   178 
   179 
   179 
   180 def cif_get_checksum(number):
   180 def cif_get_checksum(number):
   181     s1 = sum([int(digit) for pos, digit in enumerate(number) if int(pos) % 2])
   181     s1 = sum([int(digit) for pos, digit in enumerate(number) if int(pos) % 2])
   182     s2 = sum([sum([int(unit) for unit in str(int(digit) * 2)]) for pos, digit in enumerate(number) if not int(pos) % 2])
   182     s2 = sum([sum([int(unit) for unit in str(int(digit) * 2)]) for pos, digit in enumerate(number) if not int(pos) % 2])
   183     return 10 - ((s1 + s2) % 10)
   183     return (10 - ((s1 + s2) % 10)) % 10
   184 
   184