8000 Add support for North Macedonia TIN · unho/python-stdnum@2c92234 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2c92234

Browse files
committed
Add support for North Macedonia TIN
Note that this is implementation is mostly based on unofficial sources describing the format, which match the hundreds of examples found online. Also note that the algorithm for the check digit was tested on all found examples, and it doesn't work for all of them, despite those failing examples don't seem to be valid according to the official online search. Closes arthurdejong#222.
1 parent 2907676 commit 2c92234

File tree

3 files changed

+577
-0
lines changed

3 files changed

+577
-0
lines changed

stdnum/mk/__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 North Macedonia 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 North Macedonia numbers."""
22+
23+
# provide aliases
24+
from stdnum.mk import edb as vat # noqa: F401

stdnum/mk/edb.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# edb.py - functions for handling North Macedonia EDB 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+
"""ЕДБ (Едниствен Даночен Број, North Macedonia tax number).
22+
23+
This number consists of 13 digits, sometimes with an additional "MK" prefix.
24+
25+
More information:
26+
27+
* http://www.ujp.gov.mk/en
28+
* https://forum.it.mk/threads/modularna-kontrola-na-embg-edb-dbs-itn.15663/?__cf_chl_tk=Op2PaEIauip6Z.ZjvhP897O8gRVAwe5CDAVTpjx1sEo-1663498930-0-gaNycGzNCRE#post-187048
29+
30+
>>> validate('4030000375897')
31+
'4030000375897'
32+
>>> validate('МК 4020990116747')
33+
'4020990116747'
34+
>>> validate('MK4057009501106')
35+
'4057009501106'
36+
>>> validate('МК4030006603425')
37+
'4030006603425'
38+
>>> validate('12345')
39+
Traceback (most recent call last):
40+
...
41+
InvalidLength: ...
42+
>>> validate('1234567890XYZ')
43+
Traceback (most recent call last):
44+
...
45+
InvalidFormat: ...
46+
>>> validate('4030000375890')
47+
Traceback (most recent call last):
48+
...
49+
InvalidChecksum: ...
50+
>>> format('4030000375897')
51+
'4030000375897'
52+
>>> format('МК 4020990116747')
53+
'4020990116747'
54+
>>> format('MK4057009501106')
55+
'4057009501106'
56+
>>> format('МК4030006603425')
57+
'4030006603425'
58+
""" # noqa: E501
59+
60+
from stdnum.exceptions import *
61+
from stdnum.util import clean, isdigits
62+
63+
64+
def compact(number):
65+
"""Convert the number to the minimal representation.
66+
67+
This strips the number of any valid separators and removes surrounding
68+
whitespace.
69+
"""
70+
number = clean(number, ' -').upper().strip()
71+
if number.startswith('MK') or number.startswith('МК'):
72+
return number[2:]
73+
return number
74+
75+
76+
def calc_check_digit(number):
77+
"""Calculate the check digit."""
78+
weights = (7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
79+
total = sum(int(n) * w for n, w in zip(number, weights))
80+
return str((-total % 11) % 10)
81+
82+
83+
def validate(number):
84+
"""Check if the number is a valid North Macedonia ЕДБ number.
85+
86+
This checks the length, formatting and check digit.
87+
"""
88+
number = compact(number)
89+
if len(number) != 13:
90+
raise InvalidLength()
91+
if not isdigits(number):
92+
raise InvalidFormat()
93+
if number[-1] != calc_check_digit(number):
94+
raise InvalidChecksum()
95+
return number
96+
97+
98+
def is_valid(number):
99+
"""Check if the number is a valid North Macedonia ЕДБ number."""
100+
try:
101+
return bool(validate(number))
102+
except ValidationError:
103< 4FEC span class="diff-text-marker">+
return False
104+
105+
106+
def format(number):
107+
"""Reformat the number to the standard presentation format."""
108+
return compact(number)

0 commit comments

Comments
 (0)
0