Create "Vatin" rule (VAT identification number)

See https://en.wikipedia.org/wiki/VAT_identification_number
This commit is contained in:
Tomasz Regdos 2016-08-13 23:00:38 +02:00 committed by Henrique Moody
parent 332b0d7bb6
commit 38aedd01e3
No known key found for this signature in database
GPG key ID: 221E9281655813A6
16 changed files with 330 additions and 0 deletions

View file

@ -19,3 +19,4 @@ See also:
* [Bank](Bank.md)
* [Pesel](Pesel.md)
* [SubdivisionCode](SubdivisionCode.md)
* [Vatin](Vatin.md)

View file

@ -10,3 +10,11 @@ v::pesel()->validate('97072704800'); // true
v::pesel()->validate('97072704801'); // false
v::pesel()->validate('PESEL123456'); // false
```
***
See also:
* [Bank](Bank.md)
* [IdentityCard](IdentityCard.md)
* [SubdivisionCode](SubdivisionCode.md)
* [Vatin](Vatin.md)

View file

@ -189,6 +189,7 @@
* [Phone](Phone.md)
* [Sf](Sf.md)
* [Url](Url.md)
* [Vatin](Vatin.md)
* [VideoUrl](VideoUrl.md)
* [Zend](Zend.md)
@ -319,6 +320,7 @@
* [Uploaded](Uploaded.md)
* [Uppercase](Uppercase.md)
* [Url](Url.md)
* [Vatin](Vatin.md)
* [Version](Version.md)
* [VideoUrl](VideoUrl.md)
* [Vowel](Vowel.md)

23
docs/Vatin.md Normal file
View file

@ -0,0 +1,23 @@
# Vatin
- `v::vatin(string $countryCode)`
Validates VAT identification number according to the defined country.
```php
v::vatin('PL')->validate('1645865777'); // true
v::vatin('PL')->validate('1645865778'); // false
v::vatin('PL')->validate('1234567890'); // false
v::vatin('PL')->validate('164-586-57-77'); // false
v::vatin('PL')->validate('164-58-65-777'); // false
```
For now this rule only accepts Polish VAT identification number (NIP).
***
See also:
* [Bank](Bank.md)
* [IdentityCard](IdentityCard.md)
* [Pesel](Pesel.md)
* [SubdivisionCode](SubdivisionCode.md)

View file

@ -0,0 +1,29 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Exceptions\Locale;
use Respect\Validation\Exceptions\ValidationException;
final class PlVatinException extends ValidationException
{
/**
* @var array
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must be a valid Polish VAT identification number',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not be a valid Polish VAT identification number',
],
];
}

View file

@ -0,0 +1,27 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Exceptions;
final class VatinException extends ValidationException
{
/**
* @var array
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must be a valid VAT identification number for {{countryCode}}',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not be a valid VAT identification number for {{countryCode}}',
],
];
}

View file

@ -0,0 +1,46 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Rules\Locale;
use Respect\Validation\Rules\AbstractRule;
/**
* Validator for Polish VAT identification number (NIP).
*
* @link https://en.wikipedia.org/wiki/VAT_identification_number
*/
final class PlVatin extends AbstractRule
{
public function validate($input)
{
if (!is_scalar($input)) {
return false;
}
if (!preg_match('/^\d{10}$/', (string) $input)) {
return false;
}
$weights = [6, 5, 7, 2, 3, 4, 5, 6, 7];
$targetControlNumber = $input[9];
$calculateControlNumber = 0;
for ($i = 0; $i < 9; ++$i) {
$calculateControlNumber += $input[$i] * $weights[$i];
}
$calculateControlNumber = $calculateControlNumber % 11;
return $targetControlNumber == $calculateControlNumber;
}
}

32
library/Rules/Vatin.php Normal file
View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Rules;
use Respect\Validation\Exceptions\ComponentException;
final class Vatin extends AbstractWrapper
{
public $countryCode;
public function __construct($countryCode)
{
$shortName = ucfirst(strtolower($countryCode)).'Vatin';
$className = __NAMESPACE__.'\\Locale\\'.$shortName;
if (!class_exists($className)) {
$message = sprintf('There is no support for VAT identification number from "%s"', $countryCode);
throw new ComponentException($message);
}
$this->countryCode = $countryCode;
$this->validatable = new $className();
}
}

View file

@ -141,6 +141,7 @@ use Respect\Validation\Rules\Key;
* @method static Validator uploaded()
* @method static Validator uppercase()
* @method static Validator url()
* @method static Validator vatin(string $countryCode)
* @method static Validator version()
* @method static Validator videoUrl(string $service = null)
* @method static Validator vowel()

View file

@ -0,0 +1,11 @@
--FILE--
<?php
require_once 'vendor/autoload.php';
use Respect\Validation\Validator as v;
v::vatin('PL')->check('1645865777');
v::vatin('PL')->assert('1645865777');
?>
--EXPECTF--

View file

@ -0,0 +1,16 @@
--FILE--
<?php
require_once 'vendor/autoload.php';
use Respect\Validation\Exceptions\Locale\PlVatinException;
use Respect\Validation\Validator as v;
try {
v::vatin('PL')->check('1645865778');
} catch (PlVatinException $e) {
echo $e->getMainMessage();
}
?>
--EXPECTF--
"1645865778" must be a valid Polish VAT identification number

View file

@ -0,0 +1,15 @@
--FILE--
<?php
require_once 'vendor/autoload.php';
use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\AllOfException;
try {
v::vatin('PL')->assert('1645865778');
} catch (AllOfException $e) {
echo $e->getFullMessage();
}
--EXPECTF--
- "1645865778" must be a valid Polish VAT identification number

View file

@ -0,0 +1,16 @@
--FILE--
<?php
require_once 'vendor/autoload.php';
use Respect\Validation\Exceptions\VatinException;
use Respect\Validation\Validator as v;
try {
v::not(v::vatin('PL'))->check('1645865777');
} catch (VatinException $e) {
echo $e->getMainMessage();
}
?>
--EXPECTF--
"1645865777" must not be a valid VAT identification number for "PL"

View file

@ -0,0 +1,16 @@
--FILE--
<?php
require_once 'vendor/autoload.php';
use Respect\Validation\Exceptions\AllOfException;
use Respect\Validation\Validator as v;
try {
v::not(v::vatin('PL'))->assert('1645865777');
} catch (AllOfException $e) {
echo $e->getFullMessage();
}
?>
--EXPECTF--
- "1645865777" must not be a valid VAT identification number for "PL"

View file

@ -0,0 +1,49 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Rules\Locale;
use Respect\Validation\Rules\RuleTestCase;
use stdClass;
/**
* @group rule
* @covers Respect\Validation\Rules\Locale\PlVatin
*/
class PlVatinTest extends RuleTestCase
{
public function providerForValidInput()
{
$rule = new PlVatin();
return [
[$rule, '1645865777'],
[$rule, '5581418257'],
[$rule, '1298727531'],
];
}
public function providerForInvalidInput()
{
$rule = new PlVatin();
return [
[$rule, []],
[$rule, new stdClass()],
[$rule, '1645865778'],
[$rule, '164-586-57-77'],
[$rule, '164-58-65-777'],
[$rule, '5581418258'],
[$rule, '1298727532'],
[$rule, '1234567890'],
];
}
}

View file

@ -0,0 +1,38 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
namespace Respect\Validation\Rules;
use Respect\Validation\Validatable;
/**
* @group rule
* @covers Respect\Validation\Rules\Vatin
*/
final class VatinTest extends \PHPUnit_Framework_TestCase
{
public function testShouldAcceptCountryCodeOnConstructor()
{
$countryCode = 'PL';
$rule = new Vatin($countryCode);
$this->assertInstanceOf(Validatable::class, $rule->getValidatable());
}
/**
* @expectedException Respect\Validation\Exceptions\ComponentException
* @expectedExceptionMessage There is no support for VAT identification number from "BR"
*/
public function testShouldThrowAnExceptionWhenCountryCodeIsNotSupported()
{
new Vatin('BR');
}
}