Ticket #3946: ch-localflavor.diff

File ch-localflavor.diff, 5.2 KB (added by charly.wilhelm@…, 8 years ago)

initial ch localflavor

  • django/contrib/localflavor/ch/ch_states.py

     
     1# -*- coding: utf-8 -*
     2from django.utils.translation import gettext_lazy as _
     3
     4STATE_CHOICES = (
     5    ('AG', _('Aargau')),
     6    ('AI', _('Appenzell Innerrhoden')),
     7    ('AR', _('Appenzell Ausserrhoden')),
     8    ('BS', _('Basel-Stadt')),
     9    ('BL', _('Basel-Land')),
     10    ('BE', _('Berne')),
     11    ('FR', _('Fribourg')),
     12    ('GE', _('Geneva')),
     13    ('GL', _('Glarus')),
     14    ('GR', _('Graubuenden')),
     15    ('JU', _('Jura')),
     16    ('LU', _('Lucerne')),
     17    ('NE', _('Neuchatel')),
     18    ('NW', _('Nidwalden')),
     19    ('OW', _('Obwalden')),
     20    ('SH', _('Schaffhausen')),
     21    ('SZ', _('Schwyz')),
     22    ('SO', _('Solothurn')),
     23    ('SG', _('St. Gallen')),
     24    ('TG', _('Thurgau')),
     25    ('TI', _('Ticino')),
     26    ('UR', _('Uri')),
     27    ('VS', _('Valais')),
     28    ('VD', _('Vaud')),
     29    ('ZG', _('Zug')),
     30    ('ZH', _('Zurich'))
     31)
  • django/contrib/localflavor/ch/forms.py

     
     1"""
     2CH-specific Form helpers
     3"""
     4
     5from django.newforms import ValidationError
     6from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
     7from django.utils.encoding import smart_unicode
     8from django.utils.translation import gettext
     9import re
     10
     11id_re = re.compile(r"^(?P<idnumber>\w{8})(?P<pos9>(\d{1}|<))(?P<checksum>\d{1})$")
     12phone_digits_re = re.compile(r'^0\d{9}$')
     13
     14class CHZipCodeField(RegexField):
     15    def __init__(self, *args, **kwargs):
     16        super(CHZipCodeField, self).__init__(r'^\d{4}$',
     17        max_length=None, min_length=None,
     18        error_message=gettext(u'Enter a zip code in the format XXXX.'),
     19        *args, **kwargs)
     20
     21class CHPhoneNumberField(Field):
     22    """
     23    Validate local Swiss phone number (not international ones)
     24    The correct format is '0XX XXX XX XX'.
     25    '0XX.XXX.XX.XX' and '0XXXXXXXXX' validate but are corrected to
     26    '0XX XXX XX XX'.
     27    """
     28    def clean(self, value):
     29        super(CHPhoneNumberField, self).clean(value)
     30        if value in EMPTY_VALUES:
     31            return u''
     32        value = re.sub('(\.|\s)', '', smart_unicode(value))
     33        print value
     34        m = phone_digits_re.search(value)
     35        if m:
     36            print u'%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10])
     37            return u'%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10])
     38        raise ValidationError(u'Phone numbers must be in 0XX XXX XX XX format.')
     39   
     40class CHStateSelect(Select):
     41    """
     42    A Select widget that uses a list of CH states as its choices.
     43    """
     44    def __init__(self, attrs=None):
     45        from ch_states import STATE_CHOICES # relative import
     46        super(CHStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
     47
     48class CHIdentityCardNumberField(Field):
     49    """
     50    A Swiss identity card number.
     51
     52    Checks the following rules to determine whether the number is valid:
     53
     54        * Conforms to the X1234567<0 or 1234567890 format.
     55        * Included checksums match calculated checksums
     56
     57    Algorithm is documented at http://adi.kousz.ch/artikel/IDCHE.htm
     58    """
     59   
     60    def has_valid_checksum(self, number):
     61        given_number, given_checksum = number[:-1], number[-1]
     62        new_number = given_number
     63        calculated_checksum = 0
     64        fragment = ""
     65        parameter = 7
     66
     67        first = str(number[:1])
     68        if first.isalpha():
     69            num = 'ABCDEFGHIJ'.index(str(first).upper())
     70            new_number = str('ABCDEFGHIJ'.index(str(first).upper())) + new_number[1:]
     71            new_number = new_number[:8] + '0'
     72
     73        if not new_number.isdigit():
     74            return False
     75       
     76        for i in range(len(new_number)):
     77          fragment = int(new_number[i])*parameter
     78          calculated_checksum += fragment
     79
     80          if parameter == 1:
     81            parameter = 7
     82          elif parameter == 3:
     83            parameter = 1
     84          elif parameter ==7:
     85            parameter = 3
     86
     87        return str(calculated_checksum)[-1] == given_checksum
     88
     89    def clean(self, value):
     90        #super(CHIdentityCardNumberField, self).clean(value)
     91        error_msg = gettext(u'Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format')
     92        if value in EMPTY_VALUES:
     93            return u''
     94       
     95        match = re.match(id_re, value)
     96        if not match:
     97            raise ValidationError(error_msg)
     98
     99        idnumber, pos9, checksum = match.groupdict()['idnumber'], match.groupdict()['pos9'], match.groupdict()['checksum']
     100
     101        if idnumber == '00000000' or \
     102           idnumber == 'A0000000':
     103            raise ValidationError(error_msg)
     104
     105        all_digits = "%s%s%s" % (idnumber, pos9, checksum)
     106        if not self.has_valid_checksum(all_digits):
     107            raise ValidationError(error_msg)
     108
     109        return u'%s%s%s' % (idnumber, pos9, checksum)
Back to Top