Skip to content

Commit 99a374c

Browse files
authored
feat: ae trn validation added (#40)
UAE has TRN(Tax Registration Number) to submit vat. A person can have TRN to submit VAT on invoiced income. Business needs to have TRN to be registered. ref: https://www.cleartax.com/ae/trn-verification-uae
1 parent 8ec537b commit 99a374c

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

stdnum/ae/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from stdnum.ae import trn as vat # noqa: F401
2+
from stdnum.ae import trn as business_tin # noqa: F401
3+
from stdnum.ae import trn as personal_tin # noqa: F401

stdnum/ae/trn.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# trn.py - functions for handling UAE TRN numbers
2+
# ref:
3+
# https://www.cleartax.com/ae/trn-verification-uae
4+
# https://tax.gov.ae/en/services/vat.registration.aspx
5+
6+
"""TRN (Tax Registration Number)
7+
8+
The TRN is a 15 digit number.
9+
10+
>>> validate('123456789012345')
11+
'123456789012345'
12+
>>> validate('1234-5678901-2345')
13+
'123456789012345'
14+
>>> validate('1234567890123456')
15+
Traceback (most recent call last):
16+
...
17+
stdnum.exceptions.InvalidLength: The number has an invalid length.
18+
"""
19+
20+
import re
21+
22+
from stdnum.exceptions import *
23+
from stdnum.util import clean
24+
25+
26+
_trn_re = re.compile(r'^\d{15}$')
27+
28+
29+
def compact(number):
30+
"""Convert the number to the minimal representation. This strips the
31+
number of any valid separators and removes surrounding whitespace."""
32+
return clean(number, ' -').strip()
33+
34+
35+
def validate(number):
36+
"""Check if the number is a valid TRN. This checks the length and format."""
37+
number = compact(number)
38+
if len(number) != 15:
39+
raise InvalidLength()
40+
if not _trn_re.match(number):
41+
raise InvalidFormat()
42+
return number
43+
44+
45+
def is_valid(number):
46+
"""Check if the number is a valid TRN."""
47+
try:
48+
return bool(validate(number))
49+
except ValidationError:
50+
return False

tests/test_ae_trn.doctest

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
>>> from stdnum.ae import trn
2+
3+
>>> trn.validate('123456789012345')
4+
'123456789012345'
5+
>>> trn.is_valid('123456789012345')
6+
True
7+
>>> trn.validate('1234-5678901-2345')
8+
'123456789012345'
9+
>>> trn.is_valid('1234-5678901-2345')
10+
True
11+
>>> trn.validate(' 1234-5678901-2345 ')
12+
'123456789012345'
13+
>>> trn.is_valid(' 1234-5678901-2345 ')
14+
True
15+
>>> trn.validate(' 1234-5678901-2 345 ')
16+
'123456789012345'
17+
>>> trn.is_valid(' 1234-5678901-2 345 ')
18+
True
19+
>>> trn.validate('1234567890123456')
20+
Traceback (most recent call last):
21+
...
22+
stdnum.exceptions.InvalidLength: The number has an invalid length.
23+
>>> trn.is_valid('1234567890123456')
24+
False
25+
>>> trn.validate('12345678901234A')
26+
Traceback (most recent call last):
27+
...
28+
stdnum.exceptions.InvalidFormat: The number has an invalid format.
29+
>>> trn.is_valid('1234-567890123456')
30+
False

0 commit comments

Comments
 (0)