8000 Add Algerian NIF number · unho/python-stdnum@31709fc · GitHub
[go: up one dir, main page]

Skip to content

Commit 31709fc

Browse files
unhoarthurdejong
authored andcommitted
Add Algerian NIF number
This currently only checks the length and whether it only contains digits because little could be found on the structure of the number of whether there are any check digits. Closes arthurdejong#313 Closes arthurdejong#307
1 parent 2907676 commit 31709fc

File tree

3 files changed

+282
-0
lines changed

3 files changed

+282
-0
lines changed

stdnum/dz/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# __init__.py - collection of Algerian numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2022 Leandro Regueiro
5+
#
6+
# This library is free software; you can redistribute it and/or
7+
# modify it under the terms of the GNU Lesser General Public
8+
# License as published by the Free Software Foundation; either
9+
# version 2.1 of the License, or (at your option) any later version.
10+
#
11+
# This library is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public
17+
# License along with this library; if not, write to the Free Software
18+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19+
# 02110-1301 USA
20+
21+
"""Collection of Algerian numbers."""
22+
23+
# provide vat as an alias
24+
from stdnum.dz import nif as vat # noqa: F401

stdnum/dz/nif.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# pin.py - functions for handling Algeria NIF numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2022 Leandro Regueiro
5+
#
6+
# This library is free software; you can redistribute it and/or
7+
# modify it under the terms of the GNU Lesser General Public
8+
# License as published by the Free Software Foundation; either
9+
# version 2.1 of the License, or (at your option) any later version.
10+
#
11+
# This library is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public
17+
# License along with this library; if not, write to the Free Software
18+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19+
# 02110-1301 USA
20+
21+
"""NIF, sometimes N.I.F. (Numéro d'Identification Fiscale, Algeria tax number).
22+
23+
The NIF was adopted by the Algerian tax authorities on 2006, replacing the NIS
24+
number.
25+
26+
The NIF applies to physical persons, legal persons, legal entities,
27+
administrative entities, local branches for foreign companies, associations,
28+
professional organisations, etc.
29+
30+
The NIF consists of 15 digits, but sometimes it can be 20 digits long in order
31+
to represent branches or secondary establishments.
32+
33+
More information:
34+
35+
* http://www.jecreemonentreprise.dz/index.php?option=com_content&view=article&id=612&Itemid=463&lang=fr
36+
* https://www.mf.gov.dz/index.php/fr/fiscalite
37+
* https://cnrcinfo.cnrc.dz/numero-didentification-fiscale-nif/
38+
* https://nifenligne.mfdgi.gov.dz/
39+
* http://nif.mfdgi.gov.dz/nif.asp
40+
41+
>>> validate('416001000000007')
42+
'416001000000007'
43+
>>> validate('408 020 000 150 039')
44+
'408020000150039'
45+
>>> validate('41201600000606600001')
46+
'41201600000606600001'
47+
>>> validate('000 216 001 808 337 13010')
48+
'00021600180833713010'
49+
>>> validate('12345')
50+
Traceback (most recent call last):
51+
...
52+
InvalidLength: ...
53+
>>> validate('X1600100000000V')
54+
Traceback (most recent call last):
55+
...
56+
InvalidFormat: ...
57+
>>> format('408 020 000 150 039')
58+
'408020000150039'
59+
>>> format('000 216 001 808 337 13010')
60+
'00021600180833713010'
61+
"""
62+
63+
from stdnum.exceptions import *
64+
from stdnum.util import clean, isdigits
65+
66+
67+
def compact(number):
68+
"""Convert the number to the minimal representation.
69+
70+
This strips the number of any valid separators, removes surrounding
71+
whitespace.
72+
"""
73+
return clean(number, ' ')
74+
75+
76+
def validate(number):
77+
"""Check if the number is a valid Algeria NIF number.
78+
79+
This checks the length and formatting.
80+
"""
81+
number = compact(number)
82+
if len(number) not in (15, 20):
83+
raise InvalidLength()
84+
if not isdigits(number):
85+
raise InvalidFormat()
86+
return number
87+
88+
89+
def is_valid(number):
90+
"""Check if the number is a valid Algeria NIF number."""
91+
try:
92+
return bool(validate(number))
93+
except ValidationError:
94+
return False
95+
96+
97+
def format(number):
98+
"""Reformat the number to the standard presentation format."""
99+
return compact(number)

