1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Tax rule variable refactor

This commit is contained in:
David Bomba 2023-04-10 21:04:16 +10:00
parent 4ad389ccec
commit 76d2780a60
5 changed files with 121 additions and 97 deletions

View File

@ -137,9 +137,9 @@ class BaseRule implements RuleInterface
{
if(!array_key_exists($this->client->country->iso_3166_2, $this->region_codes))
throw new \Exception('Country not supported');
throw new \Exception('Automatic tax calculates not supported for this country');
$this->client_region = $this->region_codes[$this->client->country->iso_3166_2] ?? '';
$this->client_region = $this->region_codes[$this->client->country->iso_3166_2];
match($this->client_region){
'US' => $this->client_subregion = $this->tax_data->geoState,
@ -150,7 +150,7 @@ class BaseRule implements RuleInterface
return $this;
}
private function isTaxableRegion(): bool
public function isTaxableRegion(): bool
{
return $this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions || $this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax;
}

View File

@ -29,9 +29,9 @@ class Rule extends BaseRule implements RuleInterface
public bool $foreign_consumer_tax_exempt = true;
public float $vat_rate = 0;
public float $tax_rate = 0;
public float $reduced_vat_rate = 0;
public float $reduced_tax_rate = 0;
public function init(): self
{
@ -83,7 +83,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxReduced(): self
{
$this->tax_rate1 = $this->reduced_vat_rate;
$this->tax_rate1 = $this->reduced_tax_rate;
$this->tax_name1 = 'ermäßigte MwSt.';
return $this;
@ -122,7 +122,7 @@ class Rule extends BaseRule implements RuleInterface
{
// $this->tax();
$this->tax_rate1 = $this->vat_rate;
$this->tax_rate1 = $this->tax_rate;
$this->tax_name1 = 'MwSt.';
return $this;
}
@ -145,39 +145,39 @@ class Rule extends BaseRule implements RuleInterface
{
if ($this->client->is_tax_exempt) {
// nlog("tax exempt");
$this->vat_rate = 0;
$this->reduced_vat_rate = 0;
$this->tax_rate = 0;
$this->reduced_tax_rate = 0;
}
elseif($this->client_subregion != $this->vendor_iso_3166_2 && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt)
{
// nlog("euro zone and tax exempt");
$this->vat_rate = 0;
$this->reduced_vat_rate = 0;
$this->tax_rate = 0;
$this->reduced_tax_rate = 0;
}
elseif(!in_array($this->client_subregion, $this->eu_country_codes) && ($this->foreign_consumer_tax_exempt || $this->foreign_business_tax_exempt)) //foreign + tax exempt
{
// nlog("foreign and tax exempt");
$this->vat_rate = 0;
$this->reduced_vat_rate = 0;
$this->tax_rate = 0;
$this->reduced_tax_rate = 0;
}
elseif(in_array($this->client_subregion, $this->eu_country_codes) && !$this->client->has_valid_vat_number) //eu country / no valid vat
{
if(($this->vendor_iso_3166_2 != $this->client_subregion) && $this->client->company->tax_data->regions->EU->has_sales_above_threshold)
{
// nlog("eu zone with sales above threshold");
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->vat_rate;
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_vat_rate;
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->tax_rate;
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_tax_rate;
}
else {
// nlog("EU with intra-community supply ie DE to DE");
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->vat_rate;
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_vat_rate;
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
}
}
else {
// nlog("default tax");
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->vat_rate;
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_vat_rate;
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
}
return $this;

View File

@ -16,6 +16,8 @@ class TaxModel
public string $seller_subregion = 'CA';
public string $version = 'alpha';
public object $regions;
public function __construct(public ?TaxModel $model = null)
@ -35,12 +37,35 @@ class TaxModel
$this->regions->EU = new \stdClass();
$this->usRegion()
->euRegion();
->euRegion()
->auRegion();
return $this->regions;
}
private function auRegion(): self
{
$this->regions->AU = new \stdClass();
$this->regions->AU->has_sales_above_threshold = false;
$this->regions->AU->tax_all_subregions = false;
$this->regions->AU->vat_threshold = 75000;
$this->auSubRegions();
return $this;
}
private function auSubRegions(): self
{
$this->regions->AU->subregions = new \stdClass();
$this->regions->AU->subregions->AU = new \stdClass();
$this->regions->AU->subregions->AU->apply_tax = false;
$this->regions->AU->subregions->AU->tax_rate = 10;
return $this;
}
private function usRegion(): self
{
$this->regions->US->has_sales_above_threshold = false;
@ -174,138 +199,138 @@ class TaxModel
$this->regions->EU->subregions = new \stdClass();
$this->regions->EU->subregions->AT = new \stdClass();
$this->regions->EU->subregions->AT->vat_rate = 21;
$this->regions->EU->subregions->AT->reduced_vat_rate = 11;
$this->regions->EU->subregions->AT->tax_rate = 21;
$this->regions->EU->subregions->AT->reduced_tax_rate = 11;
$this->regions->EU->subregions->AT->apply_tax = false;
$this->regions->EU->subregions->BE = new \stdClass();
$this->regions->EU->subregions->BE->vat_rate = 21;
$this->regions->EU->subregions->BE->reduced_vat_rate = 6;
$this->regions->EU->subregions->BE->tax_rate = 21;
$this->regions->EU->subregions->BE->reduced_tax_rate = 6;
$this->regions->EU->subregions->BE->apply_tax = false;
$this->regions->EU->subregions->BG = new \stdClass();
$this->regions->EU->subregions->BG->vat_rate = 20;
$this->regions->EU->subregions->BG->reduced_vat_rate = 9;
$this->regions->EU->subregions->BG->tax_rate = 20;
$this->regions->EU->subregions->BG->reduced_tax_rate = 9;
$this->regions->EU->subregions->BG->apply_tax = false;
$this->regions->EU->subregions->CY = new \stdClass();
$this->regions->EU->subregions->CY->vat_rate = 19;
$this->regions->EU->subregions->CY->reduced_vat_rate = 9;
$this->regions->EU->subregions->CY->tax_rate = 19;
$this->regions->EU->subregions->CY->reduced_tax_rate = 9;
$this->regions->EU->subregions->CY->apply_tax = false;
$this->regions->EU->subregions->CZ = new \stdClass();
$this->regions->EU->subregions->CZ->vat_rate = 21;
$this->regions->EU->subregions->CZ->reduced_vat_rate = 15;
$this->regions->EU->subregions->CZ->tax_rate = 21;
$this->regions->EU->subregions->CZ->reduced_tax_rate = 15;
$this->regions->EU->subregions->CZ->apply_tax = false;
$this->regions->EU->subregions->DE = new \stdClass();
$this->regions->EU->subregions->DE->vat_rate = 19;
$this->regions->EU->subregions->DE->reduced_vat_rate = 7;
$this->regions->EU->subregions->DE->tax_rate = 19;
$this->regions->EU->subregions->DE->reduced_tax_rate = 7;
$this->regions->EU->subregions->DE->apply_tax = false;
$this->regions->EU->subregions->DK = new \stdClass();
$this->regions->EU->subregions->DK->vat_rate = 25;
$this->regions->EU->subregions->DK->reduced_vat_rate = 0;
$this->regions->EU->subregions->DK->tax_rate = 25;
$this->regions->EU->subregions->DK->reduced_tax_rate = 0;
$this->regions->EU->subregions->DK->apply_tax = false;
$this->regions->EU->subregions->EE = new \stdClass();
$this->regions->EU->subregions->EE->vat_rate = 20;
$this->regions->EU->subregions->EE->reduced_vat_rate = 9;
$this->regions->EU->subregions->EE->tax_rate = 20;
$this->regions->EU->subregions->EE->reduced_tax_rate = 9;
$this->regions->EU->subregions->EE->apply_tax = false;
$this->regions->EU->subregions->ES = new \stdClass();
$this->regions->EU->subregions->ES->vat_rate = 21;
$this->regions->EU->subregions->ES->reduced_vat_rate = 10;
$this->regions->EU->subregions->ES->tax_rate = 21;
$this->regions->EU->subregions->ES->reduced_tax_rate = 10;
$this->regions->EU->subregions->ES->apply_tax = false;
$this->regions->EU->subregions->FI = new \stdClass();
$this->regions->EU->subregions->FI->vat_rate = 24;
$this->regions->EU->subregions->FI->reduced_vat_rate = 14;
$this->regions->EU->subregions->FI->tax_rate = 24;
$this->regions->EU->subregions->FI->reduced_tax_rate = 14;
$this->regions->EU->subregions->FI->apply_tax = false;
$this->regions->EU->subregions->FR = new \stdClass();
$this->regions->EU->subregions->FR->vat_rate = 20;
$this->regions->EU->subregions->FR->reduced_vat_rate = 5.5;
$this->regions->EU->subregions->FR->tax_rate = 20;
$this->regions->EU->subregions->FR->reduced_tax_rate = 5.5;
$this->regions->EU->subregions->FR->apply_tax = false;
// $this->regions->EU->subregions->GB = new \stdClass();
// $this->regions->EU->subregions->GB->vat_rate = 20;
// $this->regions->EU->subregions->GB->reduced_vat_rate = 0;
// $this->regions->EU->subregions->GB->tax_rate = 20;
// $this->regions->EU->subregions->GB->reduced_tax_rate = 0;
// $this->regions->EU->subregions->GB->apply_tax = false;
$this->regions->EU->subregions->GR = new \stdClass();
$this->regions->EU->subregions->GR->vat_rate = 24;
$this->regions->EU->subregions->GR->reduced_vat_rate = 13;
$this->regions->EU->subregions->GR->tax_rate = 24;
$this->regions->EU->subregions->GR->reduced_tax_rate = 13;
$this->regions->EU->subregions->GR->apply_tax = false;
$this->regions->EU->subregions->HR = new \stdClass();
$this->regions->EU->subregions->HR->vat_rate = 25;
$this->regions->EU->subregions->HR->reduced_vat_rate = 5;
$this->regions->EU->subregions->HR->tax_rate = 25;
$this->regions->EU->subregions->HR->reduced_tax_rate = 5;
$this->regions->EU->subregions->HR->apply_tax = false;
$this->regions->EU->subregions->HU = new \stdClass();
$this->regions->EU->subregions->HU->vat_rate = 27;
$this->regions->EU->subregions->HU->reduced_vat_rate = 5;
$this->regions->EU->subregions->HU->tax_rate = 27;
$this->regions->EU->subregions->HU->reduced_tax_rate = 5;
$this->regions->EU->subregions->HU->apply_tax = false;
$this->regions->EU->subregions->IE = new \stdClass();
$this->regions->EU->subregions->IE->vat_rate = 23;
$this->regions->EU->subregions->IE->reduced_vat_rate = 0;
$this->regions->EU->subregions->IE->tax_rate = 23;
$this->regions->EU->subregions->IE->reduced_tax_rate = 0;
$this->regions->EU->subregions->IE->apply_tax = false;
$this->regions->EU->subregions->IT = new \stdClass();
$this->regions->EU->subregions->IT->vat_rate = 22;
$this->regions->EU->subregions->IT->reduced_vat_rate = 10;
$this->regions->EU->subregions->IT->tax_rate = 22;
$this->regions->EU->subregions->IT->reduced_tax_rate = 10;
$this->regions->EU->subregions->IT->apply_tax = false;
$this->regions->EU->subregions->LT = new \stdClass();
$this->regions->EU->subregions->LT->vat_rate = 21;
$this->regions->EU->subregions->LT->reduced_vat_rate = 9;
$this->regions->EU->subregions->LT->tax_rate = 21;
$this->regions->EU->subregions->LT->reduced_tax_rate = 9;
$this->regions->EU->subregions->LT->apply_tax = false;
$this->regions->EU->subregions->LU = new \stdClass();
$this->regions->EU->subregions->LU->vat_rate = 17;
$this->regions->EU->subregions->LU->reduced_vat_rate = 3;
$this->regions->EU->subregions->LU->tax_rate = 17;
$this->regions->EU->subregions->LU->reduced_tax_rate = 3;
$this->regions->EU->subregions->LU->apply_tax = false;
$this->regions->EU->subregions->LV = new \stdClass();
$this->regions->EU->subregions->LV->vat_rate = 21;
$this->regions->EU->subregions->LV->reduced_vat_rate = 12;
$this->regions->EU->subregions->LV->tax_rate = 21;
$this->regions->EU->subregions->LV->reduced_tax_rate = 12;
$this->regions->EU->subregions->LV->apply_tax = false;
$this->regions->EU->subregions->MT = new \stdClass();
$this->regions->EU->subregions->MT->vat_rate = 18;
$this->regions->EU->subregions->MT->reduced_vat_rate = 5;
$this->regions->EU->subregions->MT->tax_rate = 18;
$this->regions->EU->subregions->MT->reduced_tax_rate = 5;
$this->regions->EU->subregions->MT->apply_tax = false;
$this->regions->EU->subregions->NL = new \stdClass();
$this->regions->EU->subregions->NL->vat_rate = 21;
$this->regions->EU->subregions->NL->reduced_vat_rate = 9;
$this->regions->EU->subregions->NL->tax_rate = 21;
$this->regions->EU->subregions->NL->reduced_tax_rate = 9;
$this->regions->EU->subregions->NL->apply_tax = false;
$this->regions->EU->subregions->PT = new \stdClass();
$this->regions->EU->subregions->PT->vat_rate = 23;
$this->regions->EU->subregions->PT->reduced_vat_rate = 6;
$this->regions->EU->subregions->PT->tax_rate = 23;
$this->regions->EU->subregions->PT->reduced_tax_rate = 6;
$this->regions->EU->subregions->PT->apply_tax = false;
$this->regions->EU->subregions->RO = new \stdClass();
$this->regions->EU->subregions->RO->vat_rate = 19;
$this->regions->EU->subregions->RO->reduced_vat_rate = 5;
$this->regions->EU->subregions->RO->tax_rate = 19;
$this->regions->EU->subregions->RO->reduced_tax_rate = 5;
$this->regions->EU->subregions->RO->apply_tax = false;
$this->regions->EU->subregions->SE = new \stdClass();
$this->regions->EU->subregions->SE->vat_rate = 25;
$this->regions->EU->subregions->SE->reduced_vat_rate = 12;
$this->regions->EU->subregions->SE->tax_rate = 25;
$this->regions->EU->subregions->SE->reduced_tax_rate = 12;
$this->regions->EU->subregions->SE->apply_tax = false;
$this->regions->EU->subregions->SI = new \stdClass();
$this->regions->EU->subregions->SI->vat_rate = 22;
$this->regions->EU->subregions->SI->reduced_vat_rate = 9.5;
$this->regions->EU->subregions->SI->tax_rate = 22;
$this->regions->EU->subregions->SI->reduced_tax_rate = 9.5;
$this->regions->EU->subregions->SI->apply_tax = false;
$this->regions->EU->subregions->SK = new \stdClass();
$this->regions->EU->subregions->SK->vat_rate = 20;
$this->regions->EU->subregions->SK->reduced_vat_rate = 10;
$this->regions->EU->subregions->SK->tax_rate = 20;
$this->regions->EU->subregions->SK->reduced_tax_rate = 10;
$this->regions->EU->subregions->SK->apply_tax = false;
return $this;

View File

@ -35,12 +35,12 @@ class Rule extends BaseRule implements RuleInterface
if ($this->client->is_tax_exempt) {
return $this->taxExempt();
} elseif($this->client->company->tax_data->regions->US->tax_all_subregions || $this->client->company->tax_data->regions->US->subregions->{$this->client_subregion}->apply_tax) {
} elseif($this->client_region == 'US' && $this->isTaxableRegion()) {
$this->taxByType($item->tax_id);
return $this;
} elseif($this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions || $this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax) { //other regions outside of US
} elseif($this->isTaxableRegion()) { //other regions outside of US
}
return $this;
@ -122,9 +122,8 @@ class Rule extends BaseRule implements RuleInterface
public function calculateRates(): self
{
if($this->client_region != 'US' && $this->isTaxableRegion()) {
}
if($this->client_region != 'US' && $this->isTaxableRegion())
return $this;
return $this;
}

View File

@ -273,9 +273,9 @@ class EuTaxTest extends TestCase
$this->assertInstanceOf(Rule::class, $process);
$this->assertEquals(19, $process->vat_rate);
$this->assertEquals(19, $process->tax_rate);
$this->assertEquals(7, $process->reduced_vat_rate);
$this->assertEquals(7, $process->reduced_tax_rate);
}
@ -319,9 +319,9 @@ class EuTaxTest extends TestCase
$this->assertInstanceOf(Rule::class, $process);
$this->assertEquals(21, $process->vat_rate);
$this->assertEquals(21, $process->tax_rate);
$this->assertEquals(6, $process->reduced_vat_rate);
$this->assertEquals(6, $process->reduced_tax_rate);
}
@ -360,9 +360,9 @@ class EuTaxTest extends TestCase
$this->assertInstanceOf(Rule::class, $process);
$this->assertEquals(0, $process->vat_rate);
$this->assertEquals(0, $process->tax_rate);
$this->assertEquals(0, $process->reduced_vat_rate);
$this->assertEquals(0, $process->reduced_tax_rate);
}
@ -401,9 +401,9 @@ class EuTaxTest extends TestCase
$this->assertFalse($client->has_valid_vat_number);
$this->assertEquals(19, $process->vat_rate);
$this->assertEquals(19, $process->tax_rate);
$this->assertEquals(7, $process->reduced_vat_rate);
$this->assertEquals(7, $process->reduced_tax_rate);
}
@ -442,9 +442,9 @@ class EuTaxTest extends TestCase
$this->assertTrue($client->has_valid_vat_number);
$this->assertEquals(19, $process->vat_rate);
$this->assertEquals(19, $process->tax_rate);
$this->assertEquals(7, $process->reduced_vat_rate);
$this->assertEquals(7, $process->reduced_tax_rate);
}
@ -482,9 +482,9 @@ class EuTaxTest extends TestCase
$this->assertTrue($client->has_valid_vat_number);
$this->assertEquals(0, $process->vat_rate);
$this->assertEquals(0, $process->tax_rate);
$this->assertEquals(0, $process->reduced_vat_rate);
$this->assertEquals(0, $process->reduced_tax_rate);
}
@ -522,9 +522,9 @@ class EuTaxTest extends TestCase
$this->assertTrue($client->is_tax_exempt);
$this->assertEquals(0, $process->vat_rate);
$this->assertEquals(0, $process->tax_rate);
$this->assertEquals(0, $process->reduced_vat_rate);
$this->assertEquals(0, $process->reduced_tax_rate);
}
@ -562,9 +562,9 @@ class EuTaxTest extends TestCase
$this->assertTrue($client->is_tax_exempt);
$this->assertEquals(0, $process->vat_rate);
$this->assertEquals(0, $process->tax_rate);
$this->assertEquals(0, $process->reduced_vat_rate);
$this->assertEquals(0, $process->reduced_tax_rate);
}
@ -602,9 +602,9 @@ class EuTaxTest extends TestCase
$this->assertTrue($client->is_tax_exempt);
$this->assertEquals(0, $process->vat_rate);
$this->assertEquals(0, $process->tax_rate);
$this->assertEquals(0, $process->reduced_vat_rate);
$this->assertEquals(0, $process->reduced_tax_rate);
}