Skip to content

Commit a6e7ff3

Browse files
committed
Add TIN number for Rwanda
Fixes arthurdejong#315
1 parent 6d366e3 commit a6e7ff3

File tree

3 files changed

+368
-0
lines changed

3 files changed

+368
-0
lines changed

Diff for: stdnum/rw/__init__.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# __init__.py - collection of Rwanda numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2023 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 Rwanda numbers."""
22+
23+
# provide aliases
24+
from stdnum.rw import tin as vat # noqa: F401

Diff for: stdnum/rw/tin.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# tin.py - functions for handling Rwanda TIN numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2023 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+
"""TIN (Taxpayer's Identification Number, Rwanda tax number).
22+
23+
This number is also called "Numéro d'Identification du Contribuable", or
24+
"Numéro d'identification fiscale" or "Nomero iranga umusoreshwa", and is also
25+
shortened as "NIF".
26+
27+
This number consists of 9 digits.
28+
29+
More information:
30+
31+
* https://businessprocedures.rdb.rw/procedure/13/47?l=en
32+
* https://www.rra.gov.rw/en/home
33+
34+
>>> validate('102134442')
35+
'102134442'
36+
>>> validate('10 7826151')
37+
'107826151'
38+
>>> validate('12345')
39+
Traceback (most recent call last):
40+
...
41+
InvalidLength: ...
42+
>>> format('10 7826151')
43+
'107826151'
44+
""" # noqa: E501
45+
46+
from stdnum.exceptions import *
47+
from stdnum.util import clean, isdigits
48+
49+
50+
def compact(number):
51+
"""Convert the number to the minimal representation.
52+
53+
This strips the number of any valid separators and removes surrounding
54+
whitespace.
55+
"""
56+
return clean(number, ' -').strip()
57+
58+
59+
def validate(number):
60+
"""Check if the number is a valid Rwanda TIN number.
61+
62+
This checks the length and formatting.
63+
"""
64+
number = compact(number)
65+
if len(number) != 9:
66+
raise InvalidLength()
67+
if not isdigits(number):
68+
raise InvalidFormat()
69+
return number
70+
71+
72+
def is_valid(number):
73+
"""Check if the number is a valid Rwanda TIN number."""
74+
try:
75+
return bool(validate(number))
76+
except ValidationError:
77+
return False
78+
79+
80+
def format(number):
81+
"""Reformat the number to the standard presentation format."""
82+
return compact(number)

