Ticket #7763: ro_localflavor.patch

File ro_localflavor.patch, 8.6 KB (added by Mihai Damian, 16 years ago)

localflavor files

  • contrib/localflavor/ro/forms.py

     
     1# -*- coding: utf-8 -*-
     2"""
     3Romanian specific form helpers.
     4"""
     5
     6from django.newforms.fields import EMPTY_VALUES,Field,RegexField,Select
     7from django.newforms import ValidationError
     8from django.utils.translation import ugettext_lazy as _
     9import re
     10
     11class ROCIFField(RegexField):
     12    """
     13    A Romanian fiscal identity code (CIF) field
     14
     15    For CIF validation algorithm see http://www.validari.ro/cui.html
     16    """
     17    default_error_messages = {
     18        'invalid': _("Enter a valid CIF"),
     19    }
     20
     21    def __init__(self, *args, **kwargs):
     22        super(ROCIFField, self).__init__(r'^[0-9]{2,10}', max_length=10,
     23            min_length=2, *args, **kwargs)
     24
     25    def clean(self, value):
     26        """
     27        CIF validation
     28        """
     29        value = super(ROCIFField, self).clean(value)
     30        if value in EMPTY_VALUES:
     31            return u''
     32        # strip RO part
     33        if value[0:2] == 'RO':
     34            value = value[2:]
     35        key = '753217532'[::-1]
     36        value = value[::-1]
     37        key_iter = iter(key)
     38        checksum = 0
     39        for digit in value[1:]:
     40            checksum += int(digit) * int(key_iter.next())
     41        checksum = checksum * 10 % 11
     42        if checksum == 10:
     43            checksum = 0
     44        if checksum != int(value[0]):
     45            raise ValidationError(self.error_messages['invalid'])
     46        return value[::-1]
     47
     48class ROCNPField(RegexField):
     49    """
     50    A Romanian personal identity code (CNP) field
     51
     52    For CNP validation algorithm see http://www.validari.ro/cnp.html
     53    """
     54    default_error_messages = {
     55        'invalid': _("Enter a valid CNP"),
     56    }
     57
     58    def __init__(self, *args, **kwargs):
     59        super(ROCNPField, self).__init__(r'^[1-9][0-9]{12}', max_length=13,
     60            min_length=13, *args, **kwargs)
     61
     62    def clean(self, value):
     63        """
     64        CNP validations
     65        """
     66        value = super(ROCNPField, self).clean(value)
     67        # check birthdate digits
     68        import datetime
     69        try:
     70            datetime.date(int(value[1:3]),int(value[3:5]),int(value[5:7]))
     71        except:
     72            raise ValidationError(self.error_messages['invalid'])
     73        # checksum
     74        key = '279146358279'
     75        checksum = 0
     76        value_iter = iter(value)
     77        for digit in key:
     78            checksum += int(digit) * int(value_iter.next())
     79        checksum %= 11
     80        if checksum == 10:
     81            checksum = 1
     82        if checksum != int(value[12]):
     83            raise ValidationError(self.error_messages['invalid'])
     84        return value
     85
     86class ROCountyField(Field):
     87    """
     88    A form field that validates its input is a Romanian county name or
     89    abbreviation. It normalizes the input to the standard vehicle registration
     90    abbreviation for the given county
     91
     92    WARNING: This field will only accept names written with diacritics; consider
     93    using ROCountySelect if this behavior is unnaceptable for you
     94    Example:
     95        Argeş => valid
     96        Arges => invalid
     97    """
     98    default_error_messages = {
     99        'invalid': u'Enter a Romanian county code or name.',
     100    }
     101
     102    def clean(self, value):
     103        from ro_counties import COUNTIES_CHOICES
     104        super(ROCountyField, self).clean(value)
     105        if value in EMPTY_VALUES:
     106            return u''
     107        try:
     108            value = value.strip().upper()
     109        except AttributeError:
     110            pass
     111        # search for county code
     112        for entry in COUNTIES_CHOICES:
     113            if value in entry:
     114                return value
     115        # search for county name
     116        normalized_CC = []
     117        for entry in COUNTIES_CHOICES:
     118            normalized_CC.append((entry[0],entry[1].upper()))
     119        for entry in normalized_CC:
     120            if entry[1] == value:
     121                return entry[0]
     122        raise ValidationError(self.error_messages['invalid'])
     123
     124class ROCountySelect(Select):
     125    """
     126    A Select widget that uses a list of Romanian counties (judete) as its
     127    choices.
     128    """
     129    def __init__(self, attrs=None):
     130        from ro_counties import COUNTIES_CHOICES
     131        super(ROCountySelect, self).__init__(attrs, choices=COUNTIES_CHOICES)
     132
     133class ROIBANField(RegexField):
     134    """
     135    Romanian International Bank Account Number (IBAN) field
     136
     137    For Romanian IBAN validation algorithm see http://validari.ro/iban.html
     138    """
     139    default_error_messages = {
     140        'invalid': _('Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format'),
     141    }
     142
     143    def __init__(self, *args, **kwargs):
     144        super(ROIBANField, self).__init__(r'^[0-9A-Za-z\-\s]{24,40}$',
     145            max_length=40, min_length=24, *args, **kwargs)
     146
     147    def clean(self, value):
     148        """
     149        Strips - and spaces, performs country code and checksum validation
     150        """
     151        value = super(ROIBANField, self).clean(value)
     152        value = value.replace('-','')
     153        value = value.replace(' ','')
     154        value = value.upper()
     155        if value[0:2] != 'RO':
     156            raise ValidationError(self.error_messages['invalid'])
     157        numeric_format = ''
     158        for char in value[4:] + value[0:4]:
     159            if char.isalpha():
     160                numeric_format += str(ord(char) - 55)
     161            else:
     162                numeric_format += char
     163        if int(numeric_format) % 97 != 1:
     164            raise ValidationError(self.error_messages['invalid'])
     165        return value
     166       
     167
     168class ROPhoneNumberField(RegexField):
     169    """Romanian phone number field"""
     170    default_error_messages = {
     171        'invalid': _('Phone numbers must be in XXXX-XXXXXX format.'),
     172    }
     173
     174    def __init__(self, *args, **kwargs):
     175        super(ROPhoneNumberField, self).__init__(r'^[0-9\-\(\)\s]{10,20}$',
     176            max_length=20, min_length=10, *args, **kwargs)
     177
     178    def clean(self, value):
     179        """
     180        Strips -, (, ) and spaces, checks the final length
     181        """
     182        value = super(ROPhoneNumberField, self).clean(value)
     183        value = value.replace('-','')
     184        value = value.replace('(','')
     185        value = value.replace(')','')
     186        value = value.replace(' ','')
     187        if len(value) != 10:
     188            raise ValidationError(self.error_messages['invalid'])
     189        return value
     190
     191class ROPostalCodeField(RegexField):
     192    """Romanian postal code field."""
     193    default_error_messages = {
     194        'invalid': _('Enter a valid postal code in the format XXXXXX'),
     195    }
     196
     197    def __init__(self, *args, **kwargs):
     198        super(ROPostalCodeField, self).__init__(r'^[0-9][0-8][0-9]{4}$',
     199            max_length=6, min_length=6, *args, **kwargs)
  • contrib/localflavor/ro/ro_counties.py

     
     1# -*- coding: utf-8 -*-
     2"""
     3A list of Romanian counties as `choices` in a formfield.
     4
     5This exists in this standalone file so that it's only imported into memory
     6when explicitly needed.
     7"""
     8
     9COUNTIES_CHOICES = (
     10    ('AB', u'Alba'),
     11    ('AR', u'Arad'),
     12    ('AG', u'Argeş'),
     13    ('BC', u'Bacău'),
     14    ('BH', u'Bihor'),
     15    ('BN', u'Bistriţa-Năsăud'),
     16    ('BT', u'Botoşani'),
     17    ('BV', u'Braşov'),
     18    ('BR', u'Brăila'),
     19    ('B',  u'Bucureşti'),
     20    ('BZ', u'Buzău'),
     21    ('CS', u'Caraş-Severin'),
     22    ('CL', u'Călăraşi'),
     23    ('CJ', u'Cluj'),
     24    ('CT', u'Constanţa'),
     25    ('CV', u'Covasna'),
     26    ('DB', u'Dâmboviţa'),
     27    ('DJ', u'Dolj'),
     28    ('GL', u'Galaţi'),
     29    ('GR', u'Giurgiu'),
     30    ('GJ', u'Gorj'),
     31    ('HR', u'Harghita'),
     32    ('HD', u'Hunedoara'),
     33    ('IL', u'Ialomiţa'),
     34    ('IS', u'Iaşi'),
     35    ('IF', u'Ilfov'),
     36    ('MM', u'Maramureş'),
     37    ('MH', u'Mehedinţi'),
     38    ('MS', u'Mureş'),
     39    ('NT', u'Neamţ'),
     40    ('OT', u'Olt'),
     41    ('PH', u'Prahova'),
     42    ('SM', u'Satu Mare'),
     43    ('SJ', u'Sălaj'),
     44    ('SB', u'Sibiu'),
     45    ('SV', u'Suceava'),
     46    ('TR', u'Teleorman'),
     47    ('TM', u'Timiş'),
     48    ('TL', u'Tulcea'),
     49    ('VS', u'Vaslui'),
     50    ('VL', u'Vâlcea'),
     51    ('VN', u'Vrancea'),
     52)
Back to Top