diff --git a/docs/authors.rst b/docs/authors.rst index add25b974..026839e00 100644 --- a/docs/authors.rst +++ b/docs/authors.rst @@ -2,6 +2,7 @@ Authors ======= * Aaron Boman +* Abdellah El Youssfi Alaoui * Adam Taylor * Adnane Belmadiaf * Adonys Alea Boffill diff --git a/docs/changelog.rst b/docs/changelog.rst index e41dfb278..cb0c49375 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,7 +10,7 @@ New flavors: New fields for existing flavors: -- None +- Added CIN Number field in Morocco flavor (`gh-705 `_). Modifications to existing flavors: diff --git a/localflavor/ma/forms.py b/localflavor/ma/forms.py index 84bbd9e4c..8e11a0a19 100644 --- a/localflavor/ma/forms.py +++ b/localflavor/ma/forms.py @@ -74,3 +74,26 @@ class MARegionField(CharField): def __init__(self, **kwargs): kwargs.setdefault('label', _('Select Region')) super().__init__(**kwargs) + + +class MACinNumberField(RegexField): + """ + CIN number: (Numéro de la Carte D'Identité Nationale) The CIN represents the ID of a Moroccan citizen. + + - It is an 8-max-length string that starts with one or two Latin letters followed by digits, + with the first digit not being zero. + + - as implemented in the official government site "https://www.cnie.ma/" + .. versionadded:: 4.1 + """ + + default_error_messages = { + 'invalid': _('Enter a valid Moroccan CIN number.'), + } + cin_pattern = r'^[A-Za-z]{1,2}[1-9][0-9]{0,6}$' + + def __init__(self, **kwargs): + kwargs.setdefault('label', _('CIN Number')) + kwargs['max_length'] = 8 + kwargs['min_length'] = 2 + super().__init__(self.cin_pattern, **kwargs) diff --git a/tests/test_ma.py b/tests/test_ma.py index 2fdb75e5e..09e92ead6 100644 --- a/tests/test_ma.py +++ b/tests/test_ma.py @@ -1,6 +1,7 @@ from django.test import SimpleTestCase -from localflavor.ma.forms import MAPostalCodeField, MAProvinceField, MAProvinceSelect, MARegionField, MARegionSelect +from localflavor.ma.forms import MAPostalCodeField, MAProvinceField, MAProvinceSelect, MARegionField, MARegionSelect, \ + MACinNumberField PROVINCE_SELECT_OUTPUT = ''' ''' + class MALocalFlavorTests(SimpleTestCase): def test_MAPostalCodeField(self): error_format = ['Enter a postal code in the format XXXXX.'] @@ -128,3 +130,32 @@ def test_MAProvinceSelect(self): def test_MARegionSelect(self): f = MARegionSelect() self.assertHTMLEqual(f.render('region', '04'), REGION_SELECT_OUTPUT) + + def test_MACinNumberField(self): + error_format = ['Enter a valid Moroccan CIN number.'] + valid = { + 'D1': 'D1', + 'DZ1': 'DZ1', + 'D23': 'D23', + 'DR23': 'DR23', + 'D345': 'D345', + 'DR345': 'DR345', + 'D3454': 'D3454', + 'DT3454': 'DT3454', + 'D34546': 'D34546', + 'DG34546': 'DG34546', + 'D345467': 'D345467', + 'DH345467': 'DH345467', + 'D3454673': 'D3454673', + + } + invalid = { + '9': ['Ensure this value has at least 2 characters (it has 1).'] + error_format, + 'T': ['Ensure this value has at least 2 characters (it has 1).'] + error_format, + '903': error_format, + 'D034': error_format, + 'DR034': error_format, + 'RER45': error_format, + 'T23456786': ['Ensure this value has at most 8 characters (it has 9).'] + error_format, + } + self.assertFieldOutput(MACinNumberField, valid, invalid)