diff --git a/src/Faker/Generator.php b/src/Faker/Generator.php index a169997c87..1d8477738a 100644 --- a/src/Faker/Generator.php +++ b/src/Faker/Generator.php @@ -42,7 +42,7 @@ * @property string $creditCardDetails * @property string $bankAccountNumber * @property string $swiftBicNumber - * @property string $vat + * @method string vat($country, $spacedNationalPrefix = true) * * @property string $word * @property string|array $words diff --git a/src/Faker/Provider/Payment.php b/src/Faker/Provider/Payment.php index cadbc48d33..26829fc44e 100644 --- a/src/Faker/Provider/Payment.php +++ b/src/Faker/Provider/Payment.php @@ -6,6 +6,88 @@ class Payment extends Base { + /** + * Regular expression patterns per country code. + * + * @var array + * + * @link http://ec.europa.eu/taxation_customs/vies/faq.html?locale=lt#item_11 + * @link http://www.iecomputersystems.com/ordering/eu_vat_numbers.htm + * @link http://en.wikipedia.org/wiki/VAT_identification_number + * @link https://github.com/ronanguilloux/IsoCodes/blob/master/src/IsoCodes/Vat.php + */ + public static $countryPatterns = array( + 'AT' => 'U\d{8}', + 'BE' => '0\d{9}', + 'BG' => '\d{9,10}', + 'CY' => '\d{8}[A-Z]', + 'CZ' => '\d{8,10}', + 'DE' => '\d{9}', + 'DK' => '(\d{2} ?){3}\d{2}', + 'EE' => '\d{9}', + 'EL' => '\d{9}', + // ES: The first and last characters may be alpha or numeric; but they may not both be numeric: + 'ES' => '[A-Z]\d{7}[A-Z]|\d{8}[A-Z]|[A-Z]\d{8}', + 'FI' => '\d{8}', + 'FR' => '([A-Z]{2}|\d{2})\d{9}', + 'GB' => '\d{9}|\d{12}|(GD|HA)\d{3}', + 'HU' => '\d{8}', + // IE: Seven digits and one last letter or six digits and two letters (second & last) + 'IE' => '\d{7}[A-Z]|\d[A-Z]\d{5}[A-Z]', + 'IT' => '\d{11}', + 'LT' => '(\d{9}|\d{12})', + 'LU' => '\d{8}', + 'LV' => '\d{11}', + 'MT' => '\d{8}', + // NL: The 10th position following the prefix is always "B". + 'NL' => '\d{9}B\d{2}', + 'PL' => '\d{10}', + 'PT' => '\d{9}', + 'RO' => '\d{2,10}', + 'SE' => '\d{12}', + 'SI' => '\d{8}', + 'SK' => '\d{10}', + 'AL' => '[KJ]\d{8}L', + 'AU' => '\d{9}', + 'BY' => '\d{9}', + 'HR' => '\d{11}', + 'NO' => '\d{9}MVA', + 'PH' => '\d{12}', + 'RU' => '(\d{10}|\d{12})', + 'TR' => '\d{10}', + 'UA' => '\d{12}', + 'AR' => '\d{11}', + 'CL' => '\d{8}-\d', + 'CO' => '\d{10}', + 'EC' => '\d{13}', + 'GT' => '\d{7}-\d', + 'MX' => '\d{3} \d{6} \d{3}', + 'VE' => '[JGVE]-\d{8}-?\d', + ); + + /** + * Generate a national VAT number. + * + * The Value Added Tax, or VAT, is a general, broadly based consumption tax + * assessed on the value added to goods and services. + * + * @link http://ec.europa.eu/taxation_customs/vies/faq.html for European VAT numbers rules + * @example (belgian) BE0629078028, (polish, spaced) PL 5206136094 + * @param bool $spacedNationalPrefix + * @param string $country country code (ex: 'BE') + * @return string a fake valid VAT number + */ + public static function vat($spacedNationalPrefix = true, $country = null) + { + $country = is_null($country) ? array_rand(self::$countryPatterns) : $country; + $prefix = ($spacedNationalPrefix) ? " " : ""; + if (!array_key_exists($country, self::$countryPatterns)) { + throw new \InvalidArgumentException(sprintf("There is no VAT generator for %s so far.", $country)); + } + + return self::regexify(sprintf("^%s%s%s$", $country, $prefix, self::$countryPatterns[$country])); + } + public static $expirationDateFormat = "m/y"; protected static $cardVendors = array( diff --git a/src/Faker/Provider/at_AT/Payment.php b/src/Faker/Provider/at_AT/Payment.php index 799e864f2f..2895d01ebe 100644 --- a/src/Faker/Provider/at_AT/Payment.php +++ b/src/Faker/Provider/at_AT/Payment.php @@ -12,20 +12,22 @@ class Payment extends \Faker\Provider\Payment /** * Value Added Tax (VAT) * + * (this method is kept for backwards compatibility purpose only, until 1.6.0) + * @deprecated Deprecated since version 1.6.0, please use \Faker\Provider\Payment::vat() instead + * * @example 'ATU12345678', ('spaced') 'AT U12345678' * * @see http://ec.europa.eu/taxation_customs/vies/faq.html?locale=en#item_11 * @see http://www.iecomputersystems.com/ordering/eu_vat_numbers.htm * @see http://en.wikipedia.org/wiki/VAT_identification_number * - * @param bool $spacedNationalPrefix + * @param bool $spacedNationalPrefix + * @param string $country country code (ex: 'BE') * * @return string VAT Number */ - public static function vat($spacedNationalPrefix = true) + public static function vat($spacedNationalPrefix = true, $country = 'AT') { - $prefix = ($spacedNationalPrefix) ? "AT U" : "ATU"; - - return sprintf("%s%d", $prefix, self::randomNumber(8, true)); + return parent::vat($spacedNationalPrefix, $country); } } diff --git a/src/Faker/Provider/be_BE/Payment.php b/src/Faker/Provider/be_BE/Payment.php deleted file mode 100644 index b38e3fcf45..0000000000 --- a/src/Faker/Provider/be_BE/Payment.php +++ /dev/null @@ -1,31 +0,0 @@ -assertEquals(count($cardDetails), 4); $this->assertEquals(array('type', 'number', 'name', 'expirationDate'), array_keys($cardDetails)); } + + public function countriesProvider() + { + $data = array(); + + foreach(Payment::$countryPatterns as $country => $regexp) { + $data[] = array($country, sprintf("/^%s%s$/",$country, Payment::$countryPatterns[$country])); + } + + return $data; + } + + /** + * @dataProvider countriesProvider + */ + public function testVat($country, $regexp) + { + $vat = Payment::vat(false, $country); + $this->assertRegExp($regexp, $vat); + } + + public function testVatWithRandomCountry() + { + $vat = Payment::vat(false, null); + $this->assertNotEmpty($vat); + } } diff --git a/test/Faker/Provider/be_BE/PaymentTest.php b/test/Faker/Provider/be_BE/PaymentTest.php deleted file mode 100644 index d253b05cd6..0000000000 --- a/test/Faker/Provider/be_BE/PaymentTest.php +++ /dev/null @@ -1,30 +0,0 @@ -addProvider(new Payment($faker)); - $this->faker = $faker; - } - - public function testVatIsValid() - { - $vat = $this->faker->vat(); - $unspacedVat = $this->faker->vat(false); - $this->assertRegExp('/^(BE 0\d{9})$/', $vat); - $this->assertRegExp('/^(BE0\d{9})$/', $unspacedVat); - } -}