Ticket #4036: 4036_2.diff

File 4036_2.diff, 9.1 KB (added by Marc Garcia, 17 years ago)

spanish localflavor files

  • django/contrib/localflavor/es/es_regions.py

     
     1# -*- coding: utf-8 -*-
     2from django.utils.translation import ugettext_lazy as _
     3
     4REGION_CHOICES = (
     5        ('AN', _('Andalusia')),
     6        ('AR', _('Aragon')),
     7        ('O', _('Principality of Asturias')),
     8        ('IB', _('Balearic Islands')),
     9        ('PV', _('Basque Country')),
     10        ('CN', _('Canary Islands')),
     11        ('S', _('Cantabria')),
     12        ('CM', _('Castile-La Mancha')),
     13        ('CL', _('Castile and León')),
     14        ('CT', _('Catalonia')),
     15        ('EX', _('Extremadura')),
     16        ('GA', _('Galicia')),
     17        ('LO', _('La Rioja')),
     18        ('M', _('Madrid')),
     19        ('MU', _('Region of Murcia')),
     20        ('NA', _('Foral Community of Navarre')),
     21        ('VC', _('Valencian Community')),
     22)
     23
  • django/contrib/localflavor/es/es_provinces.py

     
     1# -*- coding: utf-8 -*-
     2from django.utils.translation import ugettext_lazy as _
     3
     4PROVINCE_CHOICES = (
     5        ('01', _('Arava')),
     6        ('02', _('Albacete')),
     7        ('03', _('Alacant')),
     8        ('04', _('Almería')),
     9        ('05', _('Ávila')),
     10        ('06', _('Badajoz')),
     11        ('07', _('Illes Balears')),
     12        ('08', _('Barcelona')),
     13        ('09', _('Burgos')),
     14        ('10', _('Cáceres')),
     15        ('11', _('Cadiz')),
     16        ('12', _('Castelló')),
     17        ('13', _('Ciudad Real')),
     18        ('14', _('Córdoba')),
     19        ('15', _('A Coruña')),
     20        ('16', _('Cuenca')),
     21        ('17', _('Girona')),
     22        ('18', _('Granada')),
     23        ('19', _('Guadalajara')),
     24        ('20', _('Guipuzkoa')),
     25        ('21', _('Huelva')),
     26        ('22', _('Huesca')),
     27        ('23', _('Jaén')),
     28        ('24', _('León')),
     29        ('25', _('Lleida')),
     30        ('26', _('La Rioja')),
     31        ('27', _('Lugo')),
     32        ('28', _('Madrid')),
     33        ('29', _('Málaga')),
     34        ('30', _('Murcia')),
     35        ('31', _('Navarre')),
     36        ('32', _('Ourense')),
     37        ('33', _('Asturias')),
     38        ('34', _('Palencia')),
     39        ('35', _('Las Palmas')),
     40        ('36', _('Pontevedra')),
     41        ('37', _('Salamanca')),
     42        ('38', _('Santa Cruz de Tenerife')),
     43        ('39', _('Cantabria')),
     44        ('40', _('Segovia')),
     45        ('41', _('Seville')),
     46        ('42', _('Soria')),
     47        ('43', _('Tarragona')),
     48        ('44', _('Teruel')),
     49        ('45', _('Toledo')),
     50        ('46', _('València')),
     51        ('47', _('Valladolid')),
     52        ('48', _('Bizkaia')),
     53        ('49', _('Zamora')),
     54        ('50', _('Zaragoza')),
     55        ('51', _('Ceuta')),
     56        ('52', _('Melilla')),
     57)
     58
  • django/contrib/localflavor/es/forms.py

     
     1# -*- coding: utf-8 -*-
     2"""
     3Spanish-specific Form helpers
     4"""
     5
     6from django.newforms import ValidationError
     7from django.newforms.fields import RegexField, Select, EMPTY_VALUES
     8from django.utils.translation import ugettext as _
     9import re
     10
     11class ESPostalCodeField(RegexField):
     12    """
     13    A form field that validates its input as a spanish postal code.
     14   
     15    Spanish postal code is a five digits string, with two first digits
     16    between 01 and 52, assigned to provinces code.
     17    """
     18    def __init__(self, *args, **kwargs):
     19        super(ESPostalCodeField, self).__init__(r'^(0[1-9]|[1-4][0-9]|5[0-2])\d{3}$',
     20            max_length=None, min_length=None,
     21            error_message=_('Enter a valid postal code in the range and format 01XXX - 52XXX.'),
     22            *args, **kwargs)
     23
     24class ESPhoneNumberField(RegexField):
     25        """
     26        A form field that validates its input as a spanish Phone Number. Information numbers are ommited.
     27
     28        Spanish phone numbers are 9 digit numbers, where first digit is 6 (for cell phones), 8 (for special
     29        phones), or 9 (for landlines and special phones)
     30
     31        TODO: accept and strip characters like dot, hyphen... in phone number
     32        """
     33        def __init__(self, *args, **kwargs):
     34                super(ESPhoneNumberField, self).__init__(r'^(6|8|9)\d{8}$',
     35                                max_length=None, min_length=None,
     36                                error_message=_('Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'),
     37                                *args, **kwargs)
     38
     39class ESIdentityCardNumberField(RegexField):
     40        """
     41        Spanish NIF/NIE/CIF (Fiscal Identification Number) code.
     42
     43        Validates three diferent formats,
     44                NIF (individuals): 12345678A
     45                CIF (companies): A12345678
     46                NIE (foreigners): X12345678A
     47        according to a couple of simple checksum algorithms.
     48        Value can include a space or hyphen separator between number and letters.
     49        Number length is not checked for nif (or nie), old values started by 1, and future values can be more than 8.
     50        CIF control digit can be a number or a letter depending on company type. Algorithm is not public, and different
     51        authors have different opinions on which ones allows letters, so both validations are assumed true for all types.
     52        """
     53        def __init__(self, only_nif=False, *args, **kwargs):
     54                self.only_nif = only_nif
     55                self.nif_control = 'TRWAGMYFPDXBNJZSQVHLCKE'
     56                self.cif_control = 'JABCDEFGHI'
     57                self.cif_types = 'ABCDEFGHKLMNPQS'
     58                self.nie_types = 'XT'
     59                if self.only_nif:
     60                        self.id_types = 'NIF or NIE'
     61                else:
     62                        self.id_types = 'NIF, NIE, or CIF'
     63                super(ESIdentityCardNumberField, self).__init__(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control),
     64                                max_length=None, min_length=None,
     65                                error_message=_('Please enter a valid %s.' % self.id_types),
     66                                *args, **kwargs)
     67
     68        def clean(self, value):
     69                super(ESIdentityCardNumberField, self).clean(value)       
     70                if value in EMPTY_VALUES:
     71                        return u''
     72                nif_get_checksum = lambda d: self.nif_control[int(d)%23]
     73                def cif_get_checksum(number):
     74                        s1 = sum([int(digit) for pos, digit in enumerate(number) if int(pos) % 2])
     75                        s2 = sum([sum([int(unit) for unit in str(int(digit) * 2)]) for pos, digit in enumerate(number) if not int(pos) % 2])
     76                        return 10 - ((s1 + s2) % 10)
     77                #cif_get_checksum = lambda d: d
     78
     79                m = re.match(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control), value)
     80                letter1, number, letter2 = m.groups()
     81
     82                if not letter1 and letter2: # NIF
     83                        if letter2 == nif_get_checksum(number):
     84                                return value
     85                        else:
     86                                raise ValidationError, _('Invalid checksum for NIF.')
     87                elif letter1 in self.nie_types and letter2: # NIE
     88                        if letter2 == nif_get_checksum(number):
     89                                return value
     90                        else:
     91                                raise ValidationError, _('Invalid checksum for NIE.')
     92                elif not self.only_nif and letter1 in self.cif_types and len(number) in [7, 8]: # CIF
     93                        if not letter2:
     94                                number, letter2 = number[:-1], int(number[-1])
     95                        checksum = cif_get_checksum(number)
     96                        if letter2 in [checksum, self.cif_control[checksum]]:
     97                                return value
     98                        else:
     99                                raise ValidationError, _('Invalid checksum for CIF.')
     100                else:
     101                        raise ValidationError, _('Please enter a valid %s.' % self.id_types)
     102
     103class ESCCCField(RegexField):
     104        """
     105    A form field that validates its input as a spanish bank account or CCC (Código Cuenta Cliente)
     106
     107                Spanish CCC is in format EEEE-OOOO-CC-AAAAAAAAAA where
     108                        E = entity
     109                        O = office
     110                        C = checksum
     111                        A = account
     112                It's also valid using space as delimiter, or using no delimiter
     113
     114                First checksum digit validates entity and office, and last one validates account. Validation is
     115                done multiplying every digit of 10 digit value (with leading 0 if necessary) by number in its
     116                position in string 1, 2, 4, 8, 5, 10, 9, 7, 3, 6. Sum resulting numbers and extract it from 11.
     117                Result is checksum except when 10 then is 1, or when 11 then is 0.
     118
     119                TODO: allow IBAN validation too
     120        """
     121        def __init__(self, nif=True, cif=True, *args, **kwargs):
     122                super(ESCCCField, self).__init__(r'^\d{4}[ -]?\d{4}[ -]?\d{2}[ -]?\d{10}$',
     123                        max_length=None, min_length=None,
     124                        error_message=_('Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'),
     125                        *args, **kwargs)
     126        def clean(self, value):
     127                super(ESCCCField, self).clean(value)       
     128                if value in EMPTY_VALUES:
     129                        return u''
     130                control_str = [1, 2, 4, 8, 5, 10, 9, 7, 3, 6]
     131                m = re.match(r'^(\d{4})[ -]?(\d{4})[ -]?(\d{2})[ -]?(\d{10})$', value)
     132                entity, office, checksum, account = m.groups()
     133                get_checksum = lambda d: str(11 - sum([int(digit) * int(control) for digit, control in zip(d, control_str)]) % 11).replace('10', '1').replace('11', '0')
     134                if get_checksum('00' + entity + office) + get_checksum(account) == checksum:
     135                        return value
     136                else:
     137                        raise ValidationError, _('Invalid checksum for bank account number.')
     138
     139class ESRegionSelect(Select):
     140    """
     141    A Select widget that uses a list of spanish regions as its choices.
     142    """
     143    def __init__(self, attrs=None):
     144        from es_regions import REGION_CHOICES
     145        super(ESRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
     146
     147class ESProvinceSelect(Select):
     148    """
     149    A Select widget that uses a list of spanish provinces as its choices.
     150    """
     151    def __init__(self, attrs=None):
     152        from es_provinces import PROVINCE_CHOICES
     153        super(ESProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
     154
Back to Top