Ticket #11734: forms.py

File forms.py, 3.3 KB (added by jbkunst, 15 years ago)
Line 
1"""
2Chile specific form helpers.
3"""
4
5from django.forms import ValidationError
6from django.forms.fields import RegexField, Select, EMPTY_VALUES
7from django.utils.translation import ugettext_lazy as _
8from django.utils.encoding import smart_unicode
9
10
11class CLRegionSelect(Select):
12
13 def __init__(self, attrs=None):
14 from cl_reg_prov_com import REGION_CHOICES
15 super(CLRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
16
17class CLProvinciaSelect(Select):
18
19 def __init__(self, attrs=None):
20 from cl_reg_prov_com import PROVINCIA_CHOICES
21 super(CLProvinciaSelect, self).__init__(attrs, choices=PROVINCIA_CHOICES)
22
23class CLComunaSelect(Select):
24
25 def __init__(self, attrs=None):
26 from cl_reg_prov import COMUNA_CHOICES
27 super(CLComunaSelect, self).__init__(attrs, choices=COMUNA_CHOICES)
28
29class CLRutField(RegexField):
30 """
31 Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
32 identification number.
33
34 Samples for testing are available from
35 https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
36 """
37 default_error_messages = {
38 'invalid': _('Enter a valid Chilean RUT.'),
39 'strict': _('Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.'),
40 'checksum': _('The Chilean RUT is not valid.'),
41 }
42
43 def __init__(self, *args, **kwargs):
44 if 'strict' in kwargs:
45 del kwargs['strict']
46 super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
47 error_message=self.default_error_messages['strict'], *args, **kwargs)
48 else:
49 # In non-strict mode, accept RUTs that validate but do not exist in
50 # the real world.
51 super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', *args, **kwargs)
52
53 def clean(self, value):
54 """
55 Check and clean the Chilean RUT.
56 """
57 super(CLRutField, self).clean(value)
58 if value in EMPTY_VALUES:
59 return u''
60 rut, verificador = self._canonify(value)
61 if self._algorithm(rut) == verificador:
62 return self._format(rut, verificador)
63 else:
64 raise ValidationError(self.error_messages['checksum'])
65
66 def _algorithm(self, rut):
67 """
68 Takes RUT in pure canonical form, calculates the verifier digit.
69 """
70 suma = 0
71 multi = 2
72 for r in rut[::-1]:
73 suma += int(r) * multi
74 multi += 1
75 if multi == 8:
76 multi = 2
77 return u'0123456789K0'[11 - suma % 11]
78
79 def _canonify(self, rut):
80 """
81 Turns the RUT into one normalized format. Returns a (rut, verifier)
82 tuple.
83 """
84 rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '')
85 return rut[:-1], rut[-1]
86
87 def _format(self, code, verifier=None):
88 """
89 Formats the RUT from canonical form to the common string representation.
90 If verifier=None, then the last digit in 'code' is the verifier.
91 """
92 if verifier is None:
93 verifier = code[-1]
94 code = code[:-1]
95 while len(code) > 3 and '.' not in code[:3]:
96 pos = code.find('.')
97 if pos == -1:
98 new_dot = -3
99 else:
100 new_dot = pos - 3
101 code = code[:new_dot] + '.' + code[new_dot:]
102 return u'%s-%s' % (code, verifier)
Back to Top