| 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 |
|
|---|