Code

Ticket #9042: localflavor_mx.diff

File localflavor_mx.diff, 3.6 KB (added by marco, 6 years ago)
Line 
1Index: django/contrib/localflavor/mx/forms.py
2===================================================================
3--- django/contrib/localflavor/mx/forms.py      (revision 9014)
4+++ django/contrib/localflavor/mx/forms.py      (working copy)
5@@ -1,3 +1,5 @@
6+# -*- coding: utf-8 -*-
7+
8 """
9 Mexican-specific form helpers.
10 """
11@@ -2,4 +4,8 @@
12 
13-from django.forms.fields import Select
14+import re
15 
16+from django.forms import ValidationError
17+from django.forms.fields import Select, RegexField, EMPTY_VALUES
18+from django.utils.translation import ugettext_lazy as _
19+
20 class MXStateSelect(Select):
21@@ -12,3 +18,83 @@
22         from mx_states import STATE_CHOICES
23         super(MXStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
24 
25+class MXPostalCodeField(RegexField):
26+    default_error_messages = {
27+        'invalid': _('Enter a postal code in the format XXXXX.'),
28+    }
29+
30+    def __init__(self, *args, **kwargs):
31+        super(MXPostalCodeField, self).__init__(r'^\d{5}$',
32+            min_length=5, max_length=5, *args, **kwargs)
33+           
34+class MXRFCField(RegexField):
35+    """
36+    Registro federal de contribuyente.
37+    """
38+    default_error_messages = {
39+        'invalid': _('Invalid RFC.'),
40+    }
41+
42+    def __init__(self, *args, **kwargs):
43+        super(MXRFCField, self).__init__(
44+            re.compile(r'^[A-Z&\d]{3,4}\d{6}[A-Z\d]{3}$', re.I),
45+            min_length=12, max_length=13, *args, **kwargs)
46+
47+    def clean(self, value):
48+        value = super(MXRFCField, self).clean(value)
49+       
50+        if value in EMPTY_VALUES:
51+            return u''
52+           
53+        value = value.upper().strip()
54+        if value[-1] != self._checksum(value[:-1]):
55+            raise ValidationError(self.error_messages['invalid'])
56+           
57+        return value
58+
59+    def _checksum(self, rfc):
60+        chars = '0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ-'
61+       
62+        if len(rfc) == 11:
63+            rfc = '-' + rfc
64+           
65+        s = sum(i * chars.index(c) for i, c in zip(reversed(xrange(14)), rfc))
66+        checksum = 11 - (s % 11)
67+       
68+        if checksum == 10:
69+            return 'A'
70+        elif checksum == 11:
71+            return '0'
72+        else:
73+            return str(checksum)
74+       
75+class MXCURPField(RegexField):
76+    """
77+    Clave única de registro de población.
78+    """
79+    default_error_messages = {
80+        'invalid': _('Invalid CURP.'),
81+    }
82+   
83+    def __init__(self, *args, **kwargs):
84+        curp_re = r'^[A-Z]{4}\d{6}[HM][A-Z]{2}[B-DF-HJ-NP-TV-Z]{3}[0-9A-Z]\d$'
85+        super(MXCURPField, self).__init__(re.compile(curp_re, re.I),
86+            min_length=18, max_length=18, *args, **kwargs)
87+
88+    def clean(self, value):
89+        value = super(MXCURPField, self).clean(value)
90+       
91+        if value in EMPTY_VALUES:
92+            return u''
93+           
94+        value = value.upper()
95+        if value[-1] != self._checksum(value[:-1]):
96+            raise ValidationError(self.error_messages['invalid'])
97+           
98+        return value
99+
100+    def _checksum(self, curp):
101+        chars = u'0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'
102+        s = sum(i * chars.index(c) for i, c in zip(reversed(xrange(19)), curp))
103+        checksum = 10 - (s % 10)
104+        return '0' if checksum == 10 else str(checksum)
105Index: AUTHORS
106===================================================================
107--- AUTHORS     (revision 9014)
108+++ AUTHORS     (working copy)
109@@ -395,6 +395,7 @@
110     tt@gurgle.no
111     David Tulig <david.tulig@gmail.com>
112     Amit Upadhyay <http://www.amitu.com/blog/>
113+       Marco Antonio Valenzuela Escárcega <http://cidia.com.mx>
114     Geert Vanderkelen
115     I.S. van Oostveen <v.oostveen@idca.nl>
116     viestards.lists@gmail.com