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:
parent
a6aeb61912
commit
9ea94b285b
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user