Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like EcuadorIdentification often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EcuadorIdentification, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class EcuadorIdentification |
||
15 | { |
||
16 | /** |
||
17 | * Natural person ruc |
||
18 | */ |
||
19 | const NaturalPerson = 'NaturalPerson'; |
||
20 | |||
21 | /** |
||
22 | * Private company ruc |
||
23 | */ |
||
24 | const PrivateCompany = 'PrivateCompany'; |
||
25 | |||
26 | /** |
||
27 | * Public company ruc |
||
28 | */ |
||
29 | const PublicCompany = 'PublicCompany'; |
||
30 | |||
31 | /** |
||
32 | * Error encapsulator variable |
||
33 | * |
||
34 | * @var string |
||
35 | */ |
||
36 | private $error; |
||
37 | |||
38 | /** |
||
39 | * Number of provinces of Ecuador |
||
40 | * |
||
41 | * @var \Illuminate\Config\Repository |
||
42 | */ |
||
43 | private $provinces; |
||
44 | |||
45 | /** |
||
46 | * Length of the different types of identification |
||
47 | * |
||
48 | * @var array |
||
49 | */ |
||
50 | private $lenght; |
||
51 | |||
52 | /** |
||
53 | * Billing code for identification types |
||
54 | * |
||
55 | * @var array |
||
56 | */ |
||
57 | private $billingCode; |
||
58 | |||
59 | public function __construct() |
||
74 | |||
75 | /** |
||
76 | * Set Error |
||
77 | * |
||
78 | * @param string $error |
||
79 | */ |
||
80 | protected function setError(string $error): void |
||
84 | |||
85 | /** |
||
86 | * Get Error |
||
87 | * |
||
88 | * @return string |
||
89 | */ |
||
90 | public function getError(): string |
||
94 | |||
95 | /** |
||
96 | * Validates the Ecuadorian Identification Card |
||
97 | * |
||
98 | * @param string $number Number of Identification Card |
||
99 | * @return string|null |
||
100 | */ |
||
101 | public function validatePersonalIdentification($number) |
||
117 | |||
118 | /** |
||
119 | * Validates the Ecuadorian RUC of Natural Person |
||
120 | * |
||
121 | * @param string $number Number of RUC Natural Person |
||
122 | * @return string|null |
||
123 | */ |
||
124 | View Code Duplication | public function validateNaturalPersonRuc($number) |
|
141 | |||
142 | /** |
||
143 | * Validates the Ecuadorian RUC of Private Companies |
||
144 | * |
||
145 | * @param string $number Number of RUC Private Companies |
||
146 | * @return string|null |
||
147 | */ |
||
148 | View Code Duplication | public function validatePrivateCompanyRuc($number) |
|
165 | |||
166 | /** |
||
167 | * Validates the Ecuadorian RUC of Public Companies |
||
168 | * |
||
169 | * @param string $number Number of RUC Public Companies |
||
170 | * @return string|null |
||
171 | */ |
||
172 | View Code Duplication | public function validatePublicCompanyRuc($number) |
|
189 | |||
190 | /** |
||
191 | * Validates the Ecuadorian Final Consumer |
||
192 | * |
||
193 | * @param $number |
||
194 | * @return string|null |
||
195 | */ |
||
196 | public function validateFinalConsumer($number) |
||
211 | |||
212 | /** |
||
213 | * Validate that the number belongs to natural persons. |
||
214 | * |
||
215 | * @param $number |
||
216 | * @return string|null |
||
217 | */ |
||
218 | public function validateIsNaturalPersons($number) |
||
223 | |||
224 | /** |
||
225 | * Validate that the number belongs to juridical persons. |
||
226 | * |
||
227 | * @param $number |
||
228 | * @return string|null |
||
229 | */ |
||
230 | public function validateIsJuridicalPersons($number) |
||
235 | |||
236 | /** |
||
237 | * Validate the number with all types of documents. |
||
238 | * |
||
239 | * @param $number |
||
240 | * @return string|null |
||
241 | */ |
||
242 | public function validateAllIdentificatons($number) |
||
276 | |||
277 | /** |
||
278 | * Initial validation of the identification, not empty, only digits, not less than the given length. |
||
279 | * |
||
280 | * @param string $value CI or RUC |
||
281 | * @param int $len Number of characters required |
||
282 | * @return bool |
||
283 | * @throws EcuadorIdentificationException When the value is empty, when the value isn't digits and |
||
284 | * when the value doesn't have the required length |
||
285 | */ |
||
286 | private function initValidation($value, $len) |
||
302 | |||
303 | /** |
||
304 | * Validate the province code (first two numbers of CI/RUC) |
||
305 | * The first 2 positions correspond to the province where it was issued, |
||
306 | * so the first two numbers will not be greater than 24 or less than 1 |
||
307 | * |
||
308 | * @param string $value First two numbers of CI/RUC |
||
309 | * @return boolean |
||
310 | * @throws EcuadorIdentificationException When the province code is not between 1 and 24 |
||
311 | */ |
||
312 | private function provinceCodeValidation($value) |
||
320 | |||
321 | /** |
||
322 | * Valid the third digit |
||
323 | * |
||
324 | * It allows the third digit of the document to be valid. |
||
325 | * Depending on the type field (type of identification) validations are performed. |
||
326 | * |
||
327 | * NATURAL_PERSON |
||
328 | * For Certificates and RUC of natural persons the third digit is less than 6 so |
||
329 | * it must be between 0 and 5 (0,1,2,3,4,5) |
||
330 | * |
||
331 | * PRIVATE_COMPANY |
||
332 | * For RUC of private companies the third digit must be equal to 9. |
||
333 | * |
||
334 | * PUBLIC_COMPANY |
||
335 | * For RUC of public companies the third digit must be equal to 6. |
||
336 | * |
||
337 | * @param string $value Third digit of CI/RUC |
||
338 | * @param string $type Type of identifier |
||
339 | * @return boolean |
||
340 | * @throws EcuadorIdentificationException When it does not comply with the validation according to the type of identifier |
||
341 | */ |
||
342 | private function thirdDigitValidation($value, $type) |
||
370 | |||
371 | /** |
||
372 | * Validation of the last digits |
||
373 | * |
||
374 | * Public Ruc => 0001 |
||
375 | * Other Ruc => 001 |
||
376 | * |
||
377 | * @param string $value The last digits |
||
378 | * @param string $type Type of identifier |
||
379 | * @return boolean |
||
380 | * @throws EcuadorIdentificationException When not equal to 001 |
||
381 | */ |
||
382 | private function theLastDigitsValidation($value, $type) |
||
412 | |||
413 | /** |
||
414 | * Module 10 Algorithm to validate if Certificates and RUC of natural person are valid. |
||
415 | * |
||
416 | * Coefficients used to validate the tenth digit of the Certificates, |
||
417 | * are: 2, 1, 2, 1, 2, 1, 2, 1, 2 |
||
418 | * |
||
419 | * Step 1: Multiply each digit of the card by the coefficient, |
||
420 | * except for the verification digit (tenth digit), |
||
421 | * if it is greater than 10 sums between digits. Example: |
||
422 | * |
||
423 | * 2 1 2 1 2 1 2 1 2 (Coefficients) |
||
424 | * 1 7 1 0 0 3 4 0 6 (Certificate) |
||
425 | * 2 7 2 0 0 3 8 0 [12] => continue to step 2. |
||
426 | * |
||
427 | * Step 2: If any of the multiplication results is greater than 10, |
||
428 | * it is added between digits of the result. Example: [12] => 1 + 2 = Result (3) |
||
429 | * |
||
430 | * Step 3: The result of the multiplications is added. Example: |
||
431 | * 2 7 2 0 0 3 8 0 3 = Result (25) |
||
432 | * |
||
433 | * Step 4: The result of the sum is divided by 10 and the remainder of the division is obtained |
||
434 | * If the remainder is 0 the check digit is 0 |
||
435 | * Otherwise, the residue is subtracted from 10 |
||
436 | * |
||
437 | * If the result is equal to the verification digit, the value is correct. |
||
438 | * |
||
439 | * @param string $number Certificates or RUC of natural person |
||
440 | * @return boolean |
||
441 | * @throws EcuadorIdentificationException The verified digit does not match the verification digit. |
||
442 | */ |
||
443 | protected function moduleTen($number) |
||
474 | |||
475 | /** |
||
476 | * Module 11 Algorithm to validate if RUC of Public Companies and Private Companies are valid. |
||
477 | * |
||
478 | * For Public Companies (Third Digit => [6]): |
||
479 | * => The verifier digit is the ninth digit. |
||
480 | * => Coefficients used to validate the ninth digit of the Public Company RUC, (Third digit = [6]) |
||
481 | * are: 3, 2, 7, 6, 5, 4, 3, 2 |
||
482 | * |
||
483 | * |
||
484 | * For Private Companies (Third Digit => [9]): |
||
485 | * => The verifier digit is the tenth digit. |
||
486 | * => Coefficients used to validate the tenth digit of the Private Company RUC, (Third digit = [9]) |
||
487 | * are: 4, 3, 2, 7, 6, 5, 4, 3, 2 |
||
488 | * |
||
489 | * Step 1: Multiply each digit of the RUC with its respective coefficient, |
||
490 | * except the verification digit. Example: |
||
491 | * |
||
492 | * Public Companies |
||
493 | * 3 2 7 6 5 4 3 2 (Coefficients) |
||
494 | * 1 7 6 0 0 0 1 0 [4] 0 0 0 1 (Public RUC) [4] => Ninth Digit (Check Digit) |
||
495 | * 3 14 42 0 0 0 3 0 => Multiplication Result |
||
496 | * |
||
497 | * Private Companies |
||
498 | * 4 3 2 7 6 5 4 3 2 (Coefficients) |
||
499 | * 1 7 9 0 0 8 5 7 8 [3] 0 0 1 (Private RUC) [3] => Tenth Digit (Check Digit) |
||
500 | * 4 21 18 0 0 40 20 21 16 => Multiplication Result |
||
501 | * |
||
502 | * Step 2: The multiplication results are added |
||
503 | * |
||
504 | * Public Companies |
||
505 | * 3 14 42 0 0 0 3 0 = Result (62) |
||
506 | * |
||
507 | * * Private Companies |
||
508 | * 4 21 18 0 0 40 20 21 16 = Result (140) |
||
509 | * |
||
510 | * Step 3: The result of the sum is divided to 11 and the remainder of the division is obtained. |
||
511 | * If the remainder is 0 the check digit is 0 |
||
512 | * Otherwise, the residue is subtracted from 11 |
||
513 | * |
||
514 | * If the result is equal to the verification digit, the value is correct. |
||
515 | * |
||
516 | * @param string $number Private Company RUC or Public Compnay RUC |
||
517 | * @param string $type Type of identifier |
||
518 | * @return boolean |
||
519 | * @throws EcuadorIdentificationException The verified digit does not match the verification digit. |
||
520 | */ |
||
521 | protected function moduleEleven($number, $type) |
||
558 | } |
||
559 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: