# -*- coding: utf-8 -*- """ UY-specific form helpers. """ import re from django.core.validators import EMPTY_VALUES from django.forms.fields import Select, RegexField from django.forms import ValidationError from django.utils.translation import ugettext_lazy as _ from django.contrib.localflavor.uy.util import get_validation_digit class UYDepartamentSelect(Select): """ A Select widget that uses a list of Uruguayan departaments as its choices. """ def __init__(self, attrs=None): from uy_departaments import DEPARTAMENT_CHOICES super(UYDepartamentSelect, self).__init__(attrs, choices=DEPARTAMENT_CHOICES) class UYCIField(RegexField): """ A field that validates Uruguayan 'Cedula de identidad' (CI) numbers. """ default_error_messages = { 'invalid': _("Enter a valid CI number in X.XXX.XXX-X," "XXXXXXX-X or XXXXXXXX format."), 'invalid_validation_digit': _("Enter a valid CI number."), } def __init__(self, *args, **kwargs): super(UYCIField, self).__init__(r'(?P(\d{6,7}|(\d\.)?\d{3}\.\d{3}))-?(?P\d)', *args, **kwargs) def clean(self, value): """ Validates format and validation digit. The official format is [X.]XXX.XXX-X but usually dots and/or slash are omitted so, when validating, those characters are ignored if found in the correct place. The three typically used formats are supported: [X]XXXXXXX, [X]XXXXXX-X and [X.]XXX.XXX-X. """ value = super(UYCIField, self).clean(value) if value in EMPTY_VALUES: return u'' match = self.regex.match(value) if not match: raise ValidationError(self.error_messages['invalid']) number = int(match.group('num').replace('.', '')) validation_digit = int(match.group('val')) if not validation_digit == get_validation_digit(number): raise ValidationError(self.error_messages['invalid_validation_digit']) return value