Skip to content

Commit 3db826c

Browse files
committed
Add Albanian NIPT (VAT) number
Partially based on the implementation in the vatnumber module. Some valid numbers appear to start with an L so those are allowed as well.
1 parent 88d1af3 commit 3db826c

File tree

3 files changed

+282
-0
lines changed

3 files changed

+282
-0
lines changed

stdnum/al/__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 Albanian numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2015 Arthur de Jong
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 Albanian numbers."""
22+
23+
# provide vat as an alias
24+
from stdnum.al import nipt as vat

stdnum/al/nipt.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# nipt.py - functions for handling Albanian VAT numbers
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2008-2011 Cédric Krier
5+
# Copyright (C) 2008-2011 B2CK
6+
# Copyright (C) 2015 Arthur de Jong
7+
#
8+
# This library is free software; you can redistribute it and/or
9+
# modify it under the terms of the GNU Lesser General Public
10+
# License as published by the Free Software Foundation; either
11+
# version 2.1 of the License, or (at your option) any later version.
12+
#
13+
# This library is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
# Lesser General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU Lesser General Public
19+
# License along with this library; if not, write to the Free Software
20+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21+
# 02110-1301 USA
22+
23+
"""NIPT (Numri i Identifikimit për Personin e Tatueshëm, Albanian VAT number).
24+
25+
The Albanian NIPT is a 10-digit number with the first and last character
26+
being letters.
27+
28+
>>> validate('AL J 91402501 L')
29+
'J91402501L'
30+
>>> validate('K22218003V')
31+
'K22218003V'
32+
>>> validate('(AL) J 91402501')
33+
Traceback (most recent call last):
34+
...
35+
InvalidLength: ...
36+
>>> validate('Z 22218003 V')
37+
Traceback (most recent call last):
38+
...
39+
InvalidFormat: ...
40+
"""
41+
42+
import re
43+
44+
from stdnum.exceptions import *
45+
from stdnum.util import clean
46+
47+
48+
# regular expression for matching number
49+
_nipt_re = re.compile('^[JKL][0-9]{8}[A-Z]$')
50+
51+
52+
def compact(number):
53+
"""Convert the number to the minimal representation. This strips the
54+
number of any valid separators and removes surrounding whitespace."""
55+
number = clean(number, ' ').upper().strip()
56+
if number.startswith('AL'):
57+
number = number[2:]
58+
if number.startswith('(AL)'):
59+
number = number[4:]
60+
return number
61+
62+
63+
def validate(number):
64+
"""Checks to see if the number provided is a valid VAT number. This
65+
checks the length and formatting."""
66+
number = compact(number)
67+
if len(number) != 10:
68+
raise InvalidLength()
69+
if not _nipt_re.match(number):
70+
raise InvalidFormat()
71+
return number
72+
73+
74+
def is_valid(number):
75+
"""Checks to see if the number provided is a valid VAT number. This
76+
checks the length and formatting."""
77+
try:
78+
return bool(validate(number))
79+
except ValidationError:
80+
return False

tests/test_al_nipt.doctest

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
test_al_nitp.doctest - more detailed doctests stdnum.al.nipt
2+
3+
Copyright (C) 2015 Arthur de Jong
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.al.nipt module.
22+
23+
>>> from stdnum.al import nipt
24+
>>> from stdnum.exceptions import *
25+
26+
27+
These have been found online and should all be valid numbers. There is also
28+
a validation service at
29+
http://www.qkr.gov.al/nrc/kerko_per_subjekt.aspx
30+
31+
>>> numbers = '''
32+
...
33+
... J 64103842 S
34+
... J 69102564 M
35+
... J 78311939 N
36+
... J 8291 6498 D
37+
... J 91402501 L
38+
... J 98624806 P
39+
... J61807017B
40+
... J61826022R
41+
... J61911008C
42+
... J61922018S
43+
... J61923008Q
44+
... J62903175S
45+
... J62903393F
46+
... J62903470T
47+
... J62903491S
48+
... J64103682L
49+
... J66702410U
50+
... J67902618M
51+
... J69405530G
52+
... J71824003C
53+
... J72603171B
54+
... J73706808B
55+
... J73721043Q
56+
... J74517201G
57+
... J77411245Q
58+
... J81314004P
59+
... J81402004E
60+
... J81508002V
61+
... J81804001C
62+
... J86526614T
63+
... J91305001Q
64+
... J91808007H
65+
... J92006014W
66+
... J92917219S
67+
... J93910409N
68+
... K 01725001F
69+
... K 02727202 O
70+
... K 11715005 L
71+
... K 22013001U
72+
... K 37507987 N
73+
... K 41316001 V
74+
... K 41424801 U
75+
... K 47905861 R
76+
... K 63005203 O
77+
... K 67204202 P
78+
... K 91426008 U
79+
... K11515001T
80+
... K11715005L
81+
... K12113002H
82+
... K14019001H
83+
... K21405003G
84+
... K21622001M
85+
... K22218003V
86+
... K26330201T
87+
... K31404025J
88+
... K31525146H
89+
... K31526056N
90+
... K31823059I
91+
... K31929010K
92+
... K32203501H
93+
... K32801430W
94+
... K33714725W
95+
... K34712418N
96+
... K36308746I
97+
... K36520204A
98+
... K42725403f
99+
... K46621201I
100+
... K51428013Q
101+
... K51518058O
102+
... K59418208E
103+
... K61710508W
104+
... K71903001A
105+
... K72410014H
106+
... K81427030E
107+
... K81428502L
108+
... K81618039O
109+
... K84508002F
110+
... K87101202A
111+
... K91725009J
112+
... K92402023O
113+
... L 21721005U
114+
... L 22614402 H
115+
... L01307052Q
116+
... L01510016S
117+
... L01622006F
118+
... L01909501I
119+
... L02003503P
120+
... L02023501H
121+
... L02226012N
122+
... L02602801H
123+
... L03321203G
124+
... L06426702Q
125+
... L06524402O
126+
... L06901403L
127+
... L06923204C
128+
... L07305201K
129+
... L08711201I
130+
... L09110504G
131+
... L11325024K
132+
... L11625013E
133+
... L11810502T
134+
... L11815018A
135+
... L12003021H
136+
... L12009010A
137+
... L12624002J
138+
... L13020404N
139+
... L14118803B
140+
... L14703202P
141+
... L21310054D
142+
... L21408015A
143+
... L21429502L
144+
... L21508023Q
145+
... L21923507N
146+
... L22201021E
147+
... L22203019C
148+
... L22804207O
149+
... L22825801P
150+
... L22902002B
151+
... L24006002V
152+
... L24018612J
153+
... L26311004G
154+
... L29616001A
155+
... L31511019E
156+
... L31911504A
157+
... L32210507A
158+
... L32319014A
159+
... L32522401O
160+
... L33117002J
161+
... L33318001M
162+
... L41309075A
163+
... L41320026E
164+
... L41410025S
165+
... L42008005H
166+
... L42115015G
167+
... L42206027K
168+
... L42307007E
169+
... L42710403A
170+
... L42720201A
171+
... L44119601E
172+
... L46812703Q
173+
... L47014204F
174+
... L48117101S
175+
...
176+
... '''
177+
>>> [x for x in numbers.splitlines() if x and not nipt.is_valid(x)]
178+
[]

0 commit comments

Comments
 (0)