1 | """
|
---|
2 | Spain-specific Form helpers
|
---|
3 | """
|
---|
4 | from django.newforms import ValidationError
|
---|
5 | from django.newforms.fields import Field, EMPTY_VALUES
|
---|
6 | from django.utils.translation import ugettext_lazy as _
|
---|
7 |
|
---|
8 | class ESNifField(Field):
|
---|
9 | """
|
---|
10 | Spanish NIF/NIE/CIF (Fiscal Identification Number) code.
|
---|
11 |
|
---|
12 | Validates three diferent formats,
|
---|
13 | NIF (individuals): 12345678A
|
---|
14 | CIF (companies): A12345678
|
---|
15 | NIE (foreigners): X12345678A
|
---|
16 | according to the simple checksum algorithm.
|
---|
17 | Value can include any separator between number and letter (commonly used hyphen or space). Actually any strange character is ignored in whole value.
|
---|
18 | Less (or more) than 8 digits are allowed. It's not a mistake, old NIFs have 7 numbers, and 9 number codes could exist in the future.
|
---|
19 | Return value is normalized like patterns in previous examples (also changing letters to upper case).
|
---|
20 | """
|
---|
21 | def clean(self, value):
|
---|
22 | super(ESNifField, self).clean(value)
|
---|
23 | if value in EMPTY_VALUES:
|
---|
24 | return ''
|
---|
25 | checksum_list = 'TRWAGMYFPDXBNJZSQVHLCKE'
|
---|
26 | normalized_value = ''
|
---|
27 | for char in value:
|
---|
28 | if char.isdigit() or char.upper() in checksum_list:
|
---|
29 | normalized_value += char.upper()
|
---|
30 | if normalized_value[0] == 'X' and normalized_value[1:-1].isdigit() and normalized_value[-1] in checksum_list:
|
---|
31 | nif_number, nif_letter = normalized_value[1:-1], normalized_value[-1]
|
---|
32 | elif normalized_value[0] in checksum_list and normalized_value[1:].isdigit():
|
---|
33 | nif_letter, nif_number = normalized_value[0], normalized_value[1:]
|
---|
34 | elif normalized_value[:-1].isdigit() and normalized_value[-1] in checksum_list:
|
---|
35 | nif_number, nif_letter = normalized_value[:-1], normalized_value[-1]
|
---|
36 | else:
|
---|
37 | print normalized_value
|
---|
38 | raise ValidationError(_('Enter a CIF, NIF or NIE in the format Z99999999, 99999999Z or X99999999Z.'))
|
---|
39 |
|
---|
40 | if nif_letter == checksum_list[int(nif_number) % len(checksum_list)]:
|
---|
41 | return normalized_value
|
---|
42 | else:
|
---|
43 | raise ValidationError(_('Invalid letter for CIF/NIF number'))
|
---|
44 |
|
---|