lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.17-34-g2907676

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.17-34-g2907676



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  2907676a1f9f6ab6f1588c66c5f9b30b64ee3297 (commit)
      from  d70549a36bc6f13c21dc1b4b6042d3532f84d2e8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-stdnum/commit/?id=2907676a1f9f6ab6f1588c66c5f9b30b64ee3297

commit 2907676a1f9f6ab6f1588c66c5f9b30b64ee3297
Author: Leandro Regueiro <leandro.regueiro@gmail.com>
Date:   Sat Sep 3 21:50:51 2022 +0200

    Add support for Morocco TIN
    
    Closes https://github.com/arthurdejong/python-stdnum/issues/226
    Closes https://github.com/arthurdejong/python-stdnum/pull/312

diff --git a/stdnum/ma/__init__.py b/stdnum/ma/__init__.py
new file mode 100644
index 0000000..d2b0ff2
--- /dev/null
+++ b/stdnum/ma/__init__.py
@@ -0,0 +1,24 @@
+# __init__.py - collection of Moroccan numbers
+# coding: utf-8
+#
+# Copyright (C) 2022 Leandro Regueiro
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""Collection of Moroccan numbers."""
+
+# provide vat as an alias
+from stdnum.ma import ice as vat  # noqa: F401
diff --git a/stdnum/ma/ice.py b/stdnum/ma/ice.py
new file mode 100644
index 0000000..8beb585
--- /dev/null
+++ b/stdnum/ma/ice.py
@@ -0,0 +1,102 @@
+# ice.py - functions for handling Morocco ICE numbers
+# coding: utf-8
+#
+# Copyright (C) 2022 Leandro Regueiro
+# Copyright (C) 2022 Arthur de Jong
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""ICE (Identifiant Commun de l’Entreprise, التعريف الموحد للمقاولة, Morocco 
tax number).
+
+The ICE is a number that identifies the company and its branches in a unique
+and uniform way by all Moroccan administrations. It comes in addition to the
+other legal identifiers, notably the "identifiant fiscal" (IF), the "numéro de
+registre de commerce" (RC) and the CNSS number. The ICE does not replace these
+identifiers, which remain mandatory.
+
+The ICE is intended to ease communication among Moroccan administration
+branches, therefore simplifying procedures, increasing reliability and speed,
+and thefore reducing costs.
+
+The ICE applies to legal entities and their branches, as well as to natural
+persons.
+
+The ICE consists of 15 characters, where the first 9 represent the enterprise,
+the following 4 represent its establishments, and the last 2 are control
+characters.
+
+More information:
+
+* https://www.ice.gov.ma/
+* https://www.ice.gov.ma/ICE/Depliant_ICE.pdf
+* https://www.ice.gov.ma/ICE/Guide_ICE.pdf
+
+>>> validate('001561191000066')
+'001561191000066'
+>>> validate('00 21 36 09 30 00 040')
+'002136093000040'
+>>> validate('12345')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> validate('001561191000065')
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+>>> format('00 21 36 09 30 00 040')
+'002136093000040'
+"""
+
+from stdnum.exceptions import *
+from stdnum.iso7064 import mod_97_10
+from stdnum.util import clean, isdigits
+
+
+def compact(number):
+    """Convert the number to the minimal representation.
+
+    This strips the number of any valid separators, removes surrounding
+    whitespace.
+    """
+    return clean(number, ' ')
+
+
+def validate(number):
+    """Check if the number is a valid Morocco ICE number.
+
+    This checks the length and formatting.
+    """
+    number = compact(number)
+    if len(number) != 15:
+        raise InvalidLength()
+    if not isdigits(number):
+        raise InvalidFormat()
+    if mod_97_10.checksum(number) != 0:
+        raise InvalidChecksum()
+    return number
+
+
+def is_valid(number):
+    """Check if the number is a valid Morocco ICE number."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
+
+
+def format(number):
+    """Reformat the number to the standard presentation format."""
+    return compact(number).zfill(15)
diff --git a/tests/test_ma_ice.doctest b/tests/test_ma_ice.doctest
new file mode 100644
index 0000000..1014ba4
--- /dev/null
+++ b/tests/test_ma_ice.doctest
@@ -0,0 +1,153 @@
+test_ma_ice.doctest - more detailed doctests for stdnum.ma.ice module
+
+Copyright (C) 2022 Leandro Regueiro
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA
+
+
+This file contains more detailed doctests for the stdnum.ma.ice module. It
+tries to test more corner cases and detailed functionality that is not really
+useful as module documentation.
+
+>>> from stdnum.ma import ice
+
+
+Tests for some corner cases.
+
+>>> ice.validate('001561191000066')
+'001561191000066'
+>>> ice.validate('12345')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> ice.validate('X0156119100006Z')
+Traceback (most recent call last):
+    ...
+InvalidFormat: ...
+>>> ice.format('00 21 36 09 30 00 040')
+'002136093000040'
+>>> ice.format('36794000036')
+'000036794000036'
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... 000030205000041
+... 000039557000028
+... 000084803000004
+... 000106304000022
+... 000121494000008
+... 000206981000071
+... 00 21 36 09 30 00 040
+... 001512572000078
+... 001561191000066
+... 001565457000023
+... 001604356000066
+... 001629924000079
+... 001680801000017
+... 001731355000043
+... 001744856000042
+... 001747979000014
+... 001748885000093
+... 001753989000025
+... 001757319000034
+... 001827913000046
+... 001867807000093
+... 001883389000068
+... 001887940000090
+... 001906225000028
+... 001911196000059
+... 001965640000009
+... 001974718000022
+... 001976463000049
+... 001985336000068
+... 001996344000060
+... 002007999000043
+... 002020847000019
+... 002023181000051
+... 002033432000015
+... 002034945000001
+... 002037826000008
+... 002058647000053
+... 002063738000045
+... 002064672000047
+... 002076600000031
+... 002085583000087
+... 002105112000096
+... 002117772000007
+... 002143491000017
+... 002153925000084
+... 002171831000070
+... 002175561000046
+... 002183254000012
+... 002196660000054
+... 002200638000027
+... 002214705000070
+... 002223396000056
+... 002229460000064
+... 002270907000084
+... 002276099000065
+... 002284350000097
+... 002289496000059
+... 002295895000043
+... 002316916000023
+... 002329576000031
+... 002330015000012
+... 002332839000006
+... 002333592000045
+... 002335910000024
+... 002336083000009
+... 002356463000030
+... 002362254000037
+... 002364621000051
+... 002397991000094
+... 002398966000056
+... 002404272000063
+... 002410367000010
+... 002411901000011
+... 002428800000026
+... 002434341000090
+... 002443493000045
+... 002533410000002
+... 002539687000079
+... 002548326000014
+... 002553650000020
+... 002567289000076
+... 002581462000070
+... 002586051000036
+... 002591358000016
+... 002604451000070
+... 002614910000044
+... 002627640000005
+... 002630734000081
+... 002667689000038
+... 002672505000083
+... 002673962000029
+... 002701712000007
+... 002702346000058
+... 002738846000078
+... 002753855000004
+... 002848452000089
+... 002855545000056
+... 002904997000057
+... 003004995000009
+... 003102867000036
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not ice.is_valid(x)]
+[]

-----------------------------------------------------------------------

Summary of changes:
 stdnum/{ke => ma}/__init__.py |   8 +--
 stdnum/ma/ice.py              | 102 ++++++++++++++++++++++++++++
 tests/test_ma_ice.doctest     | 153 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 259 insertions(+), 4 deletions(-)
 copy stdnum/{ke => ma}/__init__.py (83%)
 create mode 100644 stdnum/ma/ice.py
 create mode 100644 tests/test_ma_ice.doctest


hooks/post-receive
-- 
python-stdnum