Ticket #3866: more_it_fields_3.diff

File more_it_fields_3.diff, 7.3 KB (added by Massimiliano Ravelli <massimiliano.ravelli@…>, 8 years ago)

ITFiscalCodeField renamed to ITSocialSecurityNumberField

  • django/contrib/localflavor/it/util.py

     
     1def ssn_check_digit(value):
     2    """ Calculate italian social security number check digit. """
     3    ssn_even_chars = {
     4        '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
     5        'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
     6        'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,
     7        'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25
     8    }
     9    ssn_odd_chars = {
     10        '0': 1, '1': 0, '2': 5, '3': 7, '4': 9, '5': 13, '6': 15, '7': 17, '8': 19, '9': 21,
     11        'A': 1, 'B': 0, 'C': 5, 'D': 7, 'E': 9, 'F': 13, 'G': 15, 'H': 17, 'I': 19, 'J': 21,
     12        'K': 2, 'L': 4, 'M': 18, 'N': 20, 'O': 11, 'P': 3, 'Q': 6, 'R': 8, 'S': 12,
     13        'T': 14, 'U': 16, 'V': 10, 'W': 22, 'X': 25, 'Y': 24, 'Z': 23
     14    }
     15    # Chars from 'A' to 'Z'
     16    ssn_check_digits = [chr(x) for x in range(65, 91)]
     17
     18    ssn = value.upper()
     19    total = 0
     20    for i in range(0,15):
     21        try:
     22            if i % 2 == 0:
     23                total += ssn_odd_chars[ssn[i]]
     24            else:
     25                total += ssn_even_chars[ssn[i]]
     26        except KeyError:
     27            msg = "Character '%(char)s' is not allowed." % {'char': ssn[i]}
     28            raise ValueError(msg)
     29    return ssn_check_digits[total % 26]
     30
     31def vat_number_check_digit(vat_number):
     32    """ Calculate italian vat number check digit. """
     33    normalized_vat_number = str(vat_number).zfill(10)
     34    total = 0
     35    for i in range(0, 10, 2):
     36        total += int(normalized_vat_number[i])
     37    for i in range(1, 11, 2):
     38        quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10)
     39        total += quotient + remainder
     40    return str((10 - total % 10) % 10)
  • django/contrib/localflavor/it/forms.py

     
    55from django.newforms import ValidationError
    66from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
    77from django.utils.translation import gettext
     8from django.utils.encoding import smart_unicode
     9from django.contrib.localflavor.it.util import ssn_check_digit, vat_number_check_digit
    810import re
    911
    1012class ITZipCodeField(RegexField):
     
    2931    def __init__(self, attrs=None):
    3032        from it_province import PROVINCE_CHOICES # relative import
    3133        super(ITProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
     34
     35class ITSocialSecurityNumberField(RegexField):
     36    """
     37    A form field  that validates it's input in Italian Social Security number
     38    (codice fiscale).
     39    For reference see http://www.agenziaentrate.it/ and search for
     40    'Informazioni sulla codificazione delle persone fisiche'.
     41    """
     42    err_msg = gettext(u'Enter a valid Social Security number.')
     43    def __init__(self, *args, **kwargs):
     44        super(ITSocialSecurityNumberField, self).__init__(r'^\w{3}\s*\w{3}\s*\w{5}\s*\w{5}$',
     45        max_length=None, min_length=None, error_message=self.err_msg,
     46        *args, **kwargs)
     47
     48    def clean(self, value):
     49        value = super(ITSocialSecurityNumberField, self).clean(value)
     50        if value == u'':
     51            return value
     52        value = re.sub('\s', u'', value).upper()
     53        try:
     54            check_digit = ssn_check_digit(value)
     55        except ValueError:
     56            raise ValidationError(self.err_msg)
     57        if not value[15] == check_digit:
     58            raise ValidationError(self.err_msg)
     59        return value
     60
     61class ITVatNumberField(Field):
     62    """
     63    A form field  that validates it's input in Italian VAT number (partita IVA).
     64    """
     65    def clean(self, value):
     66        value = super(ITVatNumberField, self).clean(value)
     67        if value == u'':
     68            return value
     69        err_msg = gettext(u'Enter a valid VAT number.')
     70        try:
     71            vat_number = int(value)
     72        except ValueError:
     73            raise ValidationError(err_msg)
     74        vat_number = str(vat_number).zfill(11)
     75        check_digit = vat_number_check_digit(vat_number[0:10])
     76        if not vat_number[10] == check_digit:
     77            raise ValidationError(err_msg)
     78        return smart_unicode(vat_number)
  • tests/regressiontests/forms/localflavor.py

     
    642642>>> w.render('regions', 'PMN')
    643643u'<select name="regions">\n<option value="ABR">Abruzzo</option>\n<option value="BAS">Basilicata</option>\n<option value="CAL">Calabria</option>\n<option value="CAM">Campania</option>\n<option value="EMR">Emilia-Romagna</option>\n<option value="FVG">Friuli-Venezia Giulia</option>\n<option value="LAZ">Lazio</option>\n<option value="LIG">Liguria</option>\n<option value="LOM">Lombardia</option>\n<option value="MAR">Marche</option>\n<option value="MOL">Molise</option>\n<option value="PMN" selected="selected">Piemonte</option>\n<option value="PUG">Puglia</option>\n<option value="SAR">Sardegna</option>\n<option value="SIC">Sicilia</option>\n<option value="TOS">Toscana</option>\n<option value="TAA">Trentino-Alto Adige</option>\n<option value="UMB">Umbria</option>\n<option value="VAO">Valle d\u2019Aosta</option>\n<option value="VEN">Veneto</option>\n</select>'
    644644
     645# ITSocialSecurityNumberField #################################################
     646
     647>>> from django.contrib.localflavor.it.forms import ITSocialSecurityNumberField
     648>>> f = ITSocialSecurityNumberField()
     649>>> f.clean('LVSGDU99T71H501L')
     650u'LVSGDU99T71H501L'
     651>>> f.clean('LBRRME11A01L736W')
     652u'LBRRME11A01L736W'
     653>>> f.clean('lbrrme11a01l736w')
     654u'LBRRME11A01L736W'
     655>>> f.clean('LBR RME 11A01 L736W')
     656u'LBRRME11A01L736W'
     657>>> f.clean('LBRRME11A01L736A')
     658Traceback (most recent call last):
     659...
     660ValidationError: [u'Enter a valid Social Security number.']
     661>>> f.clean('%BRRME11A01L736W')
     662Traceback (most recent call last):
     663...
     664ValidationError: [u'Enter a valid Social Security number.']
     665
     666# ITVatNumberField ###########################################################
     667
     668>>> from django.contrib.localflavor.it.forms import ITVatNumberField
     669>>> f = ITVatNumberField()
     670>>> f.clean('07973780013')
     671u'07973780013'
     672>>> f.clean('7973780013')
     673u'07973780013'
     674>>> f.clean(7973780013)
     675u'07973780013'
     676>>> f.clean('07973780014')
     677Traceback (most recent call last):
     678...
     679ValidationError: [u'Enter a valid VAT number.']
     680>>> f.clean('A7973780013')
     681Traceback (most recent call last):
     682...
     683ValidationError: [u'Enter a valid VAT number.']
     684
    645685# FIZipCodeField #############################################################
    646686
    647687FIZipCodeField validates that the data is a valid FI zipcode.
  • AUTHORS

     
    174174    J. Rademaker
    175175    Michael Radziej <mir@noris.de>
    176176    ramiro
     177    Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
    177178    Brian Ray <http://brianray.chipy.org/>
    178179    remco@diji.biz
    179180    rhettg@gmail.com
Back to Top