Ticket #11517: patch_clpatentefield.diff

File patch_clpatentefield.diff, 3.6 KB (added by alej0, 6 years ago)
  • django/contrib/localflavor/cl/forms.py

     
    33"""
    44
    55from django.forms import ValidationError
    6 from django.forms.fields import RegexField, Select, EMPTY_VALUES
     6from django.forms.fields import RegexField, Select, EMPTY_VALUES, CharField
    77from django.utils.translation import ugettext_lazy as _
    88from django.utils.encoding import smart_unicode
    99
     10OLD = 0
     11NEW = 1
    1012
     13
    1114class CLRegionSelect(Select):
    1215    """
    1316    A Select widget that uses a list of Chilean Regions (Regiones)
    1417    as its choices.
    1518    """
     19
    1620    def __init__(self, attrs=None):
    1721        from cl_regions import REGION_CHOICES
    1822        super(CLRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
    1923
     24
    2025class CLRutField(RegexField):
    2126    """
    2227    Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
     
    9297            code = code[:new_dot] + '.' + code[new_dot:]
    9398        return u'%s-%s' % (code, verifier)
    9499
     100
     101class CLPatenteField(CharField):
     102    """
     103    Chilean "Patente", Placa Patente Field, support old LL-NNNN and new LLLL-NN
     104    type, where L in new can't be vowel or m,n and q.
     105    """
     106
     107    default_error_messages = CharField.default_error_messages
     108    default_error_messages.update({'invalid': _('Enter a valid Chilean Car Plate.'),})
     109
     110    def __init__(self, *args, **kwargs):
     111        kwargs['max_length'] = 7
     112        kwargs['min_length'] = 6
     113        kwargs['label'] = "Valor"
     114        super(CLPatenteField, self).__init__(*args, **kwargs)
     115
     116    def clean(self, value):
     117        """
     118        Check and clean the field for length and type.
     119        """
     120        super(CLPatenteField, self).clean(value)
     121        if value in EMPTY_VALUES:
     122            return u''
     123
     124        value = smart_unicode(value.lower())
     125        value_length = len(value)
     126        if self.max_length is not None and value_length > self.max_length:
     127            raise ValidationError(self.error_messages['max_length'] % {'max': self.max_length, 'length': value_length})
     128        if self.min_length is not None and value_length < self.min_length:
     129            raise ValidationError(self.error_messages['min_length'] % {'min': self.min_length, 'length': value_length})
     130
     131        value = self._canonify(value)
     132        _type = self._algorithm(value)
     133
     134        if _type not in (OLD, NEW):
     135            raise ValidationError(self.error_messages['invalid'])
     136
     137        return self._format(value.upper(), _type)
     138
     139    def _algorithm(self, value):
     140        """
     141        Takes Car Plate in canonical form and verify if it is valid.
     142        Returns the type or None it is not valid.
     143        """
     144        import re
     145        # Old type patern
     146        op = '^[a-z]{2,2}\d{4,4}$'
     147        op = re.compile(op)
     148        # New type patern
     149        np = '^[bcdfghjklprstvwxyz]{4,4}\d{2,2}$'
     150        np = re.compile(np)
     151        if re.search(op, value):
     152            return OLD
     153        elif re.search(np, value):
     154            return NEW
     155        else:
     156            return None
     157
     158    def _canonify(self, patente):
     159        """
     160        Turns the Car Plate into one normalized format.
     161        """
     162        return patente.replace(' ', '').replace('-', '')
     163
     164    def _format(self, value, _type):
     165        """
     166        Formats the Car Plate from canonical form to the common string
     167        representation. LL-DDDD or LLLL-DD
     168        """
     169        if _type == OLD:
     170            return u'-'.join((value[:2], value[2:]))
     171        if _type == NEW:
     172            return u'-'.join((value[:4], value[4:]))
Back to Top