mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Refactor for tax structure
This commit is contained in:
parent
1ab8097d44
commit
d471604862
@ -18,10 +18,45 @@ class BaseRule implements RuleInterface
|
|||||||
{
|
{
|
||||||
/** EU TAXES */
|
/** EU TAXES */
|
||||||
public bool $consumer_tax_exempt = false;
|
public bool $consumer_tax_exempt = false;
|
||||||
|
|
||||||
public bool $business_tax_exempt = true;
|
public bool $business_tax_exempt = true;
|
||||||
|
|
||||||
public bool $eu_business_tax_exempt = true;
|
public bool $eu_business_tax_exempt = true;
|
||||||
|
|
||||||
public bool $foreign_business_tax_exempt = true;
|
public bool $foreign_business_tax_exempt = true;
|
||||||
|
|
||||||
public bool $foreign_consumer_tax_exempt = true;
|
public bool $foreign_consumer_tax_exempt = true;
|
||||||
|
|
||||||
|
public array $eu_country_codes = [
|
||||||
|
'AT', // Austria
|
||||||
|
'BE', // Belgium
|
||||||
|
'BG', // Bulgaria
|
||||||
|
'CY', // Cyprus
|
||||||
|
'CZ', // Czech Republic
|
||||||
|
'DE', // Germany
|
||||||
|
'DK', // Denmark
|
||||||
|
'EE', // Estonia
|
||||||
|
'ES', // Spain
|
||||||
|
'FI', // Finland
|
||||||
|
'FR', // France
|
||||||
|
'GR', // Greece
|
||||||
|
'HR', // Croatia
|
||||||
|
'HU', // Hungary
|
||||||
|
'IE', // Ireland
|
||||||
|
'IT', // Italy
|
||||||
|
'LT', // Lithuania
|
||||||
|
'LU', // Luxembourg
|
||||||
|
'LV', // Latvia
|
||||||
|
'MT', // Malta
|
||||||
|
'NL', // Netherlands
|
||||||
|
'PL', // Poland
|
||||||
|
'PT', // Portugal
|
||||||
|
'RO', // Romania
|
||||||
|
'SE', // Sweden
|
||||||
|
'SI', // Slovenia
|
||||||
|
'SK', // Slovakia
|
||||||
|
];
|
||||||
|
|
||||||
/** EU TAXES */
|
/** EU TAXES */
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +80,11 @@ class BaseRule implements RuleInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function init(): self
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setClient(Client $client): self
|
public function setClient(Client $client): self
|
||||||
{
|
{
|
||||||
$this->client = $client;
|
$this->client = $client;
|
||||||
@ -108,4 +148,9 @@ class BaseRule implements RuleInterface
|
|||||||
{
|
{
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function calculateRates(): self
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,20 @@
|
|||||||
* @license https://www.elastic.co/licensing/elastic-license
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\DataMapper\Tax\de;
|
namespace App\DataMapper\Tax\DE;
|
||||||
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use App\DataMapper\Tax\BaseRule;
|
use App\DataMapper\Tax\BaseRule;
|
||||||
use App\DataMapper\Tax\RuleInterface;
|
use App\DataMapper\Tax\RuleInterface;
|
||||||
use App\DataMapper\Tax\ZipTax\Response;
|
use App\DataMapper\Tax\ZipTax\Response;
|
||||||
|
|
||||||
class Rule extends BaseRule implements RuleInterface
|
class Rule extends BaseRule implements RuleInterface
|
||||||
{
|
{
|
||||||
|
public string $vendor_country_code = 'DE';
|
||||||
|
|
||||||
|
public string $client_country_code = 'DE';
|
||||||
|
|
||||||
public bool $consumer_tax_exempt = false;
|
public bool $consumer_tax_exempt = false;
|
||||||
|
|
||||||
@ -41,7 +45,11 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
public string $tax_name3 = '';
|
public string $tax_name3 = '';
|
||||||
|
|
||||||
public float $tax_rate3 = 0;
|
public float $tax_rate3 = 0;
|
||||||
|
|
||||||
|
public float $vat_rate = 0;
|
||||||
|
|
||||||
|
public float $reduced_vat_rate = 0;
|
||||||
|
|
||||||
protected ?Client $client;
|
protected ?Client $client;
|
||||||
|
|
||||||
protected ?Response $tax_data;
|
protected ?Response $tax_data;
|
||||||
@ -50,6 +58,14 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function init(): self
|
||||||
|
{
|
||||||
|
$this->client_country_code = $this->client->shipping_country ? $this->client->shipping_country->iso_3166_2 : $this->client->country->iso_3166_2;
|
||||||
|
$this->calculateRates();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setClient(Client $client): self
|
public function setClient(Client $client): self
|
||||||
{
|
{
|
||||||
$this->client = $client;
|
$this->client = $client;
|
||||||
@ -103,7 +119,7 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
|
|
||||||
public function taxReduced(): self
|
public function taxReduced(): self
|
||||||
{
|
{
|
||||||
$this->tax_rate1 = $this->vat_reduced_rate;
|
$this->tax_rate1 = $this->reduced_vat_rate;
|
||||||
$this->tax_name1 = 'ermäßigte MwSt.';
|
$this->tax_name1 = 'ermäßigte MwSt.';
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -159,4 +175,46 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function calculateRates(): self
|
||||||
|
{
|
||||||
|
|
||||||
|
if(
|
||||||
|
(($this->vendor_country_code == $this->client_country_code) && $this->client->has_valid_vat_number && $this->business_tax_exempt) || //same country / exempt for tax / valid vat number
|
||||||
|
(in_array($this->client_country_code, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt) //eu country / exempt for tax / valid vat number
|
||||||
|
) {
|
||||||
|
$this->vat_rate = 0;
|
||||||
|
$this->reduced_vat_rate = 0;
|
||||||
|
nlog("euro zone and tax exempt");
|
||||||
|
}
|
||||||
|
elseif(!in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && ($this->foreign_consumer_tax_exempt || $this->foreign_business_tax_exempt)) //foreign + tax exempt
|
||||||
|
{
|
||||||
|
$this->vat_rate = 0;
|
||||||
|
$this->reduced_vat_rate = 0;
|
||||||
|
nlog("foreign and tax exempt");
|
||||||
|
}
|
||||||
|
elseif(in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && !$this->client->has_valid_vat_number) //eu country / no valid vat
|
||||||
|
{
|
||||||
|
if(($this->vendor_country_code != $this->client_country_code) && $this->client->company->tax_data->regions->EU->has_sales_above_threshold)
|
||||||
|
{
|
||||||
|
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->vat_rate;
|
||||||
|
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_vat_rate;
|
||||||
|
nlog("eu zone with sales above threshold");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->vat_rate;
|
||||||
|
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_vat_rate;
|
||||||
|
nlog("same eu country with");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nlog("default tax");
|
||||||
|
$this->vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->vat_rate;
|
||||||
|
$this->reduced_vat_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_vat_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -16,6 +16,8 @@ use App\DataMapper\Tax\ZipTax\Response;
|
|||||||
|
|
||||||
interface RuleInterface
|
interface RuleInterface
|
||||||
{
|
{
|
||||||
|
public function init();
|
||||||
|
|
||||||
public function tax();
|
public function tax();
|
||||||
|
|
||||||
public function taxByType(?int $type);
|
public function taxByType(?int $type);
|
||||||
@ -39,4 +41,6 @@ interface RuleInterface
|
|||||||
public function setClient(Client $client);
|
public function setClient(Client $client);
|
||||||
|
|
||||||
public function setTaxData(Response $tax_data);
|
public function setTaxData(Response $tax_data);
|
||||||
|
|
||||||
|
public function calculateRates();
|
||||||
}
|
}
|
@ -9,7 +9,7 @@
|
|||||||
* @license https://www.elastic.co/licensing/elastic-license
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\DataMapper\Tax\us;
|
namespace App\DataMapper\Tax\US;
|
||||||
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
@ -199,7 +199,7 @@ class InvoiceItemSum
|
|||||||
if ($this->invoice->company->tax_all_products || $this->item->tax_id != '') {
|
if ($this->invoice->company->tax_all_products || $this->item->tax_id != '') {
|
||||||
$this->rule->tax();
|
$this->rule->tax();
|
||||||
} else {
|
} else {
|
||||||
$this->rule->taxByType($this->item->tax_id);
|
$this->rule->init()->taxByType($this->item->tax_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->item->tax_name1 = $this->rule->tax_name1;
|
$this->item->tax_name1 = $this->rule->tax_name1;
|
||||||
|
@ -158,6 +158,10 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Company> $companies
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Company> $companies
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankIntegration> $bank_integrations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Company> $companies
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Account extends BaseModel
|
class Account extends BaseModel
|
||||||
|
@ -39,6 +39,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class BankAccount extends BaseModel
|
class BankAccount extends BaseModel
|
||||||
|
@ -82,6 +82,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class BankIntegration extends BaseModel
|
class BankIntegration extends BaseModel
|
||||||
|
@ -291,6 +291,23 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoice> $recurring_invoices
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoice> $recurring_invoices
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $contacts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Credit> $credits
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Expense> $expenses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $gateway_tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $primary_contact
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Project> $projects
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Quote> $quotes
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringExpense> $recurring_expenses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoice> $recurring_invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Client extends BaseModel implements HasLocalePreference
|
class Client extends BaseModel implements HasLocalePreference
|
||||||
|
@ -158,6 +158,11 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $quote_invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $quote_invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $recurring_invoice_invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $recurring_invoice_invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $credit_invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\InvoiceInvitation> $invoice_invitations
|
||||||
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $quote_invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $recurring_invoice_invitations
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class ClientContact extends Authenticatable implements HasLocalePreference
|
class ClientContact extends Authenticatable implements HasLocalePreference
|
||||||
|
@ -596,6 +596,50 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Vendor> $vendors
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Vendor> $vendors
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Webhook> $webhooks
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Webhook> $webhooks
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $all_activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $all_documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankIntegration> $bank_integrations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransactionRule> $bank_transaction_rules
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $bank_transactions
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $client_contacts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Client> $clients
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyGateway> $company_gateways
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $contacts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Credit> $credits
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Design> $designs
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ExpenseCategory> $expense_categories
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Expense> $expenses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\GroupSetting> $group_settings
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\GroupSetting> $groups
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentTerm> $payment_terms
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Product> $products
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Project> $projects
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrder> $purchase_orders
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Quote> $quotes
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringExpense> $recurring_expenses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoice> $recurring_invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Scheduler> $schedulers
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Subscription> $subscriptions
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_log_relation
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Scheduler> $task_schedulers
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\TaskStatus> $task_statuses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\TaxRate> $tax_rates
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens_hashed
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Design> $user_designs
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentTerm> $user_payment_terms
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Vendor> $vendors
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Webhook> $webhooks
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Company extends BaseModel
|
class Company extends BaseModel
|
||||||
|
@ -99,6 +99,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class CompanyGateway extends BaseModel
|
class CompanyGateway extends BaseModel
|
||||||
|
@ -88,6 +88,9 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $token
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $token
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $token
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $users
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class CompanyUser extends Pivot
|
class CompanyUser extends Pivot
|
||||||
|
@ -234,6 +234,13 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Credit extends BaseModel
|
class Credit extends BaseModel
|
||||||
|
@ -137,6 +137,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Expense extends BaseModel
|
class Expense extends BaseModel
|
||||||
|
@ -35,6 +35,7 @@ namespace App\Models;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class GatewayType extends StaticModel
|
class GatewayType extends StaticModel
|
||||||
|
@ -68,6 +68,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Client> $clients
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Client> $clients
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Client> $clients
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class GroupSetting extends StaticModel
|
class GroupSetting extends StaticModel
|
||||||
|
@ -268,6 +268,15 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\InvoiceInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\InvoiceInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Credit> $credits
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Expense> $expenses
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\InvoiceInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Invoice extends BaseModel
|
class Invoice extends BaseModel
|
||||||
|
@ -167,6 +167,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Paymentable> $paymentables
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Paymentable> $paymentables
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Credit> $credits
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Paymentable> $paymentables
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Payment extends BaseModel
|
class Payment extends BaseModel
|
||||||
|
@ -105,6 +105,7 @@ use League\CommonMark\CommonMarkConverter;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Product extends BaseModel
|
class Product extends BaseModel
|
||||||
|
@ -86,6 +86,8 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Project extends BaseModel
|
class Project extends BaseModel
|
||||||
|
@ -35,6 +35,7 @@ use App\Utils\Traits\MakesHash;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Proposal extends BaseModel
|
class Proposal extends BaseModel
|
||||||
|
@ -222,6 +222,12 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class PurchaseOrder extends BaseModel
|
class PurchaseOrder extends BaseModel
|
||||||
|
@ -209,6 +209,10 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Quote extends BaseModel
|
class Quote extends BaseModel
|
||||||
|
@ -146,6 +146,7 @@ use Illuminate\Support\Carbon;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class RecurringExpense extends BaseModel
|
class RecurringExpense extends BaseModel
|
||||||
|
@ -214,6 +214,11 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringInvoiceInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class RecurringInvoice extends BaseModel
|
class RecurringInvoice extends BaseModel
|
||||||
|
@ -206,6 +206,11 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringQuoteInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringQuoteInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Quote> $quotes
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Quote> $quotes
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\RecurringQuoteInvitation> $invitations
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Quote> $quotes
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class RecurringQuote extends BaseModel
|
class RecurringQuote extends BaseModel
|
||||||
|
@ -98,6 +98,7 @@ use Illuminate\Support\Carbon;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Task extends BaseModel
|
class Task extends BaseModel
|
||||||
|
@ -188,6 +188,13 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Client> $clients
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Company> $companies
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $contacts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class User extends Authenticatable implements MustVerifyEmail
|
class User extends Authenticatable implements MustVerifyEmail
|
||||||
|
@ -132,6 +132,10 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $contacts
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $contacts
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $primary_contact
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $primary_contact
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $contacts
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $primary_contact
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class Vendor extends BaseModel
|
class Vendor extends BaseModel
|
||||||
|
@ -124,6 +124,8 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
|
||||||
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
|
||||||
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class VendorContact extends Authenticatable implements HasLocalePreference
|
class VendorContact extends Authenticatable implements HasLocalePreference
|
||||||
|
@ -1,165 +0,0 @@
|
|||||||
<?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;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use App\DataMapper\Tax\de\Rule;
|
|
||||||
use App\Services\Tax\VatNumberCheck;
|
|
||||||
class EuTax
|
|
||||||
{
|
|
||||||
public Rule $rule;
|
|
||||||
|
|
||||||
private string $vendor_country_code;
|
|
||||||
|
|
||||||
private string $client_country_code;
|
|
||||||
|
|
||||||
private bool $valid_vat_number = false;
|
|
||||||
|
|
||||||
private float $vat_rate = 0.0;
|
|
||||||
|
|
||||||
private float $reduced_vat_rate = 0.0;
|
|
||||||
|
|
||||||
private array $eu_country_codes = [
|
|
||||||
'AT', // Austria
|
|
||||||
'BE', // Belgium
|
|
||||||
'BG', // Bulgaria
|
|
||||||
'CY', // Cyprus
|
|
||||||
'CZ', // Czech Republic
|
|
||||||
'DE', // Germany
|
|
||||||
'DK', // Denmark
|
|
||||||
'EE', // Estonia
|
|
||||||
'ES', // Spain
|
|
||||||
'FI', // Finland
|
|
||||||
'FR', // France
|
|
||||||
'GR', // Greece
|
|
||||||
'HR', // Croatia
|
|
||||||
'HU', // Hungary
|
|
||||||
'IE', // Ireland
|
|
||||||
'IT', // Italy
|
|
||||||
'LT', // Lithuania
|
|
||||||
'LU', // Luxembourg
|
|
||||||
'LV', // Latvia
|
|
||||||
'MT', // Malta
|
|
||||||
'NL', // Netherlands
|
|
||||||
'PL', // Poland
|
|
||||||
'PT', // Portugal
|
|
||||||
'RO', // Romania
|
|
||||||
'SE', // Sweden
|
|
||||||
'SI', // Slovenia
|
|
||||||
'SK', // Slovakia
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct(protected Company $company, protected Client $client)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need to have a setting that allows a user to define their annual turnover, or whether they have breached their thresholds */
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
$this->setUp()
|
|
||||||
->validateVat()
|
|
||||||
->calculateVatRates();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasValidVatNumber(): bool
|
|
||||||
{
|
|
||||||
return $this->valid_vat_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVatRate(): float
|
|
||||||
{
|
|
||||||
return $this->vat_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVatReducedRate(): float
|
|
||||||
{
|
|
||||||
return $this->reduced_vat_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVendorCountryCode(): string
|
|
||||||
{
|
|
||||||
return $this->vendor_country_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClientCountryCode(): string
|
|
||||||
{
|
|
||||||
return $this->client_country_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setUp(): self
|
|
||||||
{
|
|
||||||
$this->vendor_country_code = Str::lower($this->company->country()->iso_3166_2);
|
|
||||||
|
|
||||||
$this->client_country_code = $this->client->shipping_country ? Str::lower($this->client->shipping_country->iso_3166_2) : Str::lower($this->client->country->iso_3166_2);
|
|
||||||
|
|
||||||
$class = "App\\DataMapper\\Tax\\".$this->vendor_country_code."\\Rule";
|
|
||||||
|
|
||||||
$this->rule = new $class();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function validateVat(): self
|
|
||||||
{
|
|
||||||
$vat_check = (new VatNumberCheck($this->client->vat_number, $this->client_country_code))->run();
|
|
||||||
|
|
||||||
$this->valid_vat_number = $vat_check->isValid();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function calculateVatRates(): self
|
|
||||||
{
|
|
||||||
|
|
||||||
if(
|
|
||||||
(($this->vendor_country_code == $this->client_country_code) && $this->valid_vat_number && $this->rule->business_tax_exempt) || //same country / exempt for tax / valid vat number
|
|
||||||
(in_array($this->client_country_code, $this->eu_country_codes) && $this->valid_vat_number && $this->rule->eu_business_tax_exempt) //eu country / exempt for tax / valid vat number
|
|
||||||
) {
|
|
||||||
$this->vat_rate = 0;
|
|
||||||
$this->reduced_vat_rate = 0;
|
|
||||||
nlog("euro zone and tax exempt");
|
|
||||||
}
|
|
||||||
elseif(!in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && ($this->rule->foreign_consumer_tax_exempt || $this->rule->foreign_business_tax_exempt)) //foreign + tax exempt
|
|
||||||
{
|
|
||||||
$this->vat_rate = 0;
|
|
||||||
$this->reduced_vat_rate = 0;
|
|
||||||
nlog("foreign and tax exempt");
|
|
||||||
}
|
|
||||||
elseif(in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && !$this->valid_vat_number) //eu country / no valid vat
|
|
||||||
{
|
|
||||||
if(($this->vendor_country_code != $this->client_country_code) && $this->company->tax_data->regions->EU->has_sales_above_threshold)
|
|
||||||
{
|
|
||||||
$this->vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->vat_rate;
|
|
||||||
$this->reduced_vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_vat_rate;
|
|
||||||
nlog("eu zone with sales above threshold");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->company->country()->iso_3166_2}->vat_rate;
|
|
||||||
$this->reduced_vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->company->country()->iso_3166_2}->reduced_vat_rate;
|
|
||||||
nlog("same eu country with");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nlog("default tax");
|
|
||||||
$this->vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->company->country()->iso_3166_2}->vat_rate;
|
|
||||||
$this->reduced_vat_rate = $this->company->tax_data->regions->EU->subregions->{$this->company->country()->iso_3166_2}->reduced_vat_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,5 +23,15 @@ class TaxService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validateVat(): self
|
||||||
|
{
|
||||||
|
$client_country_code = $this->client->shipping_country ? $this->client->shipping_country->iso_3166_2 : $this->client->country->iso_3166_2;
|
||||||
|
|
||||||
|
$vat_check = (new VatNumberCheck($this->client->vat_number, $client_country_code))->run();
|
||||||
|
|
||||||
|
$this->client->has_valid_vat_number = $vat_check->isValid();
|
||||||
|
$this->client->saveQuietly();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,8 +22,7 @@ return new class extends Migration
|
|||||||
Schema::table('companies', function (Illuminate\Database\Schema\Blueprint $table) {
|
Schema::table('companies', function (Illuminate\Database\Schema\Blueprint $table) {
|
||||||
$table->mediumText('tax_data')->nullable()->change();
|
$table->mediumText('tax_data')->nullable()->change();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,10 +15,9 @@ use Tests\TestCase;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
use App\DataMapper\Tax\de\Rule;
|
use App\DataMapper\Tax\DE\Rule;
|
||||||
use App\DataMapper\Tax\TaxModel;
|
use App\DataMapper\Tax\TaxModel;
|
||||||
use App\DataMapper\CompanySettings;
|
use App\DataMapper\CompanySettings;
|
||||||
use App\Services\Tax\Providers\EuTax;
|
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
|
||||||
@ -66,22 +65,24 @@ class EuTaxTest extends TestCase
|
|||||||
'company_id' => $company->id,
|
'company_id' => $company->id,
|
||||||
'country_id' => 276,
|
'country_id' => 276,
|
||||||
'shipping_country_id' => 276,
|
'shipping_country_id' => 276,
|
||||||
|
'has_valid_vat_number' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$process = new EuTax($company, $client);
|
$process = new Rule();
|
||||||
$process->run();
|
$process->setClient($client);
|
||||||
|
$process->init();
|
||||||
|
|
||||||
$this->assertEquals('de', $process->getVendorCountryCode());
|
$this->assertEquals('DE', $process->vendor_country_code);
|
||||||
|
|
||||||
$this->assertEquals('de', $process->getClientCountryCode());
|
$this->assertEquals('DE', $process->client_country_code);
|
||||||
|
|
||||||
$this->assertFalse($process->hasValidVatNumber());
|
$this->assertFalse($client->has_valid_vat_number);
|
||||||
|
|
||||||
$this->assertInstanceOf(Rule::class, $process->rule);
|
$this->assertInstanceOf(Rule::class, $process);
|
||||||
|
|
||||||
$this->assertEquals(19, $process->getVatRate());
|
$this->assertEquals(19, $process->vat_rate);
|
||||||
|
|
||||||
$this->assertEquals(7, $process->getVatReducedRate());
|
$this->assertEquals(7, $process->reduced_vat_rate);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -110,22 +111,25 @@ class EuTaxTest extends TestCase
|
|||||||
'company_id' => $company->id,
|
'company_id' => $company->id,
|
||||||
'country_id' => 56,
|
'country_id' => 56,
|
||||||
'shipping_country_id' => 56,
|
'shipping_country_id' => 56,
|
||||||
|
'has_valid_vat_number' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$process = new EuTax($company, $client);
|
$process = new Rule();
|
||||||
$process->run();
|
$process->setClient($client);
|
||||||
|
$process->init();
|
||||||
|
|
||||||
$this->assertEquals('de', $process->getVendorCountryCode());
|
|
||||||
|
|
||||||
$this->assertEquals('be', $process->getClientCountryCode());
|
$this->assertEquals('DE', $process->vendor_country_code);
|
||||||
|
|
||||||
$this->assertFalse($process->hasValidVatNumber());
|
$this->assertEquals('BE', $process->client_country_code);
|
||||||
|
|
||||||
$this->assertInstanceOf(Rule::class, $process->rule);
|
$this->assertFalse($client->has_valid_vat_number);
|
||||||
|
|
||||||
$this->assertEquals(21, $process->getVatRate());
|
$this->assertInstanceOf(Rule::class, $process);
|
||||||
|
|
||||||
$this->assertEquals(6, $process->getVatReducedRate());
|
$this->assertEquals(21, $process->vat_rate);
|
||||||
|
|
||||||
|
$this->assertEquals(6, $process->reduced_vat_rate);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -146,25 +150,71 @@ class EuTaxTest extends TestCase
|
|||||||
'company_id' => $company->id,
|
'company_id' => $company->id,
|
||||||
'country_id' => 840,
|
'country_id' => 840,
|
||||||
'shipping_country_id' => 840,
|
'shipping_country_id' => 840,
|
||||||
|
'has_valid_vat_number' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$process = new EuTax($company, $client);
|
$process = new Rule();
|
||||||
$process->run();
|
$process->setClient($client);
|
||||||
|
$process->init();
|
||||||
|
|
||||||
$this->assertEquals('de', $process->getVendorCountryCode());
|
|
||||||
|
|
||||||
$this->assertEquals('us', $process->getClientCountryCode());
|
$this->assertEquals('DE', $process->vendor_country_code);
|
||||||
|
|
||||||
$this->assertFalse($process->hasValidVatNumber());
|
$this->assertEquals('US', $process->client_country_code);
|
||||||
|
|
||||||
$this->assertInstanceOf(Rule::class, $process->rule);
|
$this->assertFalse($client->has_valid_vat_number);
|
||||||
|
|
||||||
$this->assertEquals(0, $process->getVatRate());
|
$this->assertInstanceOf(Rule::class, $process);
|
||||||
|
|
||||||
$this->assertEquals(0, $process->getVatReducedRate());
|
$this->assertEquals(0, $process->vat_rate);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $process->reduced_vat_rate);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSubThresholdCorrectRate()
|
||||||
|
{
|
||||||
|
|
||||||
|
$settings = CompanySettings::defaults();
|
||||||
|
$settings->country_id = '276'; // germany
|
||||||
|
|
||||||
|
$tax_data = new TaxModel();
|
||||||
|
$tax_data->seller_region = 'DE';
|
||||||
|
$tax_data->seller_subregion = 'DE';
|
||||||
|
$tax_data->regions->EU->has_sales_above_threshold = false;
|
||||||
|
$tax_data->regions->EU->tax_all = true;
|
||||||
|
|
||||||
|
$company = Company::factory()->create([
|
||||||
|
'account_id' => $this->account->id,
|
||||||
|
'settings' => $settings,
|
||||||
|
'tax_data' => $tax_data,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$client = Client::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'country_id' => 56,
|
||||||
|
'shipping_country_id' => 56,
|
||||||
|
'has_valid_vat_number' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$process = new Rule();
|
||||||
|
$process->setClient($client);
|
||||||
|
$process->init();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Rule::class, $process);
|
||||||
|
|
||||||
|
$this->assertFalse($client->has_valid_vat_number);
|
||||||
|
|
||||||
|
$this->assertEquals(19, $process->vat_rate);
|
||||||
|
|
||||||
|
$this->assertEquals(7, $process->reduced_vat_rate);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//tests with valid vat.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user