1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-11 21:52:35 +01:00
invoiceninja/app/Services/Tax/Providers/TaxProvider.php

265 lines
6.7 KiB
PHP
Raw Normal View History

2023-03-26 22:46:26 +02:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Services\Tax\Providers;
use App\Models\Client;
use App\Models\Company;
class TaxProvider
{
public array $eu_countries = [
"AT",
"BE",
"BG",
"HR",
"CY",
"CZ",
"DK",
"EE",
"FI",
"FR",
"DE",
"GR",
"HU",
"IE",
"IT",
"LV",
"LT",
"LU",
"MT",
"NL",
"PL",
"PT",
"RO",
"SK",
"SI",
"ES",
"SE"
];
private string $provider = ZipTax::class;
2024-01-14 05:05:00 +01:00
2023-03-26 22:46:26 +02:00
private mixed $api_credentials;
2023-06-02 07:53:33 +02:00
private bool $updated_client = false;
2023-05-17 06:07:48 +02:00
public function __construct(public Company $company, public ?Client $client = null)
2023-03-26 22:46:26 +02:00
{
}
2024-01-14 05:05:00 +01:00
2023-06-02 07:53:33 +02:00
/**
* Flag if tax has been updated successfull.
*
* @return bool
*/
public function updatedTaxStatus(): bool
{
return $this->updated_client;
}
2023-05-25 02:38:43 +02:00
/**
* updateCompanyTaxData
*
* @return self
*/
2023-03-26 22:46:26 +02:00
public function updateCompanyTaxData(): self
{
try {
2023-10-26 04:57:44 +02:00
$this->configureProvider($this->provider, $this->company->country()->iso_3166_2); //hard coded for now to one provider, but we'll be able to swap these out later
2023-03-26 22:46:26 +02:00
$company_details = [
'address2' => $this->company->settings->address2,
'address1' => $this->company->settings->address1,
'city' => $this->company->settings->city,
'state' => $this->company->settings->state,
'postal_code' => $this->company->settings->postal_code,
'country' => $this->company->country()->name,
];
2023-03-26 22:46:26 +02:00
2023-06-02 07:53:33 +02:00
$tax_provider = new $this->provider($company_details);
2023-03-26 22:46:26 +02:00
2023-06-02 07:53:33 +02:00
$tax_provider->setApiCredentials($this->api_credentials);
2024-01-14 05:05:00 +01:00
2023-06-02 07:53:33 +02:00
$tax_data = $tax_provider->run();
if($tax_data) {
$this->company->origin_tax_data = $tax_data;
$this->company->saveQuietly();
$this->updated_client = true;
}
2024-01-14 05:05:00 +01:00
2023-10-26 04:57:44 +02:00
} catch(\Exception $e) {
2023-06-02 07:53:33 +02:00
nlog("Could not updated company tax data: " . $e->getMessage());
}
2023-03-26 22:46:26 +02:00
return $this;
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* updateClientTaxData
*
* @return self
*/
2023-03-26 22:46:26 +02:00
public function updateClientTaxData(): self
{
2023-05-17 06:07:48 +02:00
$this->configureProvider($this->provider, $this->client->country->iso_3166_2); //hard coded for now to one provider, but we'll be able to swap these out later
2023-03-26 22:46:26 +02:00
2024-01-14 05:05:00 +01:00
$billing_details = [
2023-03-26 22:46:26 +02:00
'address2' => $this->client->address2,
2023-06-02 07:53:33 +02:00
'address1' => $this->client->address1,
2023-03-26 22:46:26 +02:00
'city' => $this->client->city,
'state' => $this->client->state,
'postal_code' => $this->client->postal_code,
2023-06-02 07:53:33 +02:00
'country' => $this->client->country->name,
2023-03-26 22:46:26 +02:00
];
2024-01-14 05:05:00 +01:00
$shipping_details = [
2023-03-26 22:46:26 +02:00
'address2' => $this->client->shipping_address2,
2023-06-02 07:53:33 +02:00
'address1' => $this->client->shipping_address1,
2023-03-26 22:46:26 +02:00
'city' => $this->client->shipping_city,
'state' => $this->client->shipping_state,
'postal_code' => $this->client->shipping_postal_code,
2023-06-22 08:54:30 +02:00
'country' => $this->client->shipping_country()->exists() ? $this->client->shipping_country->name : $this->client->country->name,
2023-03-26 22:46:26 +02:00
];
2023-05-25 02:38:43 +02:00
$taxable_address = $this->taxShippingAddress() ? $shipping_details : $billing_details;
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
$tax_provider = new $this->provider($taxable_address);
2023-03-26 22:46:26 +02:00
$tax_provider->setApiCredentials($this->api_credentials);
2024-01-14 05:05:00 +01:00
2023-03-26 22:46:26 +02:00
$tax_data = $tax_provider->run();
2023-06-02 07:53:33 +02:00
// nlog($tax_data);
2024-01-14 05:05:00 +01:00
2023-06-02 07:53:33 +02:00
if($tax_data) {
$this->client->tax_data = $tax_data;
$this->client->saveQuietly();
$this->updated_client = true;
}
2023-03-26 22:46:26 +02:00
return $this;
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* taxShippingAddress
*
* @return bool
*/
private function taxShippingAddress(): bool
{
2024-01-14 05:05:00 +01:00
2023-10-26 04:57:44 +02:00
if($this->client->shipping_country_id == "840" && strlen($this->client->shipping_postal_code) > 3) {
2023-05-25 02:38:43 +02:00
return true;
2023-10-26 04:57:44 +02:00
}
2023-03-26 22:46:26 +02:00
2023-05-25 02:38:43 +02:00
return false;
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* configureProvider
*
* @param string $provider
* @param string $country_code
* @return self
*/
2023-05-17 06:07:48 +02:00
private function configureProvider(?string $provider, string $country_code): self
2023-03-26 22:46:26 +02:00
{
2023-10-26 04:57:44 +02:00
match($country_code) {
2023-03-26 22:46:26 +02:00
'US' => $this->configureZipTax(),
"AT" => $this->configureEuTax(),
"BE" => $this->configureEuTax(),
"BG" => $this->configureEuTax(),
"HR" => $this->configureEuTax(),
"CY" => $this->configureEuTax(),
"CZ" => $this->configureEuTax(),
"DK" => $this->configureEuTax(),
"EE" => $this->configureEuTax(),
"FI" => $this->configureEuTax(),
"FR" => $this->configureEuTax(),
"DE" => $this->configureEuTax(),
"GR" => $this->configureEuTax(),
"HU" => $this->configureEuTax(),
"IE" => $this->configureEuTax(),
"IT" => $this->configureEuTax(),
"LV" => $this->configureEuTax(),
"LT" => $this->configureEuTax(),
"LU" => $this->configureEuTax(),
"MT" => $this->configureEuTax(),
"NL" => $this->configureEuTax(),
"PL" => $this->configureEuTax(),
"PT" => $this->configureEuTax(),
"RO" => $this->configureEuTax(),
"SK" => $this->configureEuTax(),
"SI" => $this->configureEuTax(),
"ES" => $this->configureEuTax(),
"SE" => $this->configureEuTax(),
default => $this->noTaxRegionDefined(),
};
return $this;
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* configureEuTax
*
* @return self
*/
2023-03-26 22:46:26 +02:00
private function configureEuTax(): self
{
2023-10-19 02:23:13 +02:00
throw new \Exception("No tax region defined for this country");
2023-03-26 22:46:26 +02:00
$this->provider = EuTax::class;
return $this;
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* noTaxRegionDefined
*
* @return void
*/
2023-05-17 06:07:48 +02:00
private function noTaxRegionDefined()
2023-03-26 22:46:26 +02:00
{
2023-03-27 05:47:01 +02:00
throw new \Exception("No tax region defined for this country");
2023-05-17 06:07:48 +02:00
// return $this;
2023-03-26 22:46:26 +02:00
}
2024-01-14 05:05:00 +01:00
2023-05-25 02:38:43 +02:00
/**
* configureZipTax
*
* @return self
*/
2023-03-26 22:46:26 +02:00
private function configureZipTax(): self
{
2023-10-26 04:57:44 +02:00
if(!config('services.tax.zip_tax.key')) {
2023-06-02 07:53:33 +02:00
throw new \Exception("ZipTax API key not set in .env file");
2023-10-26 04:57:44 +02:00
}
2023-03-26 22:46:26 +02:00
$this->api_credentials = config('services.tax.zip_tax.key');
2024-01-14 05:05:00 +01:00
2023-06-02 07:53:33 +02:00
$this->provider = ZipTax::class;
2023-03-26 22:46:26 +02:00
return $this;
}
2023-10-26 04:57:44 +02:00
}