Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
50.85% |
60 / 118 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
EUVATVies | |
50.85% |
60 / 118 |
|
0.00% |
0 / 3 |
199.57 | |
0.00% |
0 / 1 |
__construct | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
validate | |
86.21% |
25 / 29 |
|
0.00% |
0 / 1 |
6.09 | |||
validateQualified | |
43.55% |
27 / 62 |
|
0.00% |
0 / 1 |
100.34 | |||
parseResponse | |
29.63% |
8 / 27 |
|
0.00% |
0 / 1 |
37.23 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\Api\EUVAT |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\Api\EUVAT; |
16 | |
17 | use phpOMS\Message\Http\HttpRequest; |
18 | use phpOMS\Message\Http\RequestMethod; |
19 | use phpOMS\Message\Http\Rest; |
20 | use phpOMS\Uri\HttpUri; |
21 | |
22 | /** |
23 | * Check EU VAT. |
24 | * |
25 | * @package phpOMS\Api\EUVAT |
26 | * @license OMS License 2.0 |
27 | * @link https://jingga.app |
28 | * @since 1.0.0 |
29 | */ |
30 | final class EUVATVies implements EUVATInterface |
31 | { |
32 | /** |
33 | * Constructor. |
34 | * |
35 | * @since 1.0.0 |
36 | * @codeCoverageIgnore |
37 | */ |
38 | private function __construct() |
39 | { |
40 | } |
41 | |
42 | /** |
43 | * {@inheritdoc} |
44 | */ |
45 | public static function validate(string $otherVAT, string $ownVAT = '') : array |
46 | { |
47 | $result = [ |
48 | 'status' => -1, |
49 | 'vat' => 'B', |
50 | 'name' => '', |
51 | 'city' => '', |
52 | 'postal' => '', |
53 | 'address' => '', |
54 | 'body' => '', |
55 | ]; |
56 | |
57 | if (empty($otherVAT)) { |
58 | return $result; |
59 | } |
60 | |
61 | $request = new HttpRequest( |
62 | new HttpUri( |
63 | 'https://ec.europa.eu/taxation_customs/vies/rest-api/ms/' . \substr($otherVAT, 0, 2) . '/vat/' . \substr($otherVAT, 2) . ( |
64 | $ownVAT !== '' ? '?requesterMemberStateCode=' . \substr($ownVAT, 0, 2) . '&requesterNumber=' . \substr($ownVAT, 2) : '' |
65 | ) |
66 | ) |
67 | ); |
68 | $request->setMethod(RequestMethod::GET); |
69 | |
70 | try { |
71 | $body = Rest::request($request)->getBody(); |
72 | $result['body'] = $body; |
73 | |
74 | /** @var array $json */ |
75 | $json = \json_decode($body, true); |
76 | if ($json === false) { |
77 | return $result; |
78 | } |
79 | |
80 | $result = \array_merge($result, self::parseResponse($json)); |
81 | |
82 | $result['status'] = $json['userError'] === 'VALID' ? 0 : -1; |
83 | } catch (\Throwable $_) { |
84 | return $result; |
85 | } |
86 | |
87 | return $result; |
88 | } |
89 | |
90 | /** |
91 | * {@inheritdoc} |
92 | */ |
93 | public static function validateQualified( |
94 | string $otherVAT, |
95 | string $ownVAT, |
96 | string $otherName, |
97 | string $otherCity, |
98 | string $otherPostal, |
99 | string $otherStreet |
100 | ) : array |
101 | { |
102 | $result = [ |
103 | 'status' => -1, |
104 | 'vat' => 'B', |
105 | 'name' => 'C', |
106 | 'city' => 'C', |
107 | 'postal' => 'C', |
108 | 'address' => 'C', |
109 | 'body' => '', |
110 | ]; |
111 | |
112 | if (empty($otherVAT)) { |
113 | return $result; |
114 | } |
115 | |
116 | $request = new HttpRequest( |
117 | new HttpUri( |
118 | 'https://ec.europa.eu/taxation_customs/vies/rest-api/ms/' . \substr($otherVAT, 0, 2) . '/vat/' . \substr($otherVAT, 2) . ( |
119 | $ownVAT !== '' |
120 | ? '?requesterMemberStateCode=' . \substr($ownVAT, 0, 2) . '&requesterNumber=' . \substr($ownVAT, 2) |
121 | : '' |
122 | ) |
123 | ) |
124 | ); |
125 | $request->setMethod(RequestMethod::GET); |
126 | |
127 | try { |
128 | $body = Rest::request($request)->getBody(); |
129 | $result['body'] = $body; |
130 | |
131 | /** @var array $json */ |
132 | $json = \json_decode($body, true); |
133 | if ($json === false) { |
134 | return $result; |
135 | } |
136 | |
137 | $result = \array_merge($result, self::parseResponse($json)); |
138 | |
139 | if ($otherName === '') { |
140 | $result['name'] = 'C'; |
141 | } elseif ((\stripos($result['name'], $otherName) !== false |
142 | && \strlen($otherName) / \strlen($result['name']) > 0.8) |
143 | || \levenshtein($otherName, $result['name']) / \strlen($result['name']) < 0.2 |
144 | ) { |
145 | $result['name'] = 'A'; |
146 | } elseif ($result['name'] === '') { |
147 | $result['name'] = 'C'; |
148 | } else { |
149 | $result['name'] = 'B'; |
150 | } |
151 | |
152 | if ($otherCity === '') { |
153 | $result['city'] = 'D'; |
154 | } elseif (\stripos($result['city'], $otherCity) !== false) { |
155 | $result['city'] = 'A'; |
156 | } elseif ($result['city'] === '') { |
157 | $result['city'] = 'C'; |
158 | } else { |
159 | $result['city'] = 'B'; |
160 | } |
161 | |
162 | if ($otherPostal === '') { |
163 | $result['postal'] = 'D'; |
164 | } elseif (\stripos($result['postal'], $otherPostal) !== false) { |
165 | $result['postal'] = 'A'; |
166 | } elseif ($result['postal'] === '') { |
167 | $result['postal'] = 'C'; |
168 | } else { |
169 | $result['postal'] = 'B'; |
170 | } |
171 | |
172 | if ($otherStreet === '') { |
173 | $result['address'] = 'D'; |
174 | } elseif (\stripos($result['address'], $otherStreet) !== false |
175 | && \levenshtein($otherStreet, $result['address'], 0) / \strlen($result['address']) < 0.2 |
176 | ) { |
177 | $result['address'] = 'A'; |
178 | } elseif ($result['address'] === '') { |
179 | $result['address'] = 'C'; |
180 | } else { |
181 | $result['address'] = 'B'; |
182 | } |
183 | |
184 | $result['status'] = $json['userError'] === 'VALID' ? 0 : -1; |
185 | } catch (\Throwable $_) { |
186 | return $result; |
187 | } |
188 | |
189 | return $result; |
190 | } |
191 | |
192 | /** |
193 | * Parse response. |
194 | * |
195 | * @param array $json JSON response |
196 | * |
197 | * @return array |
198 | * |
199 | * @since 1.0.0 |
200 | */ |
201 | private static function parseResponse(array $json) : array |
202 | { |
203 | $result = [ |
204 | 'vat' => '', |
205 | 'name' => '', |
206 | 'city' => '', |
207 | 'postal' => '', |
208 | 'address' => '', |
209 | ]; |
210 | |
211 | $result['vat'] = $json['isValid'] ? 'A' : 'B'; |
212 | $result['name'] = $json['isValid']; |
213 | |
214 | $result['city'] = \stripos($json['address'], "\n") !== false |
215 | ? \substr($json['address'], \stripos($json['address'], "\n") + 1) |
216 | : ''; |
217 | |
218 | $result['postal'] = \stripos($json['address'], "\n") !== false |
219 | ? \substr( |
220 | $json['address'], |
221 | \stripos($json['address'], "\n") + 1, |
222 | \stripos($json['address'], ' ', \stripos($json['address'], "\n")) - \stripos($json['address'], "\n") - 1 |
223 | ) |
224 | : ''; |
225 | |
226 | $result['address'] = \stripos($json['address'], "\n") !== false |
227 | ? \substr($json['address'], 0, \stripos($json['address'], "\n") - 1) |
228 | : $json['address']; |
229 | |
230 | $result['name'] = $result['name'] === '---' ? '' : $result['name']; |
231 | $result['city'] = $result['city'] === '---' ? '' : $result['city']; |
232 | $result['postal'] = $result['postal'] === '---' ? '' : $result['postal']; |
233 | $result['address'] = $result['address'] === '---' ? '' : $result['address']; |
234 | |
235 | return $result; |
236 | } |
237 | } |