Add Django-1.2.1
[frozenviper.git] / Django-1.2.1 / build / lib.linux-i686-2.6 / django / contrib / localflavor / ar / forms.py
blob53721a17b6f808469886305b2d92838c7f374f9a
1 # -*- coding: utf-8 -*-
2 """
3 AR-specific Form helpers.
4 """
6 from django.forms import ValidationError
7 from django.core.validators import EMPTY_VALUES
8 from django.forms.fields import RegexField, CharField, Select
9 from django.utils.encoding import smart_unicode
10 from django.utils.translation import ugettext_lazy as _
12 class ARProvinceSelect(Select):
13 """
14 A Select widget that uses a list of Argentinean provinces/autonomous cities
15 as its choices.
16 """
17 def __init__(self, attrs=None):
18 from ar_provinces import PROVINCE_CHOICES
19 super(ARProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
21 class ARPostalCodeField(RegexField):
22 """
23 A field that accepts a 'classic' NNNN Postal Code or a CPA.
25 See http://www.correoargentino.com.ar/consulta_cpa/home.php
26 """
27 default_error_messages = {
28 'invalid': _("Enter a postal code in the format NNNN or ANNNNAAA."),
31 def __init__(self, *args, **kwargs):
32 super(ARPostalCodeField, self).__init__(r'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
33 min_length=4, max_length=8, *args, **kwargs)
35 def clean(self, value):
36 value = super(ARPostalCodeField, self).clean(value)
37 if value in EMPTY_VALUES:
38 return u''
39 if len(value) not in (4, 8):
40 raise ValidationError(self.error_messages['invalid'])
41 if len(value) == 8:
42 return u'%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
43 return value
45 class ARDNIField(CharField):
46 """
47 A field that validates 'Documento Nacional de Identidad' (DNI) numbers.
48 """
49 default_error_messages = {
50 'invalid': _("This field requires only numbers."),
51 'max_digits': _("This field requires 7 or 8 digits."),
54 def __init__(self, *args, **kwargs):
55 super(ARDNIField, self).__init__(max_length=10, min_length=7, *args,
56 **kwargs)
58 def clean(self, value):
59 """
60 Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats.
61 """
62 value = super(ARDNIField, self).clean(value)
63 if value in EMPTY_VALUES:
64 return u''
65 if not value.isdigit():
66 value = value.replace('.', '')
67 if not value.isdigit():
68 raise ValidationError(self.error_messages['invalid'])
69 if len(value) not in (7, 8):
70 raise ValidationError(self.error_messages['max_digits'])
72 return value
74 class ARCUITField(RegexField):
75 """
76 This field validates a CUIT (Código Único de Identificación Tributaria). A
77 CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
78 """
79 default_error_messages = {
80 'invalid': _('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
81 'checksum': _("Invalid CUIT."),
84 def __init__(self, *args, **kwargs):
85 super(ARCUITField, self).__init__(r'^\d{2}-?\d{8}-?\d$',
86 *args, **kwargs)
88 def clean(self, value):
89 """
90 Value can be either a string in the format XX-XXXXXXXX-X or an
91 11-digit number.
92 """
93 value = super(ARCUITField, self).clean(value)
94 if value in EMPTY_VALUES:
95 return u''
96 value, cd = self._canon(value)
97 if self._calc_cd(value) != cd:
98 raise ValidationError(self.error_messages['checksum'])
99 return self._format(value, cd)
101 def _canon(self, cuit):
102 cuit = cuit.replace('-', '')
103 return cuit[:-1], cuit[-1]
105 def _calc_cd(self, cuit):
106 mults = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
107 tmp = sum([m * int(cuit[idx]) for idx, m in enumerate(mults)])
108 return str(11 - tmp % 11)
110 def _format(self, cuit, check_digit=None):
111 if check_digit == None:
112 check_digit = cuit[-1]
113 cuit = cuit[:-1]
114 return u'%s-%s-%s' % (cuit[:2], cuit[2:], check_digit)