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

Refactor for taxes

This commit is contained in:
David Bomba 2023-04-22 17:07:22 +10:00
parent a6aeb61912
commit 9ea94b285b
6 changed files with 137 additions and 45 deletions

View File

@ -12,6 +12,7 @@
namespace App\DataMapper\Tax;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\Product;
use App\DataMapper\Tax\ZipTax\Response;
@ -117,6 +118,8 @@ class BaseRule implements RuleInterface
protected ?Response $tax_data;
public ?Invoice $invoice;
public function __construct()
{
}
@ -126,18 +129,16 @@ class BaseRule implements RuleInterface
return $this;
}
public function setClient(Client $client): self
public function setInvoice(Invoice $invoice): self
{
$this->client = $client;
$this->invoice = $invoice;
$this->client = $invoice->client;
$this->tax_data = new Response($invoice?->tax_data);
$this->resolveRegions();
return $this;
}
public function setTaxData(Response $tax_data): self
{
$this->tax_data = $tax_data;
return $this;
}
@ -176,10 +177,10 @@ class BaseRule implements RuleInterface
return $this;
}
elseif($this->client_region == 'AU'){
elseif($this->client_region == 'AU'){ //these are defaults and are only stubbed out for now, for AU we can actually remove these
$this->tax_rate1 = 10;
$this->tax_name1 = 'GST';
$this->tax_rate1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_rate;
$this->tax_name1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_name;
return $this;
}

View File

@ -14,19 +14,19 @@ namespace App\DataMapper\Tax;
class TaxModel
{
/** @var mixed $seller_subregion */
/** @var string $seller_subregion */
public string $seller_subregion = 'CA';
/** @var mixed $version */
/** @var string $version */
public string $version = 'alpha';
/** @var mixed $regions */
/** @var object $regions */
public object $regions;
/**
* __construct
*
* @param mixed $model
* @param TaxModel $model
* @return void
*/
public function __construct(public ?TaxModel $model = null)
@ -42,9 +42,9 @@ class TaxModel
/**
* Initializes the rules and builds any required data.
*
* @return void
* @return object
*/
public function init()
public function init(): object
{
$this->regions = new \stdClass();
$this->regions->US = new \stdClass();

View File

@ -65,6 +65,7 @@ class Response
public string $geoCounty = "";
public string $geoState = "";
public float $taxSales = 0;
public string $taxName = "";
public float $taxUse = 0;
public string $txbService = ""; // N = No, Y = Yes
public string $txbFreight = ""; // N = No, Y = Yes
@ -73,6 +74,8 @@ class Response
public float $citySalesTax = 0;
public float $cityUseTax = 0;
public string $cityTaxCode = "";
/* US SPECIFIC TAX CODES */
public float $countySalesTax = 0;
public float $countyUseTax = 0;
public string $countyTaxCode = "";
@ -93,7 +96,9 @@ class Response
public string $district5Code = "";
public float $district5SalesTax = 0;
public float $district5UseTax = 0;
public string $originDestination = "";
/* US SPECIFIC TAX CODES */
public string $originDestination = ""; // defines if the client origin is the locale where the tax is remitted to
public function __construct($data)
{

View File

@ -146,12 +146,9 @@ class InvoiceItemSum
$class = "App\DataMapper\Tax\\".$this->client->company->country()->iso_3166_2."\\Rule";
$tax_data = new Response($this->invoice?->tax_data);
$this->rule = new $class();
$this->rule
->setTaxData($tax_data)
->setClient($this->client)
->setInvoice($this->invoice)
->init();
$this->calc_tax = true;

View File

@ -190,7 +190,7 @@ class BaseRepository
$this->new_model = true;
if (is_array($model->line_items) && !($model instanceof RecurringInvoice)) {
$model->line_items = (collect($model->line_items))->map(function ($item) use ($model, $client) {
$model->line_items = (collect($model->line_items))->map(function ($item) use ($client) {
$item->notes = Helpers::processReservedKeywords($item->notes, $client);
return $item;

View File

@ -11,18 +11,18 @@
namespace Tests\Unit\Tax;
use Tests\TestCase;
use App\DataMapper\CompanySettings;
use App\DataMapper\Tax\DE\Rule;
use App\DataMapper\Tax\TaxModel;
use App\DataMapper\Tax\ZipTax\Response;
use App\Models\Client;
use App\Models\Company;
use App\Models\Invoice;
use App\Models\Product;
use Tests\MockAccountData;
use App\DataMapper\Tax\DE\Rule;
use App\DataMapper\Tax\TaxModel;
use App\DataMapper\CompanySettings;
use App\DataMapper\Tax\ZipTax\Response;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test App\Services\Tax\Providers\EuTax
@ -338,8 +338,18 @@ class EuTaxTest extends TestCase
'has_valid_vat_number' => false,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
@ -382,12 +392,21 @@ class EuTaxTest extends TestCase
'has_valid_vat_number' => false,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
$this->assertEquals('EU', $process->seller_region);
$this->assertEquals('BE', $process->client_subregion);
@ -428,11 +447,18 @@ $this->assertEquals('EU', $process->seller_region);
'has_valid_vat_number' => false,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setTaxData(new Response([
'geoState' => 'CA',
]));
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertEquals('EU', $process->seller_region);
@ -476,8 +502,18 @@ $this->assertEquals('EU', $process->seller_region);
'has_valid_vat_number' => false,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
@ -517,10 +553,21 @@ $this->assertEquals('EU', $process->seller_region);
'has_valid_vat_number' => true,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
$this->assertTrue($client->has_valid_vat_number);
@ -556,11 +603,22 @@ $this->assertEquals('EU', $process->seller_region);
'shipping_country_id' => 56,
'has_valid_vat_number' => true,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
$this->assertTrue($client->has_valid_vat_number);
@ -597,10 +655,21 @@ $this->assertEquals('EU', $process->seller_region);
'is_tax_exempt' => true,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
$this->assertTrue($client->is_tax_exempt);
@ -637,8 +706,18 @@ $this->assertEquals('EU', $process->seller_region);
'is_tax_exempt' => true,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
@ -676,11 +755,21 @@ $this->assertEquals('EU', $process->seller_region);
'is_tax_exempt' => true,
]);
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'client_id' => $client->id,
'user_id' => $this->user->id,
'status_id' => Invoice::STATUS_SENT,
'tax_data' => new Response([
'geoState' => 'CA',
]),
]);
$process = new Rule();
$process->setTaxData(new Response([]));
$process->setClient($client);
$process->setInvoice($invoice);
$process->init();
$this->assertInstanceOf(Rule::class, $process);
$this->assertTrue($client->is_tax_exempt);