Skip to content

Commit e0332b7

Browse files
committed
Add TIN number for Bangladesh
Fixes arthurdejong#327
1 parent 38e3be3 commit e0332b7

File tree

3 files changed

+260
-0
lines changed

3 files changed

+260
-0
lines changed

stdnum/bd/__init__.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# __init__.py - collection of Bangladesh 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 Bangladesh numbers."""
22+
23+
# provide aliases
24+
from stdnum.bd import etin as vat # noqa: F401

stdnum/bd/etin.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# etin.py - functions for handling Bangladesh e-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+
"""e-TIN (Electronic Taxpayer's Identification Number, Bangladesh tax number).
22+
23+
This number consists of 12 digits.
24+
25+
More information:
26+
27+
* http://bdlaws.minlaw.gov.bd/act-672/section-34615.html
28+
* https://www.incometax.gov.bd/TINHome
29+
* https://royandassociates.com.bd/how-to-register-for-e-tin-certificate-in-bangladesh/
30+
* https://tin-check.com/en/bangladesh/
31+
32+
>>> validate('224187378587')
33+
'224187378587'
34+
>>> validate('12345')
35+
Traceback (most recent call last):
36+
...
37+
InvalidLength: ...
38+
>>> format('224187378587')
39+
'224187378587'
40+
""" # noqa: E501
41+
42+
from stdnum.exceptions import *
43+
from stdnum.util import clean, isdigits
44+
45+
46+
def compact(number):
47+
"""Convert the number to the minimal representation.
48+
49+
This strips the number of any valid separators and removes surrounding
50+
whitespace.
51+
"""
52+
return clean(number, ' -').strip()
53+
54+
55+
def validate(number):
56+
"""Check if the number is a valid Bangladesh e-TIN number.
57+
58+
This checks the length and formatting.
59+
"""
60+
number = compact(number)
61+
if len(number) != 12:
62+
raise InvalidLength()
63+
if not isdigits(number):
64+
raise InvalidFormat()
65+
return number
66+
67+
68+
def is_valid(number):
69+
"""Check if the number is a valid Bangladesh e-TIN number."""
70+
try:
71+
return bool(validate(number))
72+
except ValidationError:
73+
return False
74+
75+
76+
def format(number):
77+
"""Reformat the number to the standard presentation format."""
78+
return compact(number)

tests/test_bd_etin.doctest

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
test_bd_etin.doctest - more detailed doctests for stdnum.bd.etin 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.bd.etin 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.bd import etin
26+
27+
28+
Tests for some corner cases.
29+
30+
>>> etin.validate('224187378587')
31+
'224187378587'
32+
>>> etin.validate('12345')
33+
Traceback (most recent call last):
34+
...
35+
InvalidLength: ...
36+
>>> etin.validate('1234567890XX')
37+
Traceback (most recent call last):
38+
...
39+
InvalidFormat: ...
40+
>>> etin.format('224187378587')
41+
'224187378587'
42+
43+
44+
These have been found online and should all be valid numbers.
45+
46+
>>> numbers = '''
47+
...
48+
... 224187378587
49+
... 135055865054
50+
... 738330325591
51+
... 277916626006
52+
... 681988811545
53+
... 267962119864
54+
... 339698563430
55+
... 520540168296
56+
... 165536913384
57+
... 316174170274
58+
... 131551835650
59+
... 481375629149
60+
... 767520992761
61+
... 651069864924
62+
... 183780859375
63+
... 532529995018
64+
... 176564302526
65+
... 832273574406
66+
... 637043541293
67+
... 653402788766
68+
... 259574727994
69+
... 160874128026
70+
... 284120567875
71+
... 193190124102
72+
... 431261923476
73+
... 646693455577
74+
... 166768321166
75+
... 777596901240
76+
... 414877819850
77+
... 635337482532
78+
... 619068451149
79+
... 723377852860
80+
... 570789269501
81+
... 165536913384
82+
... 365777579468
83+
... 797905950605
84+
... 295475338492
85+
... 439442745537
86+
... 164533974718
87+
... 118701528309
88+
... 129369223588
89+
... 114403298089
90+
... 198060384543
91+
... 661881651462
92+
... 757699520135
93+
... 350175670404
94+
... 544218590837
95+
... 639216748212
96+
... 350175670404
97+
... 727126527155
98+
... 738330325591
99+
... 694411411108
100+
... 344847223347
101+
... 394777319395
102+
... 193602721035
103+
... 443583654331
104+
... 123562770715
105+
... 581975497462
106+
... 172342737380
107+
... 427058738130
108+
... 621606361842
109+
... 836773433583
110+
... 723775721753
111+
... 229193339950
112+
... 518389342914
113+
... 599652154463
114+
... 499508441184
115+
... 854716207710
116+
... 827328109457
117+
... 530068670685
118+
... 448245442372
119+
... 185171632448
120+
... 150261504838
121+
... 441133295537
122+
... 314917396858
123+
... 446381915223
124+
... 834323463643
125+
... 232954564554
126+
... 453961956038
127+
... 592394697235
128+
... 320623792282
129+
... 272768451190
130+
... 277916626006
131+
... 431117397300
132+
... 161231359425
133+
... 134518668890
134+
... 160951299512
135+
... 132006154756
136+
... 181118834634
137+
... 297396592589
138+
... 473613974848
139+
... 333983392178
140+
... 465337943663
141+
... 286937923024
142+
... 496902985207
143+
... 143462765792
144+
... 763686958372
145+
... 864865842903
146+
... 630477546927
147+
... 144050147394
148+
... 481375629149
149+
... 733743131344
150+
... 768947979306
151+
... 457158218470
152+
... 820797987002
153+
... 299334919055
154+
... 149986200224
155+
...
156+
... '''
157+
>>> [x for x in numbers.splitlines() if x and not etin.is_valid(x)]
158+
[]

0 commit comments

Comments
 (0)