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; namespace App\DataMapper\Tax;
use App\Models\Client; use App\Models\Client;
use App\Models\Invoice;
use App\Models\Product; use App\Models\Product;
use App\DataMapper\Tax\ZipTax\Response; use App\DataMapper\Tax\ZipTax\Response;
@ -117,6 +118,8 @@ class BaseRule implements RuleInterface
protected ?Response $tax_data; protected ?Response $tax_data;
public ?Invoice $invoice;
public function __construct() public function __construct()
{ {
} }
@ -126,18 +129,16 @@ class BaseRule implements RuleInterface
return $this; 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(); $this->resolveRegions();
return $this;
}
public function setTaxData(Response $tax_data): self
{
$this->tax_data = $tax_data;
return $this; return $this;
} }
@ -176,10 +177,10 @@ class BaseRule implements RuleInterface
return $this; 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_rate1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_rate;
$this->tax_name1 = 'GST'; $this->tax_name1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_name;
return $this; return $this;
} }

View File

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

View File

@ -65,6 +65,7 @@ class Response
public string $geoCounty = ""; public string $geoCounty = "";
public string $geoState = ""; public string $geoState = "";
public float $taxSales = 0; public float $taxSales = 0;
public string $taxName = "";
public float $taxUse = 0; public float $taxUse = 0;
public string $txbService = ""; // N = No, Y = Yes public string $txbService = ""; // N = No, Y = Yes
public string $txbFreight = ""; // N = No, Y = Yes public string $txbFreight = ""; // N = No, Y = Yes
@ -73,6 +74,8 @@ class Response
public float $citySalesTax = 0; public float $citySalesTax = 0;
public float $cityUseTax = 0; public float $cityUseTax = 0;
public string $cityTaxCode = ""; public string $cityTaxCode = "";
/* US SPECIFIC TAX CODES */
public float $countySalesTax = 0; public float $countySalesTax = 0;
public float $countyUseTax = 0; public float $countyUseTax = 0;
public string $countyTaxCode = ""; public string $countyTaxCode = "";
@ -93,7 +96,9 @@ class Response
public string $district5Code = ""; public string $district5Code = "";
public float $district5SalesTax = 0; public float $district5SalesTax = 0;
public float $district5UseTax = 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) public function __construct($data)
{ {

View File

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

View File

@ -190,7 +190,7 @@ class BaseRepository
$this->new_model = true; $this->new_model = true;
if (is_array($model->line_items) && !($model instanceof RecurringInvoice)) { 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); $item->notes = Helpers::processReservedKeywords($item->notes, $client);
return $item; return $item;

View File

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