Skip to content
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from spaze/spaze/gb-non-eu
Browse files Browse the repository at this point in the history
Remove GB from EU tax rules
  • Loading branch information
spaze authored Jan 4, 2021
2 parents bb9c66e + 78ef408 commit f478a23
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 34 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ The returned array of rates is unsorted. This method can be useful when you want

EU countries are supported as well as some non-EU countries that use VAT. Some countries are not supported even though they also have VAT. Currently, that's the case for the following countries:
- Switzerland (CH)
- United Kingdom (GB)
- Norway (NO)
- Turkey (TR)

Expand Down
54 changes: 34 additions & 20 deletions src/VatRates.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,6 @@ class VatRates
'Mayotte' => 0,
],
],
'GB' => [ // United Kingdom
'rate' => 0.20,
'exceptions' => [
// UK RAF Bases in Cyprus are taxed at Cyprus rate
'Akrotiri' => 0.19,
'Dhekelia' => 0.19,
],
],
'GR' => [ // Greece
'rate' => 0.24,
'exceptions' => [
Expand Down Expand Up @@ -200,6 +192,14 @@ class VatRates
self::LOW => 0.025,
],
],
'GB' => [ // United Kingdom
'rate' => 0.20,
'exceptions' => [
// UK RAF Bases in Cyprus are taxed at Cyprus rate
'Akrotiri' => 0.19,
'Dhekelia' => 0.19,
],
],
'NO' => [ // Norway
'rate' => 0.25,
],
Expand Down Expand Up @@ -311,18 +311,6 @@ class VatRates
'name' => 'Mayotte',
],
],
'GB' => [
// Akrotiri
[
'postalCode' => '/^BFPO57|BF12AT$/',
'code' => 'CY',
],
// Dhekelia
[
'postalCode' => '/^BFPO58|BF12AU$/',
'code' => 'CY',
],
],
'GR' => [
[
'postalCode' => '/^63086$/',
Expand Down Expand Up @@ -358,6 +346,29 @@ class VatRates
],
];

/**
* Optional postal code exceptions.
*
* Non-EU countries with their own VAT requirements and postal code exceptions,
* added with `addRateForCountry()` for the rate and the exceptions to be applied.
*
* @var array<string, array>
*/
private $optionalPostalCodeExceptions = [
'GB' => [
// Akrotiri
[
'postalCode' => '/^BFPO57|BF12AT$/',
'code' => 'CY',
],
// Dhekelia
[
'postalCode' => '/^BFPO58|BF12AU$/',
'code' => 'CY',
],
],
];

/** @var DateTimeImmutable */
private $now;

Expand All @@ -379,6 +390,9 @@ public function addRateForCountry(string $country): void
throw new NoVatRulesForCountryException("No optional tax rules specified for {$country}");
}
$this->taxRules[$country] = $this->optionalTaxRules[$country];
if (isset($this->optionalPostalCodeExceptions[$country])) {
$this->postalCodeExceptions[$country] = $this->optionalPostalCodeExceptions[$country];
}
}


Expand Down
43 changes: 29 additions & 14 deletions tests/VatCalculatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,35 @@ public function testAddNonEuRateShouldCollectValidateThrows(): void
}


public function testAddGbRateShouldCollectWithPostalCodeException(): void
{
$this->assertFalse($this->vatCalculator->shouldCollectVat('GB'));
$this->assertFalse($this->vatCalculator->shouldCollectEuVat('GB'));
$result = $this->vatCalculator->calculate(24.00, 'GB', null, true);
$this->assertEquals(24.00, $result->getPrice());
$this->assertEquals(0.00, $result->getTaxRate());
$this->assertEquals(0.00, $result->getTaxValue());

$this->vatRates->addRateForCountry('GB');
$this->assertTrue($this->vatCalculator->shouldCollectVat('GB'));
$this->assertFalse($this->vatCalculator->shouldCollectEuVat('GB'));

// Valid UK post code
$postalCode = 'S1A 2AA';
$result = $this->vatCalculator->calculate(24.00, 'GB', $postalCode, false);
//Expect standard rate for UK
$this->assertEquals(28.80, $result->getPrice());
$this->assertEquals(0.20, $result->getTaxRate());
$this->assertEquals(4.80, $result->getTaxValue());

$postalCode = 'BFPO58'; // Dhekelia
$result = $this->vatCalculator->calculate(24.00, 'GB', $postalCode, false);
$this->assertEquals(28.56, $result->getPrice());
$this->assertEquals(0.19, $result->getTaxRate());
$this->assertEquals(4.56, $result->getTaxValue());
}


public function testSetBusinessCountryCode(): void
{
$this->vatCalculator->setBusinessCountryCode('DE');
Expand Down Expand Up @@ -265,12 +294,6 @@ public function testChecksPostalCodeForVatExceptions(): void
$this->assertEquals(0.19, $result->getTaxRate());
$this->assertEquals(4.56, $result->getTaxValue());

$postalCode = 'BFPO58'; // Dhekelia
$result = $this->vatCalculator->calculate(24.00, 'GB', $postalCode, false);
$this->assertEquals(28.56, $result->getPrice());
$this->assertEquals(0.19, $result->getTaxRate());
$this->assertEquals(4.56, $result->getTaxValue());

$postalCode = '9122'; // Madeira
$result = $this->vatCalculator->calculate(24.00, 'PT', $postalCode, false);
$this->assertEquals(29.28, $result->getPrice());
Expand All @@ -288,14 +311,6 @@ public function testPostalCodesWithoutExceptionsGetStandardRate(): void
$this->assertEquals(29.04, $result->getPrice());
$this->assertEquals(0.21, $result->getTaxRate());
$this->assertEquals(5.04, $result->getTaxValue());

// Valid UK post code
$postalCode = 'S1A 2AA';
$result = $this->vatCalculator->calculate(24.00, 'GB', $postalCode, false);
//Expect standard rate for UK
$this->assertEquals(28.80, $result->getPrice());
$this->assertEquals(0.20, $result->getTaxRate());
$this->assertEquals(4.80, $result->getTaxValue());
}


Expand Down

0 comments on commit f478a23

Please sign in to comment.