1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 08:21:34 +02:00

Refactor for taxes

This commit is contained in:
David Bomba 2023-04-24 11:47:48 +10:00
parent 252effabef
commit f356ddd845
6 changed files with 71 additions and 45 deletions

View File

@ -15,6 +15,7 @@ use App\Models\Client;
use App\Models\Invoice;
use App\Models\Product;
use App\DataMapper\Tax\ZipTax\Response;
use App\DataProviders\USStates;
class BaseRule implements RuleInterface
{
@ -116,7 +117,7 @@ class BaseRule implements RuleInterface
protected ?Client $client;
protected ?Response $tax_data;
public ?Response $tax_data;
public mixed $invoice;
@ -129,29 +130,41 @@ class BaseRule implements RuleInterface
return $this;
}
public function setInvoice(mixed $invoice): self
public function setEntity(mixed $invoice): self
{
$this->invoice = $invoice;
$this->configTaxData();
$this->client = $invoice->client;
$this->configTaxData()
->resolveRegions();
$this->tax_data = new Response($this->invoice->tax_data);
$this->resolveRegions();
return $this;
}
private function configTaxData(): self
{
if(!array_key_exists($this->client->country->iso_3166_2, $this->region_codes)) {
throw new \Exception('Automatic tax calculations not supported for this country');
}
$this->client_region = $this->region_codes[$this->client->country->iso_3166_2];
if($this->invoice->tax_data && $this->invoice->status_id > 1)
return $this;
//determine if we are taxing locally or if we are taxing globally
// $this->invoice->tax_data = $this->invoice->client->tax_data;
$this->invoice->tax_data = $this->invoice->client->tax_data ?: new Response([]);
if(strlen($this->invoice->tax_data?->originDestination) == 0 && $this->client->company->tax_data->seller_subregion != $this->client_subregion) {
$tax_data = $this->invoice->tax_data;
$tax_data->originDestination = "D";
$this->invoice->tax_data = $tax_data;
$this->invoice->saveQuietly();
}
return $this;
}
@ -160,20 +173,25 @@ class BaseRule implements RuleInterface
private function resolveRegions(): self
{
if(!array_key_exists($this->client->country->iso_3166_2, $this->region_codes))
throw new \Exception('Automatic tax calculations not supported for this country');
$this->client_region = $this->region_codes[$this->client->country->iso_3166_2];
match($this->client_region){
'US' => $this->client_subregion = $this->tax_data->geoState,
'US' => $this->client_subregion = strlen($this->invoice?->tax_data?->geoState) > 1 ? $this->invoice?->tax_data?->geoState : $this->getUSState(),
'EU' => $this->client_subregion = $this->client->country->iso_3166_2,
'AU' => $this->client_subregion = 'AU',
default => $this->client_subregion = $this->client->country->iso_3166_2,
};
return $this;
}
private function getUSState(): string
{
try {
return USStates::getState(strlen($this->client->postal_code) > 1 ? $this->client->postal_code : $this->client->shipping_postal_code);
} catch (\Exception $e) {
return 'CA';
}
}
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

@ -148,7 +148,7 @@ class InvoiceItemSum
$this->rule = new $class();
$this->rule
->setInvoice($this->invoice)
->setEntity($this->invoice)
->init();
$this->calc_tax = true;

View File

@ -480,14 +480,14 @@ class SchedulerTest extends TestCase
$c = Client::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'number' => rand(1000, 100000),
'number' => rand(1000, 10000000),
'name' => 'A fancy client'
]);
$c2 = Client::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'number' => rand(1000, 100000),
'number' => rand(1000, 10000000),
'name' => 'A fancy client'
]);

View File

@ -349,7 +349,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
@ -403,7 +403,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
@ -458,7 +458,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
@ -513,7 +513,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
@ -564,7 +564,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
@ -615,7 +615,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
@ -666,7 +666,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
@ -717,7 +717,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
@ -766,7 +766,7 @@ class EuTaxTest extends TestCase
]);
$process = new Rule();
$process->setInvoice($invoice);
$process->setEntity($invoice);
$process->init();

View File

@ -102,10 +102,13 @@ class SumTaxTest extends TestCase
$this->company->tax_data = $tax_data;
$this->company->save();
$tax_data = new TaxData($this->response);
$client = Client::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'country_id' => 840,
'tax_data' => $tax_data,
]);
$invoice = InvoiceFactory::create($this->company->id, $this->user->id);
@ -114,7 +117,7 @@ class SumTaxTest extends TestCase
$line_items = [];
$invoice->tax_data = new TaxData($this->response);
$invoice->tax_data = $tax_data;
$line_item = new InvoiceItem();
$line_item->quantity = 1;
@ -131,7 +134,6 @@ class SumTaxTest extends TestCase
$line_items = $invoice->line_items;
$this->assertEquals(10, $invoice->amount);
$this->assertEquals("", $line_items[0]->tax_name1);
$this->assertEquals(0, $line_items[0]->tax_rate1);
@ -152,19 +154,23 @@ class SumTaxTest extends TestCase
$this->company->tax_data = $tax_data;
$this->company->save();
$client = Client::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'country_id' => 840,
]);
$tax_data = new TaxData($this->response);
$invoice = InvoiceFactory::create($this->company->id, $this->user->id);
$invoice->client_id = $client->id;
$invoice->uses_inclusive_taxes = false;
$client = Client::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'country_id' => 840,
'tax_data' => $tax_data,
]);
$line_items = [];
$invoice = InvoiceFactory::create($this->company->id, $this->user->id);
$invoice->client_id = $client->id;
$invoice->uses_inclusive_taxes = false;
$line_items = [];
$invoice->tax_data = $tax_data;
$invoice->tax_data = new TaxData($this->response);
$line_item = new InvoiceItem;
$line_item->quantity = 1;

View File

@ -107,6 +107,7 @@ class UsTaxTest extends TestCase
'shipping_country_id' => 840,
'has_valid_vat_number' => false,
'postal_code' => $postal_code,
'tax_data' => new Response($this->mock_response),
]);
$invoice = Invoice::factory()->create([
@ -309,6 +310,7 @@ class UsTaxTest extends TestCase
'shipping_country_id' => 276,
'has_valid_vat_number' => false,
'postal_code' => 'xx',
'tax_data' => new Response($this->mock_response),
]);
$invoice = Invoice::factory()->create([
@ -353,18 +355,18 @@ class UsTaxTest extends TestCase
{
$invoice = $this->invoiceStub('92582');
$client = $invoice->client;
$client->is_tax_exempt = false;
$client->save();
$invoice->client->is_tax_exempt = false;
$invoice->client->tax_data = new Response($this->mock_response);
$company = $invoice->company;
$tax_data = $company->tax_data;
$invoice->client->push();
$tax_data = $invoice->company->tax_data;
$tax_data->regions->US->has_sales_above_threshold = true;
$tax_data->regions->US->tax_all_subregions = true;
$company->tax_data = $tax_data;
$company->save();
$invoice->company->tax_data = $tax_data;
$invoice->company->push();
$invoice = $invoice->calc()->getInvoice()->service()->markSent()->save();