tests/test_dz_nif.doctest

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
test_dz_nif.doctest - more detailed doctests for stdnum.dz.nif module
2+
3+
Copyright (C) 2022 Leandro Regueiro
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18+
02110-1301 USA
19+
20+
21+
This file contains more detailed doctests for the stdnum.dz.nif module. It
22+
tries to test more corner cases and detailed functionality that is not really
23+
useful as module documentation.
24+
25+
>>> from stdnum.dz import nif
26+
27+
28+
Tests for some corner cases.
29+
30+
>>> nif.validate('416001000000007')
31+
'416001000000007'
32+
>>> nif.validate('408 020 000 150 039')
33+
'408020000150039'
34+
>>> nif.validate('41201600000606600001')
35+
'41201600000606600001'
36+
>>> nif.validate('000 216 001 808 337 13010')
37+
'00021600180833713010'
38+
>>> nif.validate('12345')
39+
Traceback (most recent call last):
40+
...
41+
InvalidLength: ...
42+
>>> nif.validate('X1600100000000V')
43+
Traceback (most recent call last):
44+
...
45+
InvalidFormat: ...
46+
>>> nif.format('408 020 000 150 039')
47+
'408020000150039'
48+
>>> nif.format('000 216 001 808 337 13010')
49+
'00021600180833713010'
50+
51+
52+
These have been found online and should all be valid numbers.
53+
54+
>>> numbers = '''
55+
...
56+
... 000 116 180 807 261
57+
... 000 216 001 808 337
58+
... 000 216 001 808 337 13010
59+
... 0000 1600 15 01 289
60+
... 000016001159195
61+
... 000016001300865
62+
... 000016001358124
63+
... 00001600137674493005
64+
... 000116001524660
65+
... 000116001567707
66+
... 000116180849545
67+
... 00021 600 180 833 716 001
68+
... 000216002104442
69+
... 000216299033049
70+
... 000307024248170
71+
... 000336068252339
72+
... 000347019004646
73+
... 000428056270862
74+
... 000434046319884
75+
... 000505022347781
76+
... 000516096825183
77+
... 000516096872520
78+
... 000616097459024
79+
... 000624038263530
80+
... 000716097425528
81+
... 000716097805474
82+
... 000724038267478
83+
... 000735072494667
84+
... 000824038269319
85+
... 000825006783595
86+
... 000848019007735
87+
... 000906018632115
88+
... 001 109 199 007 345
89+
... 001116099033052
90+
... 001125069042347
91+
... 001206018759104
92+
... 001216098929656
93+
... 001216209014175
94+
... 001216209014745
95+
... 001225006964374
96+
... 00131 6099242493
97+
... 001316099262097
98+
... 001316100750513
99+
... 001316100750533
100+
... 001341050285855
101+
... 001513026489736
102+
... 001609019033838
103+
... 001616104328611
104+
... 001707024366917
105+
... 001716104401413
106+
... 001730019009056
107+
... 001816104587248
108+
... 002016101606088
109+
... 002131011846676
110+
... 097524019047421
111+
... 098919015000337
112+
... 099716000280672
113+
... 099747086204339
114+
... 099807024211756
115+
... 099815019058902
116+
... 099816000499785
117+
... 099915004292220
118+
... 099916029015224
119+
... 099919008329067
120+
... 099925006295010
121+
... 099935072285348
122+
... 152431400682135
123+
... 153160105528127
124+
... 164151000512151
125+
... 165161701380190
126+
... 169164800432122
127+
... 171161800210177
128+
... 181050400060195
129+
... 185160201610152
130+
... 194 916 010 095 431
131+
... 195213040012847
132+
... 196 816 040 011 445
133+
... 197 919 010 321 535
134+
... 197016180012728
135+
... 198018210116342
136+
... 198805420009824
137+
... 198847070005037
138+
... 287160700030597
139+
... 295161704436174
140+
... 408 020 000 150 039
141+
... 408008000100033
142+
... 408015000017094
143+
... 408015000043003
144+
... 408020000020098
145+ 8057
... 408020000060031
146+
... 408020000290087
147+
... 408020000310039
148+
... 408020001100031
149+
... 40802100000204900000
150+
... 410007000000046
151+
... 410011000000012
152+
... 417180000000088
153+
... 420016000090015
154+
... 420110400000042
155+
... 797 435 379 003 601
156+
...
157+
... '''
158+
>>> [x for x in numbers.splitlines() if x and not nif.is_valid(x)]
159+
[]

0 commit comments

Comments
 (0)
0