PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/django/contrib/localflavor/cl/forms.py

https://code.google.com/p/mango-py/
Python | 95 lines | 83 code | 4 blank | 8 comment | 0 complexity | 59927b7d051f5157ac707d8b23412f2c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. """
  2. Chile specific form helpers.
  3. """
  4. from django.core.validators import EMPTY_VALUES
  5. from django.forms import ValidationError
  6. from django.forms.fields import RegexField, Select
  7. from django.utils.translation import ugettext_lazy as _
  8. from django.utils.encoding import smart_unicode
  9. class CLRegionSelect(Select):
  10. """
  11. A Select widget that uses a list of Chilean Regions (Regiones)
  12. as its choices.
  13. """
  14. def __init__(self, attrs=None):
  15. from cl_regions import REGION_CHOICES
  16. super(CLRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
  17. class CLRutField(RegexField):
  18. """
  19. Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
  20. identification number.
  21. Samples for testing are available from
  22. https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
  23. """
  24. default_error_messages = {
  25. 'invalid': _('Enter a valid Chilean RUT.'),
  26. 'strict': _('Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.'),
  27. 'checksum': _('The Chilean RUT is not valid.'),
  28. }
  29. def __init__(self, *args, **kwargs):
  30. if 'strict' in kwargs:
  31. del kwargs['strict']
  32. super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
  33. error_message=self.default_error_messages['strict'], *args, **kwargs)
  34. else:
  35. # In non-strict mode, accept RUTs that validate but do not exist in
  36. # the real world.
  37. super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', *args, **kwargs)
  38. def clean(self, value):
  39. """
  40. Check and clean the Chilean RUT.
  41. """
  42. super(CLRutField, self).clean(value)
  43. if value in EMPTY_VALUES:
  44. return u''
  45. rut, verificador = self._canonify(value)
  46. if self._algorithm(rut) == verificador:
  47. return self._format(rut, verificador)
  48. else:
  49. raise ValidationError(self.error_messages['checksum'])
  50. def _algorithm(self, rut):
  51. """
  52. Takes RUT in pure canonical form, calculates the verifier digit.
  53. """
  54. suma = 0
  55. multi = 2
  56. for r in rut[::-1]:
  57. suma += int(r) * multi
  58. multi += 1
  59. if multi == 8:
  60. multi = 2
  61. return u'0123456789K0'[11 - suma % 11]
  62. def _canonify(self, rut):
  63. """
  64. Turns the RUT into one normalized format. Returns a (rut, verifier)
  65. tuple.
  66. """
  67. rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '')
  68. return rut[:-1], rut[-1].upper()
  69. def _format(self, code, verifier=None):
  70. """
  71. Formats the RUT from canonical form to the common string representation.
  72. If verifier=None, then the last digit in 'code' is the verifier.
  73. """
  74. if verifier is None:
  75. verifier = code[-1]
  76. code = code[:-1]
  77. while len(code) > 3 and '.' not in code[:3]:
  78. pos = code.find('.')
  79. if pos == -1:
  80. new_dot = -3
  81. else:
  82. new_dot = pos - 3
  83. code = code[:new_dot] + '.' + code[new_dot:]
  84. return u'%s-%s' % (code, verifier)