Created
February 21, 2018 18:33
-
-
Save asantibanez/181d579f87ecb41851e9c3606c9ce9e5 to your computer and use it in GitHub Desktop.
Laravel Rule Object for Ecuatorian Taxpayer Id Validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Rules; | |
use Illuminate\Contracts\Validation\Rule; | |
class EcuatorianTaxpayerId implements Rule | |
{ | |
public function __construct() | |
{ | |
// | |
} | |
public function passes($attribute, $value) | |
{ | |
$taxpayer_id = $value; | |
return collect([$taxpayer_id]) | |
->filter(function ($value) { | |
return $this->taxpayerIdHasCorrectLength($value); | |
}) | |
->filter(function ($value) { | |
return $this->taxpayerIdBelongsToPerson($value) | |
|| $this->taxpayerIdBelongsToCompany($value); | |
}) | |
->map(function ($value) { | |
if ($this->taxpayerIdBelongsToPerson($value)) | |
return $this->isValidPersonTaxpayerId($value); | |
if ($this->taxpayerIdBelongsToCompany($value)) | |
return $this->isValidCompanyTaxpayerId($value); | |
return false; | |
}) | |
->first() == true; | |
} | |
public function getTaxpayerIdDigit($taxpayer_id, $position) | |
{ | |
return $taxpayer_id[$position - 1]; | |
} | |
private function taxpayerIdHasCorrectLength($taxpayer_id) | |
{ | |
$length = strlen($taxpayer_id); | |
return $length == 10 || $length == 13; | |
} | |
private function taxpayerIdBelongsToPerson($taxpayer_id) | |
{ | |
$first_digit = $this->getTaxpayerIdDigit($taxpayer_id, 1); | |
$second_digit = $this->getTaxpayerIdDigit($taxpayer_id, 2); | |
$first_and_second_digit = $first_digit . $second_digit; | |
$third_digit = $this->getTaxpayerIdDigit($taxpayer_id, 3); | |
return $first_and_second_digit > 0 | |
&& $first_and_second_digit < 24 | |
&& $third_digit < 6; | |
} | |
private function taxpayerIdBelongsToCompany($taxpayer_id) | |
{ | |
$first_digit = $this->getTaxpayerIdDigit($taxpayer_id, 1); | |
$second_digit = $this->getTaxpayerIdDigit($taxpayer_id, 2); | |
$first_and_second_digit = $first_digit . $second_digit; | |
$third_digit = $this->getTaxpayerIdDigit($taxpayer_id, 3); | |
return $first_and_second_digit > 1 | |
&& $first_and_second_digit < 22 | |
&& ($third_digit == 6 || $third_digit == 9); | |
} | |
public function isValidPersonTaxpayerId($taxpayer_id) | |
{ | |
$sum = collect(str_split($taxpayer_id)) | |
->take(9) | |
->map(function ($value, $index) { | |
$factors = [2,1,2,1,2,1,2,1,2]; | |
return $value * $factors[$index]; | |
}) | |
->map(function ($value) { | |
if ($value >= 10) | |
return $value - 9; | |
return $value; | |
}) | |
->reduce(function ($sum, $value) { | |
return $sum + $value; | |
}); | |
$verifier = $this->getTaxpayerIdDigit($taxpayer_id, 10); | |
return $verifier > 0 ? | |
(10 - ($sum % 10)) == $verifier : | |
($sum % 10) == $verifier; | |
} | |
public function isValidCompanyTaxpayerId($taxpayer_id) | |
{ | |
$sum = collect(str_split($taxpayer_id)) | |
->take(9) | |
->map(function ($value, $index) use ($taxpayer_id) { | |
$third_digit = $this->getTaxpayerIdDigit($taxpayer_id, 3); | |
$factors = $third_digit == 9 ? | |
[4,3,2,7,6,5,4,3,2] : | |
[3,2,7,6,5,4,3,2,0]; //last is zero for public companies | |
return $value * $factors[$index]; | |
}) | |
->reduce(function ($sum, $value) { | |
return $sum + $value; | |
}); | |
$third_digit = $this->getTaxpayerIdDigit($taxpayer_id, 3); | |
$verifier = $third_digit == 9 ? | |
$this->getTaxpayerIdDigit($taxpayer_id, 10) : | |
$this->getTaxpayerIdDigit($taxpayer_id, 9); | |
return $verifier > 0 ? | |
(11 - ($sum % 11)) == $verifier : | |
($sum % 11) == $verifier; | |
} | |
public function message() | |
{ | |
return 'The taxpayer id provided is invalid'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Si el algoritmo lo sacaste de un documento publicado por el SRI del 2011 está desactualizado. Esa verificación del número 6 para ver si es una persona ya no es correcto. Aquí tengo implementado un algoritmo probado contra un set de cédulas y RUCs válidos
https://github.com/datil/personas/blob/master/src/personas/id/ec.clj