Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adding MXSocialSecurityNumberField to local flavor #42

Closed
wants to merge 8 commits into from

4 participants

@gerardo-orozco

Adding MXSocialSecurityNumberField to local flavor

AUTHORS
@@ -563,6 +563,7 @@ answer newbie questions, and generally made Django that much better:
Gasper Zejn <zejn@kiberpipa.org>
Jarek Zgoda <jarek.zgoda@gmail.com>
Cheng Zhang
+ Francisco Albarran Cristobal <pahko.xd@gmail.com>
@ramiro Collaborator
ramiro added a note

Contributor names in the AUTHORS file need to be sorted by last name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
django/contrib/localflavor/mx/forms.py
((11 lines not shown))
+ following the next pattern:
+
+ ===== =======================================
+ Index Required numbers
+ ===== =======================================
+ 1-2 The number of the branch office where the Social Security Number
+ was designated.
+ 3-4 The year of inscription to the Social Security.
+ 5-6 The year of birth of the Social Security Number owner.
+ 7-10 The progressive number of procedure for the IMSS.
+ (This digit is provided exclusively by the Institute as it regards
+ the Folio number of such procedure).
+ 11 The verification digit.
+
+ More info about this:
+ <reference here>
@ramiro Collaborator
ramiro added a note

Please add the reference or simply remove the section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@pahko

Now Fixed @ramiro thanks.

@adrianholovaty
Collaborator

Hey there -- django.contrib.localflavor is now deprecated, and we're not making any more changes to it (see https://docs.djangoproject.com/en/dev/ref/contrib/localflavor/). Could you reopen this pull request for the shiny new package django-localflavor-mx? Here's the link: https://github.com/django/django-localflavor-mx

Sorry we didn't get to this pull request before the deprecation. I hope it's not too much of a pain to migrate this to the new package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
1  AUTHORS
@@ -43,6 +43,7 @@ answer newbie questions, and generally made Django that much better:
ajs <adi@sieker.info>
alang@bright-green.com
A S Alam <aalam@users.sf.net>
+ Francisco Albarran Cristobal <pahko.xd@gmail.com>
Andi Albrecht <albrecht.andi@gmail.com>
Marty Alchin <gulopine@gamemusic.org>
Ahmad Alhashemi <trans@ahmadh.com>
View
58 django/contrib/localflavor/mx/forms.py
@@ -17,7 +17,6 @@
document described in the next link:
http://www.sisi.org.mx/jspsi/documentos/2005/seguimiento/06101/0610100162005_065.doc
"""
-
RFC_INCONVENIENT_WORDS = [
u'BUEI', u'BUEY', u'CACA', u'CACO', u'CAGA', u'CAGO', u'CAKA', u'CAKO',
u'COGE', u'COJA', u'COJE', u'COJI', u'COJO', u'CULO', u'FETO', u'GUEY',
@@ -46,6 +45,7 @@
u'WUEY',
]
+
class MXStateSelect(Select):
"""
A Select widget that uses a list of Mexican states as its choices.
@@ -105,8 +105,8 @@ class MXRFCField(RegexField):
http://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes_(M%C3%A9xico)
"""
default_error_messages = {
- 'invalid': _('Enter a valid RFC.'),
- 'invalid_checksum': _('Invalid checksum for RFC.'),
+ 'invalid': _(u'Enter a valid RFC.'),
+ 'invalid_checksum': _(u'Invalid checksum for RFC.'),
}
def __init__(self, min_length=9, max_length=13, *args, **kwargs):
@@ -186,7 +186,7 @@ class MXCURPField(RegexField):
http://www.condusef.gob.mx/index.php/clave-unica-de-registro-de-poblacion-curp
"""
default_error_messages = {
- 'invalid': _('Enter a valid CURP.'),
+ 'invalid': _(u'Enter a valid CURP.'),
'invalid_checksum': _(u'Invalid checksum for CURP.'),
}
@@ -223,3 +223,53 @@ def _checksum(self, value):
def _has_inconvenient_word(self, curp):
first_four = curp[:4]
return first_four in CURP_INCONVENIENT_WORDS
+
+
+class MXSocialSecurityNumberField(RegexField):
+ """
+ A field that validates a Mexican Social Security Number.
+
+ The Social Security Number is integrated by a juxtaposition of digits
+ following the next pattern:
+
+ ===== =======================================
+ Index Required numbers
+ ===== =======================================
+ 1-2 The number of the branch office where the Social Security Number
+ was designated.
+ 3-4 The year of inscription to the Social Security.
+ 5-6 The year of birth of the Social Security Number owner.
+ 7-10 The progressive number of procedure for the IMSS.
+ (This digit is provided exclusively by the Institute as it regards
+ the Folio number of such procedure).
+ 11 The verification digit.
+ """
+ default_error_messages = {
+ 'invalid': _(u'Enter a valid Social Security Number.'),
+ 'invalid_checksum': _(u'Invalid checksum for Social Security Number.'),
+ }
+
+ def __init__(self, min_length=11, max_length=11, *args, **kwargs):
+ ssn_re = ur'^\d{11}$'
+ ssn_re = re.compile(ssn_re)
+ super(MXSocialSecurityNumberField, self).__init__(ssn_re,
+ min_length=min_length, max_length=max_length, *args, **kwargs)
+
+ def clean(self, value):
+ value = super(MXSocialSecurityNumberField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ if value[-1] != self.__checksum(value[:-1]):
+ raise ValidationError(self.default_error_messages['invalid_checksum'])
+ return value
+
+ def __checksum(self, value):
+ multipliers = [1 if i % 2 == 0 else 2 for i in xrange(10)]
+
+ s = [int(v) * m for v, m in zip(value, multipliers)]
+ s = sum(map(int, ''.join(map(str, s))))
+ checksum = 10 - s % 10
+
+ if checksum == 10:
+ return u'0'
+ return unicode(checksum)
View
22 django/contrib/localflavor/mx/models.py
@@ -3,7 +3,8 @@
from django.contrib.localflavor.mx.mx_states import STATE_CHOICES
from django.contrib.localflavor.mx.forms import (MXRFCField as MXRFCFormField,
- MXZipCodeField as MXZipCodeFormField, MXCURPField as MXCURPFormField)
+ MXZipCodeField as MXZipCodeFormField, MXCURPField as MXCURPFormField,
+ MXSocialSecurityNumberField as MXSocialSecurityNumberFormField)
class MXStateField(CharField):
@@ -67,4 +68,21 @@ def __init__(self, *args, **kwargs):
def formfield(self, **kwargs):
defaults = {'form_class': MXCURPFormField}
defaults.update(kwargs)
- return super(MXCURPField, self).formfield(**defaults)
+
+
+class MXSocialSecurityNumberField(CharField):
+ """
+ A model field that forms represent as a forms.MXSocialSecurityNumberField
+ field and stores the value of a valid Mexican Social Security Number.
+ """
+ description = _("Mexican Social Security Number")
+
+ def __init__(self, *args, **kwargs):
+ kwargs['max_length'] = 11
+ super(MXSocialSecurityNumberField, self).__init__(*args, **kwargs)
+
+ def formfield(self, **kwargs):
+ defaults = {'form_class': MXSocialSecurityNumberFormField}
+ defaults.update(kwargs)
+ return super(MXSocialSecurityNumberField, self).formfield(**defaults)
View
10 docs/ref/contrib/localflavor.txt
@@ -842,6 +842,11 @@ Mexico (``mx``)
.. _curp: http://www.condusef.gob.mx/index.php/clave-unica-de-registro-de-poblacion-curp
+.. class:: mx.forms.MXSocialSecurityNumberField
+
+ A field that validates a Mexican Social Security Number(NSS) for *Instituto Mexicano del Seguro Social*.
+
+
.. class:: mx.forms.MXStateSelect
A ``Select`` widget that uses a list of Mexican states as its choices.
@@ -874,6 +879,11 @@ Mexico (``mx``)
A model field that forms represent as a ``forms.MXCURPField`` field and
stores the value of a valid Mexican CURP.
+.. class:: mx.models.MXSocialSecurityNumberField
+
+ A model field that forms represent as a ``forms.MXSocialSecurityNumberField`` field and
+ stores the eleven-digit Mexican Social Security Number for *Instituto Mexicano del Seguro Social*.
+
Additionally, a choice tuple is provided in ``django.contrib.localflavor.mx.mx_states``,
allowing customized model and form fields, and form presentations, for subsets of
Mexican states abbreviations:
View
4 tests/regressiontests/localflavor/mx/models.py
@@ -1,5 +1,6 @@
from django.contrib.localflavor.mx.models import (
- MXStateField, MXRFCField, MXCURPField, MXZipCodeField)
+ MXStateField, MXRFCField, MXCURPField, MXZipCodeField,
+ MXSocialSecurityNumberField)
from django.db import models
@@ -8,6 +9,7 @@ class MXPersonProfile(models.Model):
rfc = MXRFCField()
curp = MXCURPField()
zip_code = MXZipCodeField()
+ ssn = MXSocialSecurityNumberField()
class Meta:
app_label = 'localflavor'
View
48 tests/regressiontests/localflavor/mx/tests.py
@@ -2,7 +2,7 @@
from __future__ import absolute_import
from django.contrib.localflavor.mx.forms import (MXZipCodeField, MXRFCField,
- MXStateSelect, MXCURPField)
+ MXStateSelect, MXCURPField, MXSocialSecurityNumberField)
from django.test import SimpleTestCase
from .forms import MXPersonProfileForm
@@ -16,6 +16,7 @@ def setUp(self):
'rfc': 'toma880125kv3',
'curp': 'toma880125hmnrrn02',
'zip_code': '58120',
+ 'ssn': '53987417457',
})
def test_get_display_methods(self):
@@ -30,12 +31,14 @@ def test_errors(self):
'rfc': 'invalid rfc',
'curp': 'invalid curp',
'zip_code': 'xxx',
+ 'ssn': 'invalid ssn',
})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['state'], [u'Select a valid choice. Invalid state is not one of the available choices.'])
self.assertEqual(form.errors['rfc'], [u'Enter a valid RFC.'])
self.assertEqual(form.errors['curp'], [u'Ensure this value has at least 18 characters (it has 12).', u'Enter a valid CURP.'])
self.assertEqual(form.errors['zip_code'], [u'Enter a valid zip code in the format XXXXX.'])
+ self.assertEqual(form.errors['ssn'], [u'Enter a valid Social Security Number.'])
def test_field_blank_option(self):
"""Test that the empty option is there."""
@@ -196,3 +199,46 @@ def test_MXCURPField(self):
'OOMG890727HMNRSR07': error_checksum,
}
self.assertFieldOutput(MXCURPField, valid, invalid)
+
+ def test_MXSocialSecurityNumberField(self):
+ error_format = [u'Enter a valid Social Security Number.']
+ error_checksum = [u'Invalid checksum for Social Security Number.']
+ valid = {
+ '53987417457': u'53987417457',
+ '53916912966': u'53916912966',
+ '53986504172': u'53986504172',
+ '17300426925': u'17300426925',
+ '53067407212': u'53067407212',
+ '53018000538': u'53018000538',
+ '10836311612': u'10836311612',
+ '37007910666': u'37007910666',
+ '53055700974': u'53055700974',
+ '17303364941': u'17303364941',
+ '53078528469': u'53078528469',
+ }
+ invalid = {
+ # Invalid format
+ '5398741A457': error_format,
+ '53487G12031': error_format,
+ '530P8028702': error_format,
+ '173004K6925': error_format,
+ '5306T407212': error_format,
+ '53018N00538': error_format,
+ 'E0836311612': error_format,
+ '3700U910666': error_format,
+ '530557 0974': error_format,
+ '173033?4941': error_format,
+ '53#88417917': error_format,
+ # Incorrect checksum
+ '53987417451': error_checksum,
+ '53018522942': error_checksum,
+ '53897239693': error_checksum,
+ '01704423244': error_checksum,
+ '53855919735': error_checksum,
+ '53926201296': error_checksum,
+ '53017919037': error_checksum,
+ '53884201248': error_checksum,
+ '42805762629': error_checksum,
+ '53563800130': error_checksum,
+ }
+ self.assertFieldOutput(MXSocialSecurityNumberField, valid, invalid)
Something went wrong with that request. Please try again.