Skip to content

Instantly share code, notes, and snippets.

@asantibanez
Created February 21, 2018 18:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asantibanez/181d579f87ecb41851e9c3606c9ce9e5 to your computer and use it in GitHub Desktop.
Save asantibanez/181d579f87ecb41851e9c3606c9ce9e5 to your computer and use it in GitHub Desktop.
Laravel Rule Object for Ecuatorian Taxpayer Id Validation
<?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';
}
}
@jplaza
Copy link

jplaza commented Feb 22, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment