1 # -*- coding: utf-8 -*-
3 AR-specific Form helpers.
6 from django
.newforms
import ValidationError
7 from django
.newforms
.fields
import RegexField
, CharField
, Select
, EMPTY_VALUES
8 from django
.utils
.encoding
import smart_unicode
9 from django
.utils
.translation
import ugettext
12 class ARProvinceSelect(Select
):
14 A Select widget that uses a list of Argentinean provinces/autonomous cities
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
):
23 A field that accepts a `classic´ NNNN Postal Code or a CPA.
25 See http://www.correoargentino.com.ar/consulta_cpa/home.php
27 def __init__(self
, *args
, **kwargs
):
28 super(ARPostalCodeField
, self
).__init
__(r
'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
29 min_length
=4, max_length
=8,
30 error_message
=ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
33 def clean(self
, value
):
34 value
= super(ARPostalCodeField
, self
).clean(value
)
35 if value
in EMPTY_VALUES
:
37 if len(value
) not in (4, 8):
38 raise ValidationError(ugettext("Enter a postal code in the format NNNN or ANNNNAAA."))
40 return u
'%s%s%s' % (value
[0].upper(), value
[1:5], value
[5:].upper())
43 class ARDNIField(CharField
):
45 A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
47 def __init__(self
, *args
, **kwargs
):
48 super(ARDNIField
, self
).__init
__(max_length
=10, min_length
=7, *args
,
51 def clean(self
, value
):
53 Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats.
55 value
= super(ARDNIField
, self
).clean(value
)
56 if value
in EMPTY_VALUES
:
58 if not value
.isdigit():
59 value
= value
.replace('.', '')
60 if not value
.isdigit():
61 raise ValidationError(ugettext("This field requires only numbers."))
62 if len(value
) not in (7, 8):
63 raise ValidationError(
64 ugettext("This field requires 7 or 8 digits."))
68 class ARCUITField(RegexField
):
70 This field validates a CUIT (Código Único de Identificación Tributaria). A
71 CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
73 def __init__(self
, *args
, **kwargs
):
74 super(ARCUITField
, self
).__init
__(r
'^\d{2}-?\d{8}-?\d$',
75 error_message
=ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
78 def clean(self
, value
):
80 Value can be either a string in the format XX-XXXXXXXX-X or an
83 value
= super(ARCUITField
, self
).clean(value
)
84 if value
in EMPTY_VALUES
:
86 value
, cd
= self
._canon
(value
)
87 if self
._calc
_cd
(value
) != cd
:
88 raise ValidationError(ugettext("Invalid CUIT."))
89 return self
._format
(value
, cd
)
91 def _canon(self
, cuit
):
92 cuit
= cuit
.replace('-', '')
93 return cuit
[:-1], cuit
[-1]
95 def _calc_cd(self
, cuit
):
96 mults
= (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
97 tmp
= sum([m
* int(cuit
[idx
]) for idx
, m
in enumerate(mults
)])
98 return str(11 - tmp
% 11)
100 def _format(self
, cuit
, check_digit
=None):
101 if check_digit
== None:
102 check_digit
= cuit
[-1]
104 return u
'%s-%s-%s' % (cuit
[:2], cuit
[2:], check_digit
)