Diff for: tests/test_rw_tin.doctest

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
test_rw_tin.doctest - more detailed doctests for stdnum.rw.tin module
2+
3+
Copyright (C) 2023 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.rw.tin 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.rw import tin
26+
27+
28+
Tests for some corner cases.
29+
30+
>>> tin.validate('102134442')
31+
'102134442'
32+
>>> tin.validate('10 7826151')
33+
'107826151'
34+
>>> tin.validate('12345')
35+
Traceback (most recent call last):
36+
...
37+
InvalidLength: ...
38+
>>> tin.validate('1234567XX')
39+
Traceback (most recent call last):
40+
...
41+
InvalidFormat: ...
42+
>>> tin.format('10 7826151')
43+
'107826151'
44+
45+
46+
These have been found online and should all be valid numbers.
47+
48+
>>> numbers = '''
49+
...
50+
... 102134442
51+
... 101365708
52+
... 100384138
53+
... 101453690
54+
... 101799622
55+
... 100054122
56+
... 101909790
57+
... 101522783
58+
... 102259397
59+
... 102889110
60+
... 101982714
61+
... 103752228
62+
... 103449745
63+
... 106278222
64+
... 100003547
65+
... 102241010
66+
... 101806185
67+
... 100003458
68+
... 102294535
69+
... 102781991
70+
... 102750860
71+
... 100003547
72+
... 100005973
73+
... 110842971
74+
... 102175071
75+
... 108311419
76+
... 107610471
77+
... 111414698
78+
... 107215286
79+
... 100475843
80+
... 104940576
81+
... 102050982
82+
... 101302769
83+
... 104741833
84+
... 108708667
85+
... 10 7826151
86+
... 103745842
87+
... 107907110
88+
... 102517684
89+
... 108630474
90+
... 102517692
91+
... 107877617
92+
... 100842224
93+
... 111304003
94+
... 102312520
95+
... 101411623
96+
... 102966085
97+
... 102026860
98+
... 120201204
99+
... 106363818
100+
... 102925497
101+
... 102503783
102+
... 101651018
103+
... 102874107
104+
... 106208031
105+
... 107993781
106+
... 101611834
107+
... 101313744
108+
... 101338997
109+
... 101832055
110+
... 101898817
111+
... 101742978
112+
... 101402045
113+
... 101369930
114+
... 101605491
115+
... 100600260
116+
... 101658248
117+
... 119491475
118+
... 100805888
119+
... 101725879
120+
... 101674807
121+
... 102420381
122+
... 101056837
123+
... 102580229
124+
... 103548327
125+
... 101669410
126+
... 100600293
127+
... 102760872
128+
... 120335672
129+
... 101332193
130+
... 101717108
131+
... 103372620
132+
... 111598890
133+
... 113333440
134+
... 102043412
135+
... 101351105
136+
... 101529751
137+
... 101337363
138+
... 001337363
139+
... 113653574
140+
... 101406098
141+
... 101639016
142+
... 101639016
143+
... 101932000
144+
... 101398024
145+
... 103012202
146+
... 100834445
147+
... 101992637
148+
... 111704557
149+
... 101846992
150+
... 101828601
151+
... 101734460
152+
... 120385529
153+
... 101790784
154+
... 101735377
155+
... 103144513
156+
... 102872114
157+
... 101566434
158+
... 102279886
159+
... 116904634
160+
... 101888471
161+
... 101587056
162+
... 101808480
163+
... 100834501
164+
... 101931624
165+
... 101615259
166+
... 101628996
167+
... 101868137
168+
... 101403075
169+
... 101823693
170+
... 111444309
171+
... 120434728
172+
... 101494914
173+
... 101507188
174+
... 101515599
175+
... 101599094
176+
... 101743183
177+
... 101354055
178+
... 001354055
179+
... 101330738
180+
... 100842023
181+
... 102831150
182+
... 102000244
183+
... 102106636
184+
... 101419173
185+
... 102065987
186+
... 100604778
187+
... 102502361
188+
... 101378645
189+
... 101667834
190+
... 100600431
191+
... 103058257
192+
... 101853419
193+
... 101052213
194+
... 101662117
195+
... 101474514
196+
... 102190813
197+
... 101896784
198+
... 119776770
199+
... 102496275
200+
... 100834479
201+
... 101397575
202+
... 101397028
203+
... 107433062
204+
... 100600456
205+
... 107429609
206+
... 107433046
207+
... 120576276
208+
... 107429659
209+
... 100840910
210+
... 101852144
211+
... 101541027
212+
... 101673002
213+
... 101687703
214+
... 101746067
215+
... 103644998
216+
... 101488481
217+
... 119491475
218+
... 100805888
219+
... 101725879
220+
... 101674807
221+
... 102420381
222+
... 101056837
223+
... 102580229
224+
... 103548327
225+
... 101669410
226+
... 100600293
227+
... 102543856
228+
... 107794257
229+
... 100600423
230+
... 103047835
231+
... 101671026
232+
... 101553163
233+
... 103061847
234+
... 106891578
235+
... 102704958
236+
... 101792173
237+
... 101774925
238+
... 101408122
239+
... 101535199
240+
... 101315485
241+
... 101880603
242+
... 101711471
243+
... 101753309
244+
... 101822442
245+
... 102059291
246+
... 120263565
247+
... 102058377
248+
... 102058506
249+
... 102060367
250+
... 101785453
251+
... 101895086
252+
... 101909790
253+
... 100604752
254+
... 000604752
255+
... 111983517
256+
... 112946918
257+
... 101310933
258+
... 111954363
259+
...
260+
... '''
261+
>>> [x for x in numbers.splitlines() if x and not tin.is_valid(x)]
262+
[]

0 commit comments

Comments
 (0)