mirror of
https://github.com/Respect/Validation.git
synced 2024-06-02 13:52:14 +02:00
Create "Vatin" rule (VAT identification number)
See https://en.wikipedia.org/wiki/VAT_identification_number
This commit is contained in:
parent
332b0d7bb6
commit
38aedd01e3
|
@ -19,3 +19,4 @@ See also:
|
|||
* [Bank](Bank.md)
|
||||
* [Pesel](Pesel.md)
|
||||
* [SubdivisionCode](SubdivisionCode.md)
|
||||
* [Vatin](Vatin.md)
|
||||
|
|
|
@ -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)
|
|
@ -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
23
docs/Vatin.md
Normal 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)
|
29
library/Exceptions/Locale/PlVatinException.php
Normal file
29
library/Exceptions/Locale/PlVatinException.php
Normal 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',
|
||||
],
|
||||
];
|
||||
}
|
27
library/Exceptions/VatinException.php
Normal file
27
library/Exceptions/VatinException.php
Normal 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}}',
|
||||
],
|
||||
];
|
||||
}
|
46
library/Rules/Locale/PlVatin.php
Normal file
46
library/Rules/Locale/PlVatin.php
Normal 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
32
library/Rules/Vatin.php
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
11
tests/integration/rules/vatin_1.phpt
Normal file
11
tests/integration/rules/vatin_1.phpt
Normal 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--
|
16
tests/integration/rules/vatin_2.phpt
Normal file
16
tests/integration/rules/vatin_2.phpt
Normal 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
|
15
tests/integration/rules/vatin_3.phpt
Normal file
15
tests/integration/rules/vatin_3.phpt
Normal 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
|
16
tests/integration/rules/vatin_4.phpt
Normal file
16
tests/integration/rules/vatin_4.phpt
Normal 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"
|
16
tests/integration/rules/vatin_5.phpt
Normal file
16
tests/integration/rules/vatin_5.phpt
Normal 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"
|
49
tests/unit/Rules/Locale/PlVatinTest.php
Normal file
49
tests/unit/Rules/Locale/PlVatinTest.php
Normal 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'],
|
||||
];
|
||||
}
|
||||
}
|
38
tests/unit/Rules/VatinTest.php
Normal file
38
tests/unit/Rules/VatinTest.php
Normal 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');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue