Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/validators/i18n/es.py: 28%
40 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:08 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:08 +0000
1"""Spain."""
2# -*- coding: utf-8 -*-
4# standard
5from typing import Dict, Set
7# local
8from validators.utils import validator
11def _nif_nie_validation(value: str, number_by_letter: Dict[str, str], special_cases: Set[str]):
12 """Validate if the doi is a NIF or a NIE."""
13 if value in special_cases or len(value) != 9:
14 return False
15 value = value.upper()
16 table = "TRWAGMYFPDXBNJZSQVHLCKE"
17 # If it is not a DNI, convert the first
18 # letter to the corresponding digit
19 numbers = number_by_letter.get(value[0], value[0]) + value[1:8]
20 # doi[8] is control
21 return numbers.isdigit() and value[8] == table[int(numbers) % 23]
24@validator
25def es_cif(value: str, /):
26 """Validate a Spanish CIF.
28 Each company in Spain prior to 2008 had a distinct CIF and has been
29 discontinued. For more information see [wikipedia.org/cif][1].
31 The new replacement is to use NIF for absolutely everything. The issue is
32 that there are "types" of NIFs now: company, person [citizen or resident]
33 all distinguished by the first character of the DOI. For this reason we
34 will continue to call CIFs NIFs, that are used for companies.
36 This validator is based on [generadordni.es][2].
38 [1]: https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
39 [2]: https://generadordni.es/
41 Examples:
42 >>> es_cif('B25162520')
43 # Output: True
44 >>> es_cif('B25162529')
45 # Output: ValidationFailure(func=es_cif, args=...)
47 Args:
48 value:
49 DOI string which is to be validated.
51 Returns:
52 (Literal[True]):
53 If `value` is a valid DOI string.
54 (ValidationFailure):
55 If `value` is an invalid DOI string.
57 > *New in version 0.13.0*.
58 """
59 if not value or len(value) != 9:
60 return False
61 value = value.upper()
62 table = "JABCDEFGHI"
63 first_chr = value[0]
64 doi_body = value[1:8]
65 control = value[8]
66 if not doi_body.isdigit():
67 return False
68 res = (
69 10
70 - sum(
71 # Multiply each positionally even doi
72 # digit by 2 and sum it all together
73 sum(map(int, str(int(char) * 2))) if index % 2 == 0 else int(char)
74 for index, char in enumerate(doi_body)
75 )
76 % 10
77 ) % 10
78 if first_chr in "ABEH": # Number type
79 return str(res) == control
80 if first_chr in "PSQW": # Letter type
81 return table[res] == control
82 return control in {str(res), table[res]} if first_chr in "CDFGJNRUV" else False
85@validator
86def es_nif(value: str, /):
87 """Validate a Spanish NIF.
89 Each entity, be it person or company in Spain has a distinct NIF. Since
90 we've designated CIF to be a company NIF, this NIF is only for person.
91 For more information see [wikipedia.org/nif][1]. This validator
92 is based on [generadordni.es][2].
94 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal
95 [2]: https://generadordni.es/
97 Examples:
98 >>> es_nif('26643189N')
99 # Output: True
100 >>> es_nif('26643189X')
101 # Output: ValidationFailure(func=es_nif, args=...)
103 Args:
104 value:
105 DOI string which is to be validated.
107 Returns:
108 (Literal[True]):
109 If `value` is a valid DOI string.
110 (ValidationFailure):
111 If `value` is an invalid DOI string.
113 > *New in version 0.13.0*.
114 """
115 number_by_letter = {"L": "0", "M": "0", "K": "0"}
116 special_cases = {"X0000000T", "00000000T", "00000001R"}
117 return _nif_nie_validation(value, number_by_letter, special_cases)
120@validator
121def es_nie(value: str, /):
122 """Validate a Spanish NIE.
124 The NIE is a tax identification number in Spain, known in Spanish
125 as the NIE, or more formally the Número de identidad de extranjero.
126 For more information see [wikipedia.org/nie][1]. This validator
127 is based on [generadordni.es][2].
129 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero
130 [2]: https://generadordni.es/
132 Examples:
133 >>> es_nie('X0095892M')
134 # Output: True
135 >>> es_nie('X0095892X')
136 # Output: ValidationFailure(func=es_nie, args=...)
138 Args:
139 value:
140 DOI string which is to be validated.
142 Returns:
143 (Literal[True]):
144 If `value` is a valid DOI string.
145 (ValidationFailure):
146 If `value` is an invalid DOI string.
148 > *New in version 0.13.0*.
149 """
150 number_by_letter = {"X": "0", "Y": "1", "Z": "2"}
151 # NIE must must start with X Y or Z
152 if value and value[0] in number_by_letter:
153 return _nif_nie_validation(value, number_by_letter, {"X0000000T"})
154 return False
157@validator
158def es_doi(value: str, /):
159 """Validate a Spanish DOI.
161 A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID.
162 For more information see [wikipedia.org/doi][1]. This validator
163 is based on [generadordni.es][2].
165 [1]: https://es.wikipedia.org/wiki/Identificador_de_objeto_digital
166 [2]: https://generadordni.es/
168 Examples:
169 >>> es_doi('X0095892M')
170 # Output: True
171 >>> es_doi('X0095892X')
172 # Output: ValidationFailure(func=es_doi, args=...)
174 Args:
175 value:
176 DOI string which is to be validated.
178 Returns:
179 (Literal[True]):
180 If `value` is a valid DOI string.
181 (ValidationFailure):
182 If `value` is an invalid DOI string.
184 > *New in version 0.13.0*.
185 """
186 return es_nie(value) or es_nif(value) or es_cif(value)