Skip to content

Commit bb746a5

Browse files
committed
Add support for Cape Verde TIN
Fixes arthurdejong#387
1 parent 6d366e3 commit bb746a5

File tree

3 files changed

+408
-0
lines changed

3 files changed

+408
-0
lines changed

stdnum/cv/__init__.py

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

stdnum/cv/nif.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# nif.py - functions for handling Cape Verde NIF 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+
"""NIF (Número de Identificação Fiscal, Cape Verde tax number).
22+
23+
This number consists of 9 digits, sometimes separated into three groups with
24+
three digits each to make it easier to read, like XXX XXX XXX.
25+
26+
The first digit indicates the type of person:
27+
28+
* 1: Singular person, either resident or non resident.
29+
* 2: Companies.
30+
* 3: National entities.
31+
* 4: International entities.
32+
* 5: Other entities.
33+
34+
The following six digits are either:
35+
36+
* The Bilhete de Identidade number, for singular resident persons, or
37+
* A sequence automatically assigned, for all other cases.
38+
39+
The last two digits are control digits.
40+
41+
More information:
42+
43+
* https://portondinosilhas.gov.cv/images/igrp-portal/img/documentos/EA834694B09A15FAE044002128A60A02.pdf
44+
* https://www.mf.gov.cv/documents/54571/273413/adenda_esclarecimentos_pdfs.pdf
45+
46+
47+
>>> validate('200129775')
48+
'200129775'
49+
>>> validate('200 144 731')
50+
'200144731'
51+
>>> validate('253.656.575')
52+
'253656575'
53+
>>> validate('12345')
54+
Traceback (most recent call last):
55+
...
56+
InvalidLength: ...
57+
>>> validate('VV3456789')
58+
Traceback (most recent call last):
59+
...
60+
InvalidFormat: ...
61+
>>> validate('923456789')
62+
Traceback (most recent call last):
63+
...
64+
InvalidComponent: ...
65+
>>> format('200 144 731')
66+
'200144731'
67+
""" # noqa: E501
68+
69+
from stdnum.exceptions import *
70+
from stdnum.util import clean, isdigits
71+
72+
73+
def compact(number):
74+
"""Convert the number to the minimal representation.
75+
76+
This strips the number of any valid separators and removes surrounding
77+
whitespace.
78+
"""
79+
return clean(number, ' -.').strip()
80+
81+
82+
def validate(number):
83+
"""Check if the number is a valid Cape Verde NIF number.
84+
85+
This checks the length and formatting.
86+
"""
87+
number = compact(number)
88+
if len(number) != 9:
89+
raise InvalidLength()
90+
if not isdigits(number):
91+
raise InvalidFormat()
92+
if number[0] not in ('1', '2', '3', '4', '5'):
93+
raise InvalidComponent()
94+
return number
95+
96+
97+
def is_valid(number):
98+
"""Check if the number is a valid Cape Verde NIF number."""
99+
try:
100+
return bool(validate(number))
101+
except ValidationError:
102+
return False
103+
104+
105+
def format(number):
106+
"""Reformat the number to the standard presentation format."""
107+
return compact(number)

0 commit comments

Comments
 (0)