Skip to content

Commit

Permalink
Add GetTaxZoneCountry class to be able to use country based tax zones (
Browse files Browse the repository at this point in the history
  • Loading branch information
webcraft authored Sep 21, 2023
1 parent fafd157 commit 644c72c
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/core/src/Actions/Taxes/GetTaxZone.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ public function execute(Addressable $address = null)
}
}

if ($address && $address->country_id) {
$countryZone = app(GetTaxZoneCountry::class)->execute($address->country_id);
if ($countryZone) {
return $countryZone->taxZone;
}
}

return TaxZone::getDefault();
}
}
32 changes: 32 additions & 0 deletions packages/core/src/Actions/Taxes/GetTaxZoneCountry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Lunar\Actions\Taxes;

use Lunar\Models\TaxZoneCountry;

class GetTaxZoneCountry
{
public function execute($countryId)
{
$taxZone = $this->getZone($countryId);

if ($taxZone instanceof TaxZoneCountry) {
return $taxZone;
}

if (!$taxZone) {
return null;
}
}

/**
* Return the zone or zones which match this country.
*
* @param int $countryId
* @return TaxZoneCountry|null
*/
protected function getZone(int $countryId)
{
return TaxZoneCountry::whereCountryId($countryId)->first();
}
}
61 changes: 61 additions & 0 deletions packages/core/tests/Unit/Actions/Taxes/GetTaxZoneCountryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Lunar\Tests\Unit\Actions\Taxes;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Actions\Taxes\GetTaxZoneCountry;
use Lunar\Models\Country;
use Lunar\Models\TaxZoneCountry;
use Lunar\Tests\TestCase;

/**
* @group lunar.actions
*/
class GetTaxZoneCountryTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function can_match_country_id()
{
$belgium = Country::factory()->create([
'name' => 'Belgium',
]);

$uk = Country::factory()->create([
'name' => 'United Kingdom',
]);

$taxZoneBelgium = TaxZoneCountry::factory()->create([
'country_id' => $belgium->id,
]);

$taxZoneUk = TaxZoneCountry::factory()->create([
'country_id' => $uk->id,
]);

$zone = app(GetTaxZoneCountry::class)->execute($uk->id);

$this->assertEquals($taxZoneUk->id, $zone->id);
}

/** @test */
public function can_mismatch_country_id()
{
$belgium = Country::factory()->create([
'name' => 'Belgium',
]);

$uk = Country::factory()->create([
'name' => 'United Kingdom',
]);

$taxZoneBelgium = TaxZoneCountry::factory()->create([
'country_id' => $belgium->id,
]);

$zone = app(GetTaxZoneCountry::class)->execute($uk->id);

$this->assertNull($zone);
}
}
99 changes: 99 additions & 0 deletions packages/core/tests/Unit/Actions/Taxes/GetTaxZoneTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace Lunar\Tests\Unit\Actions\Taxes;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Actions\Taxes\GetTaxZone;
use Lunar\Actions\Taxes\GetTaxZoneCountry;
use Lunar\Models\Address;
use Lunar\Models\Country;
use Lunar\Models\State;
use Lunar\Models\TaxZone;
use Lunar\Models\TaxZoneCountry;
use Lunar\Models\TaxZonePostcode;
use Lunar\Models\TaxZoneState;
use Lunar\Tests\TestCase;

/**
* @group lunar.actions
*/
class GetTaxZoneTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function can_prioritize_taxzones()
{
$postcode = 'SW1A 0AA';

$state = State::factory()->create([
'code' => 'AL',
'name' => 'Alabama',
]);

$country = Country::factory()->create([
'name' => 'Belgium',
]);

$taxZonePostcode = TaxZonePostcode::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'postcode' => $postcode,
]);

$taxZoneState = TaxZoneState::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'state_id' => $state->id,
]);

$taxZoneCountry = TaxZoneCountry::factory()->create([
'tax_zone_id' => TaxZone::factory(['default' => false]),
'country_id' => $country->id,
]);

$defaultTaxZone = TaxZone::factory(['default' => true])->create();

// postcode, state and country match => postcode tax zone should be returned
$addressWithAllMatching = Address::factory()->create([
'postcode' => $postcode,
'state' => $state->name,
'country_id' => $country->id,
]);

$zone1 = app(GetTaxZone::class)->execute($addressWithAllMatching);

$this->assertEquals($taxZonePostcode->tax_zone_id, $zone1->id);

// only state and country match => state tax zone should be returned
$addressWithOnlyStateAndCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => $state->name,
'country_id' => $country->id,
]);

$zone2 = app(GetTaxZone::class)->execute($addressWithOnlyStateAndCountryMatching);

$this->assertEquals($taxZoneState->tax_zone_id, $zone2->id);

// only country matches => country tax zone should be returned
$addressWithOnlyCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => 'Alaska',
'country_id' => $country->id,
]);

$zone3 = app(GetTaxZone::class)->execute($addressWithOnlyCountryMatching);

$this->assertEquals($taxZoneCountry->tax_zone_id, $zone3->id);

// nothing matches => default tax zone should be returned
$addressWithOnlyCountryMatching = Address::factory()->create([
'postcode' => '1234AB',
'state' => 'Alaska',
'country_id' => 123,
]);

$zone3 = app(GetTaxZone::class)->execute($addressWithOnlyCountryMatching);

$this->assertEquals($defaultTaxZone->id, $zone3->id);
}
}

1 comment on commit 644c72c

@vercel
Copy link

@vercel vercel bot commented on 644c72c Sep 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.