Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/phpci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
fail-fast: false
name: CI PHP ${{ matrix.php-versions }}

Expand All @@ -24,7 +24,6 @@ jobs:
php_version: ${{ matrix.php-versions }}

- name: PHPUnit Tests
uses: php-actions/phpunit@v3
uses: php-actions/phpunit@v4
with:
version: "8"
php_version: ${{ matrix.php-versions }}
7 changes: 3 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
"keywords": ["tax", "vat"],
"license": "MIT",
"require": {
"php": ">=7.1",
"commerceguys/addressing": "^1.0",
"commerceguys/zone": "^0.8",
"php": ">=7.4",
"commerceguys/addressing": "^1.0 || ^2.0",
"doctrine/collections": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
"phpunit/phpunit": "^9.0",
"mikey179/vfsstream": "^1.0"
},
"autoload": {
Expand Down
6 changes: 3 additions & 3 deletions src/Model/TaxType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace CommerceGuys\Tax\Model;

use CommerceGuys\Addressing\Zone\Zone;
use CommerceGuys\Tax\Enum\GenericLabel;
use CommerceGuys\Zone\Model\ZoneEntityInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

Expand Down Expand Up @@ -59,7 +59,7 @@ class TaxType implements TaxTypeEntityInterface
/**
* The tax type zone.
*
* @var ZoneEntityInterface
* @var Zone
*/
protected $zone;

Expand Down Expand Up @@ -216,7 +216,7 @@ public function getZone()
/**
* {@inheritdoc}
*/
public function setZone(ZoneEntityInterface $zone)
public function setZone(Zone $zone)
{
$this->zone = $zone;

Expand Down
6 changes: 3 additions & 3 deletions src/Model/TaxTypeEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace CommerceGuys\Tax\Model;

use CommerceGuys\Addressing\Zone\Zone;
use Doctrine\Common\Collections\Collection;
use CommerceGuys\Zone\Model\ZoneEntityInterface;

interface TaxTypeEntityInterface extends TaxTypeInterface
{
Expand Down Expand Up @@ -62,11 +62,11 @@ public function setRoundingMode($roundingMode);
/**
* Sets the tax type zone.
*
* @param ZoneEntityInterface $zone The tax type zone.
* @param Zone $zone The tax type zone.
*
* @return self
*/
public function setZone(ZoneEntityInterface $zone);
public function setZone(Zone $zone);

/**
* Sets the tax type tag.
Expand Down
4 changes: 2 additions & 2 deletions src/Model/TaxTypeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace CommerceGuys\Tax\Model;

use CommerceGuys\Zone\Model\ZoneInterface;
use CommerceGuys\Addressing\Zone\Zone;

interface TaxTypeInterface
{
Expand Down Expand Up @@ -71,7 +71,7 @@ public function getRoundingMode();
/**
* Gets the tax type zone.
*
* @return ZoneInterface The tax type zone.
* @return Zone The tax type zone.
*/
public function getZone();

Expand Down
6 changes: 2 additions & 4 deletions src/Repository/TaxTypeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
use CommerceGuys\Tax\Model\TaxType;
use CommerceGuys\Tax\Model\TaxRate;
use CommerceGuys\Tax\Model\TaxRateAmount;
use CommerceGuys\Zone\Repository\ZoneRepository;
use CommerceGuys\Zone\Repository\ZoneRepositoryInterface;

/**
* Manages tax types based on JSON definitions.
Expand All @@ -24,7 +22,7 @@ class TaxTypeRepository implements TaxTypeRepositoryInterface
/**
* The zone repository.
*
* @var ZoneRepositoryInterface
* @var ZoneRepository
*/
protected $zoneRepository;

Expand All @@ -48,7 +46,7 @@ class TaxTypeRepository implements TaxTypeRepositoryInterface
* @param string $definitionPath The path to the tax type and zone
* definitions. Defaults to 'resources/'.
*/
public function __construct($definitionPath = null, ?ZoneRepositoryInterface $zoneRepository = null)
public function __construct($definitionPath = null, ?ZoneRepository $zoneRepository = null)
{
$definitionPath = $definitionPath ?: __DIR__ . '/../../resources/';
$this->definitionPath = $definitionPath . 'tax_type/';
Expand Down
124 changes: 124 additions & 0 deletions src/Repository/ZoneRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

declare(strict_types=1);

namespace CommerceGuys\Tax\Repository;

use CommerceGuys\Addressing\Zone\Zone;

/**
* Manages zones based on JSON definitions.
*/
class ZoneRepository
{
/**
* The path where zone definitions are stored.
*
* @var string
*/
protected string $definitionPath;

/**
* Zone index.
*
* @var array
*/
protected array $zoneIndex = [];

/**
* Zones.
*
* @var Zone[]
*/
protected array $zones = [];

/**
* Creates a ZoneRepository instance.
*
* @param string $definitionPath Path to the zone definitions.
*/
public function __construct(string $definitionPath)
{
$this->definitionPath = $definitionPath;
}

public function get(string $id): Zone
{
if (!isset($this->zones[$id])) {
$definition = $this->loadDefinition($id);
$this->zones[$id] = $this->createZoneFromDefinition($definition);
}

return $this->zones[$id];
}

public function getAll(?string $scope = null): array
{
// Build the list of all available zones.
if (empty($this->zoneIndex)) {
if ($handle = opendir($this->definitionPath)) {
while (false !== ($entry = readdir($handle))) {
if (substr($entry, 0, 1) != '.') {
$id = strtok($entry, '.');
$this->zoneIndex[] = $id;
}
}
closedir($handle);
}
}

// Load each zone, filter by scope if needed.
$zones = [];
foreach ($this->zoneIndex as $id) {
$zone = $this->get($id);
if (is_null($scope) || ($zone->getScope() == $scope)) {
$zones[$id] = $this->get($id);
}
}

return $zones;
}

/**
* Loads the zone definition for the provided id.
*
* @param string $id The zone id.
* @return array The zone definition.
*/
protected function loadDefinition(string $id): array
{
$filename = $this->definitionPath . $id . '.json';
$definition = @file_get_contents($filename);
if (empty($definition)) {
throw new UnknownZoneException($id);
}
$definition = json_decode($definition, true);
$definition['id'] = $id;

return $definition;
}

/**
* Creates a Zone instance from the provided definition.
*
* @param array $definition The zone definition.
* @return Zone
*/
protected function createZoneFromDefinition(array $definition): Zone
{
$definition['label'] = $definition['name'];

$territories = [];
foreach ($definition['members'] as $member) {
if ($member['type'] === 'zone') {
foreach ($this->loadDefinition($member['zone'])['members'] as $otherTerritory) {
$territories[] = $otherTerritory;
}
} else {
$territories[] = $member;
}
}
$definition['territories'] = $territories;
return new Zone($definition);
}
}
6 changes: 3 additions & 3 deletions src/Resolver/TaxType/StoreRegistrationCheckerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace CommerceGuys\Tax\Resolver\TaxType;

use CommerceGuys\Addressing\Address;
use CommerceGuys\Addressing\Zone\Zone;
use CommerceGuys\Tax\Model\TaxTypeInterface;
use CommerceGuys\Tax\Resolver\Context;
use CommerceGuys\Zone\Model\ZoneInterface;

trait StoreRegistrationCheckerTrait
{
Expand All @@ -19,13 +19,13 @@ trait StoreRegistrationCheckerTrait
/**
* Checks whether the store is registered to collect taxes in the given zone.
*
* @param ZoneInterface $zone The zone.
* @param Zone $zone The zone.
* @param Context $context The context containing store information.
*
* @return bool True if the store is registered to collect taxes in the
* given zone, false otherwise.
*/
protected function checkStoreRegistration(ZoneInterface $zone, Context $context)
protected function checkStoreRegistration(Zone $zone, Context $context)
{
$storeRegistrations = $context->getStoreRegistrations();
foreach ($storeRegistrations as $country) {
Expand Down
3 changes: 2 additions & 1 deletion tests/Model/TaxTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public function testRoundingMode()
public function testZone()
{
$zone = $this
->getMockBuilder('CommerceGuys\Zone\Model\Zone')
->getMockBuilder('CommerceGuys\Addressing\Zone\Zone')
->setConstructorArgs([['id' => 'test', 'label' => 'test label', 'territories' => [['country_code' => 'test']]]])
->getMock();

$this->taxType->setZone($zone);
Expand Down
6 changes: 3 additions & 3 deletions tests/Repository/TaxTypeRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function testGet()
{
$taxType = $this->taxTypeRepository->get('fr_vat');
$this->assertInstanceOf('CommerceGuys\Tax\Model\TaxType', $taxType);
$this->assertInstanceOf('CommerceGuys\Zone\Model\Zone', $taxType->getZone());
$this->assertInstanceOf('CommerceGuys\Addressing\Zone\Zone', $taxType->getZone());
$this->assertEquals('fr_vat', $taxType->getId());
$this->assertEquals('French VAT', $taxType->getName());
$this->assertEquals(GenericLabel::VAT, $taxType->getGenericLabel());
Expand Down Expand Up @@ -182,9 +182,9 @@ public function testGetAll()
*/
protected function getZoneRepository()
{
$zone = $this->createMock('CommerceGuys\Zone\Model\Zone');
$zone = $this->createMock('CommerceGuys\Addressing\Zone\Zone');
$zoneRepository = $this
->getMockBuilder('CommerceGuys\Zone\Repository\ZoneRepository')
->getMockBuilder('CommerceGuys\Tax\Repository\ZoneRepository')
->disableOriginalConstructor()
->getMock();
$zoneRepository
Expand Down
2 changes: 2 additions & 0 deletions tests/Resolver/TaxRate/DefaultTaxRateResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*/
class DefaultTaxRateResolverTest extends TestCase
{
private ?DefaultTaxRateResolver $resolver = null;

/**
* {@inheritdoc}
*/
Expand Down
Loading