Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/validators/i18n/es.py: 30%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

40 statements  

1"""Spain.""" 

2 

3# standard 

4from typing import Dict 

5 

6# local 

7from validators.utils import validator 

8 

9 

10def _nif_nie_validation(value: str, number_by_letter: Dict[str, str]): 

11 """Validate if the doi is a NIF or a NIE.""" 

12 if len(value) != 9: 

13 return False 

14 value = value.upper() 

15 table = "TRWAGMYFPDXBNJZSQVHLCKE" 

16 # If it is not a DNI, convert the first 

17 # letter to the corresponding digit 

18 numbers = number_by_letter.get(value[0], value[0]) + value[1:8] 

19 # doi[8] is control 

20 return numbers.isdigit() and value[8] == table[int(numbers) % 23] 

21 

22 

23@validator 

24def es_cif(value: str, /): 

25 """Validate a Spanish CIF. 

26 

27 Each company in Spain prior to 2008 had a distinct CIF and has been 

28 discontinued. For more information see [wikipedia.org/cif][1]. 

29 

30 The new replacement is to use NIF for absolutely everything. The issue is 

31 that there are "types" of NIFs now: company, person [citizen or resident] 

32 all distinguished by the first character of the DOI. For this reason we 

33 will continue to call CIFs NIFs, that are used for companies. 

34 

35 This validator is based on [generadordni.es][2]. 

36 

37 [1]: https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal 

38 [2]: https://generadordni.es/ 

39 

40 Examples: 

41 >>> es_cif('B25162520') 

42 True 

43 >>> es_cif('B25162529') 

44 ValidationError(func=es_cif, args={'value': 'B25162529'}) 

45 

46 Args: 

47 value: 

48 DOI string which is to be validated. 

49 

50 Returns: 

51 (Literal[True]): If `value` is a valid DOI string. 

52 (ValidationError): If `value` is an invalid DOI string. 

53 """ 

54 if not value or len(value) != 9: 

55 return False 

56 value = value.upper() 

57 table = "JABCDEFGHI" 

58 first_chr = value[0] 

59 doi_body = value[1:8] 

60 control = value[8] 

61 if not doi_body.isdigit(): 

62 return False 

63 res = ( 

64 10 

65 - sum( 

66 # Multiply each positionally even doi 

67 # digit by 2 and sum it all together 

68 sum(map(int, str(int(char) * 2))) if index % 2 == 0 else int(char) 

69 for index, char in enumerate(doi_body) 

70 ) 

71 % 10 

72 ) % 10 

73 if first_chr in "ABEH": # Number type 

74 return str(res) == control 

75 if first_chr in "PSQW": # Letter type 

76 return table[res] == control 

77 return control in {str(res), table[res]} if first_chr in "CDFGJNRUV" else False 

78 

79 

80@validator 

81def es_nif(value: str, /): 

82 """Validate a Spanish NIF. 

83 

84 Each entity, be it person or company in Spain has a distinct NIF. Since 

85 we've designated CIF to be a company NIF, this NIF is only for person. 

86 For more information see [wikipedia.org/nif][1]. This validator 

87 is based on [generadordni.es][2]. 

88 

89 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal 

90 [2]: https://generadordni.es/ 

91 

92 Examples: 

93 >>> es_nif('26643189N') 

94 True 

95 >>> es_nif('26643189X') 

96 ValidationError(func=es_nif, args={'value': '26643189X'}) 

97 

98 Args: 

99 value: 

100 DOI string which is to be validated. 

101 

102 Returns: 

103 (Literal[True]): If `value` is a valid DOI string. 

104 (ValidationError): If `value` is an invalid DOI string. 

105 """ 

106 number_by_letter = {"L": "0", "M": "0", "K": "0"} 

107 return _nif_nie_validation(value, number_by_letter) 

108 

109 

110@validator 

111def es_nie(value: str, /): 

112 """Validate a Spanish NIE. 

113 

114 The NIE is a tax identification number in Spain, known in Spanish 

115 as the NIE, or more formally the Número de identidad de extranjero. 

116 For more information see [wikipedia.org/nie][1]. This validator 

117 is based on [generadordni.es][2]. 

118 

119 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero 

120 [2]: https://generadordni.es/ 

121 

122 Examples: 

123 >>> es_nie('X0095892M') 

124 True 

125 >>> es_nie('X0095892X') 

126 ValidationError(func=es_nie, args={'value': 'X0095892X'}) 

127 

128 Args: 

129 value: 

130 DOI string which is to be validated. 

131 

132 Returns: 

133 (Literal[True]): If `value` is a valid DOI string. 

134 (ValidationError): If `value` is an invalid DOI string. 

135 """ 

136 number_by_letter = {"X": "0", "Y": "1", "Z": "2"} 

137 # NIE must must start with X Y or Z 

138 if value and value[0] in number_by_letter: 

139 return _nif_nie_validation(value, number_by_letter) 

140 return False 

141 

142 

143@validator 

144def es_doi(value: str, /): 

145 """Validate a Spanish DOI. 

146 

147 A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. 

148 For more information see [wikipedia.org/doi][1]. This validator 

149 is based on [generadordni.es][2]. 

150 

151 [1]: https://es.wikipedia.org/wiki/Identificador_de_objeto_digital 

152 [2]: https://generadordni.es/ 

153 

154 Examples: 

155 >>> es_doi('X0095892M') 

156 True 

157 >>> es_doi('X0095892X') 

158 ValidationError(func=es_doi, args={'value': 'X0095892X'}) 

159 

160 Args: 

161 value: 

162 DOI string which is to be validated. 

163 

164 Returns: 

165 (Literal[True]): If `value` is a valid DOI string. 

166 (ValidationError): If `value` is an invalid DOI string. 

167 """ 

168 return es_nie(value) or es_nif(value) or es_cif(value)