Merge pull request #8427 from turbo124/v5-stable

v5.5.102
This commit is contained in:
David Bomba 2023-04-04 07:44:16 +10:00 committed by GitHub
commit b1d4e77cb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
227 changed files with 351205 additions and 337499 deletions

View File

@ -83,6 +83,66 @@ http://localhost:8000/client/login - For Client Portal
user: user@example.com
pass: password
```
## Developers Guide
### App Design
The API and client portal have been developed using [Laravel](https://laravel.com) if you wish to contribute to this project familiarity with Laravel is essential.
When inspecting functionality of the API, the best place to start would be in the routes/api.php file which describes all of the availabe API endpoints. The controller methods then describe all the entry points into each domain of the application, ie InvoiceController / QuoteController
The average API request follows this path into the application.
* Middleware processes the request initially inspecting the domain being requested + provides the authentication layer.
* The request then passes into a Form Request (Type hinted in the controller methods) which is used to provide authorization and also validation of the request. If successful, the request is then passed into the controller method where it is digested, here is an example:
```php
public function store(StoreInvoiceRequest $request)
{
$invoice = $this->invoice_repo->save($request->all(), InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
$invoice = $invoice->service()
->fillDefaults()
->triggeredActions($request)
->adjustInventory()
->save();
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
return $this->itemResponse($invoice);
}
```
Here for example we are storing a new invoice, we pass the validated request along with a factory into the invoice repository where it is processed and saved.
The returned invoice then passes through its service class (app/Services/Invoice) where various actions are performed.
A event is then fired which notifies listeners in the application (app/Providers/EventServiceProvider) which perform non blocking sub tasks
Finally the invoice is transformed (app/Transformers/) and returned as a response via Fractal.
### Developer environment
Using the Quick Hosting Setup describe above you can quickly get started building out your development environment. Instead of using
```
composer i -o --no-dev
```
use
```
composer i -o
```
This provides the developer tools including phpunit which allows the test suite to be run.
If you are considering contributing back to the main repository, please add in any tests for new functionality / modifications. This will greatly increase the chances of your PR being accepted
Also, if you plan any additions for the main repository, you may want to discuss this with us first on Slack where we can assist with any technical information and provide advice.
## Credits
* [Hillel Coren](https://hillelcoren.com/)

View File

@ -1 +1 @@
5.5.96
5.5.102

View File

@ -188,6 +188,7 @@ class DemoMode extends Command
$company_token->account_id = $account->id;
$company_token->name = 'test token';
$company_token->token = 'TOKEN';
$company_token->is_system = true;
$company_token->save();
$u2->companies()->attach($company->id, [

View File

@ -51,8 +51,8 @@ class ReactBuilder extends Command
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
if (str_contains($file->getFileName(), '.js') && !strpos($file->getFileName(), '.json')) {
if (str_contains($file->getFileName(), 'index.')) {
if ($file->getExtension() == 'js') {
if (str_contains($file->getFileName(), 'index-')) {
$includes .= '<script type="module" crossorigin src="/react/'.$file->getFileName().'"></script>'."\n";
} else {
$includes .= '<link rel="modulepreload" href="/react/'.$file->getFileName().'">'."\n";

View File

@ -449,6 +449,8 @@ class CompanySettings extends BaseSettings
public $mailgun_domain = '';
public $mailgun_endpoint = 'api.mailgun.net'; //api.eu.mailgun.net
public $auto_bill_standard_invoices = false;
public $email_alignment = 'center'; // center , left, right
@ -471,12 +473,10 @@ class CompanySettings extends BaseSettings
public $client_initiated_payments_minimum = 0;
public $client_initiated_payments_recurring = false;
public $sync_invoice_quote_columns = true;
public static $casts = [
'client_initiated_payments_recurring'=> 'bool',
'mailgun_endpoint' => 'string',
'client_initiated_payments' => 'bool',
'client_initiated_payments_minimum' => 'float',
'sync_invoice_quote_columns' => 'bool',
@ -505,7 +505,6 @@ class CompanySettings extends BaseSettings
'purchase_order_design_id' => 'string',
'purchase_order_footer' => 'string',
'purchase_order_number_pattern' => 'string',
'purchase_order_number_counter' => 'int',
'page_numbering_alignment' => 'string',
'page_numbering' => 'bool',
'auto_archive_invoice_cancelled' => 'bool',
@ -537,7 +536,6 @@ class CompanySettings extends BaseSettings
'reminder_send_time' => 'int',
'email_sending_method' => 'string',
'gmail_sending_user_id' => 'string',
'currency_id' => 'string',
'counter_number_applied' => 'string',
'quote_number_applied' => 'string',
'email_subject_custom1' => 'string',

View File

@ -59,7 +59,11 @@ class InvoiceItem
public $type_id = '1'; //1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee, 6 expense
public $tax_id = '';
public static $casts = [
'tax_id' => 'string',
'type_id' => 'string',
'quantity' => 'float',
'cost' => 'float',

View File

@ -11,14 +11,14 @@
namespace App\DataMapper\Schedule;
class ScheduleEntity
class EmailRecord
{
/**
* Defines the template name
*
* @var string
*/
public string $template = 'schedule_entity';
public string $template = 'email_record';
/**
* Defines the template name

View File

@ -0,0 +1,156 @@
<?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\DataMapper\Tax;
use App\DataMapper\Tax\ZipTax\Response;
use App\Models\Client;
class BaseRule implements RuleInterface
{
/** EU TAXES */
public bool $consumer_tax_exempt = false;
public bool $business_tax_exempt = true;
public bool $eu_business_tax_exempt = true;
public bool $foreign_business_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 */
/** US TAXES */
/** US TAXES */
public string $tax_name1 = '';
public float $tax_rate1 = 0;
public string $tax_name2 = '';
public float $tax_rate2 = 0;
public string $tax_name3 = '';
public float $tax_rate3 = 0;
protected ?Client $client;
protected ?Response $tax_data;
public function __construct()
{
}
public function init(): self
{
return $this;
}
public function setClient(Client $client): self
{
$this->client = $client;
return $this;
}
public function setTaxData(Response $tax_data): self
{
$this->tax_data = $tax_data;
return $this;
}
public function tax($product_tax_type): self
{
return $this;
}
public function taxByType($product_tax_type): self
{
return $this;
}
public function taxReduced(): self
{
return $this;
}
public function taxExempt(): self
{
return $this;
}
public function taxDigital(): self
{
return $this;
}
public function taxService(): self
{
return $this;
}
public function taxShipping(): self
{
return $this;
}
public function taxPhysical(): self
{
return $this;
}
public function default(): self
{
return $this;
}
public function override(): self
{
return $this;
}
public function calculateRates(): self
{
return $this;
}
}

View File

@ -0,0 +1,233 @@
<?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\DataMapper\Tax\DE;
use App\Models\Client;
use App\Models\Product;
use Illuminate\Support\Str;
use App\DataMapper\Tax\BaseRule;
use App\DataMapper\Tax\RuleInterface;
use App\DataMapper\Tax\ZipTax\Response;
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 $business_tax_exempt = false;
public bool $eu_business_tax_exempt = true;
public bool $foreign_business_tax_exempt = true;
public bool $foreign_consumer_tax_exempt = true;
public string $tax_name1 = '';
public float $tax_rate1 = 0;
public string $tax_name2 = '';
public float $tax_rate2 = 0;
public string $tax_name3 = '';
public float $tax_rate3 = 0;
public float $vat_rate = 0;
public float $reduced_vat_rate = 0;
protected ?Client $client;
protected ?Response $tax_data;
public function __construct()
{
}
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
{
$this->client = $client;
return $this;
}
public function setTaxData(Response $tax_data): self
{
$this->tax_data = $tax_data;
return $this;
}
//need to add logic here to capture if
public function tax($type): self
{
if ($this->client->is_tax_exempt) {
return $this->taxExempt();
} elseif ($this->client->company->tax_data->regions->EU->tax_all) {
$this->tax_rate1 = $this->vat_rate;
$this->tax_name1 = "MwSt.";
return $this;
}
if ($type)
return $this->taxByType($type);
return $this;
}
public function taxByType($product_tax_type): self
{
if ($this->client->is_tax_exempt) {
return $this->taxExempt();
}
if(!$product_tax_type)
return $this;
match($product_tax_type){
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt(),
Product::PRODUCT_TYPE_DIGITAL => $this->taxDigital(),
Product::PRODUCT_TYPE_SERVICE => $this->taxService(),
Product::PRODUCT_TYPE_SHIPPING => $this->taxShipping(),
Product::PRODUCT_TYPE_PHYSICAL => $this->taxPhysical(),
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced(),
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override(),
default => $this->default(),
};
return $this;
}
public function taxReduced(): self
{
$this->tax_rate1 = $this->reduced_vat_rate;
$this->tax_name1 = 'ermäßigte MwSt.';
return $this;
}
public function taxExempt(): self
{
$this->tax_name1 = '';
$this->tax_rate1 = 0;
return $this;
}
public function taxDigital(): self
{
$this->tax();
return $this;
}
public function taxService(): self
{
$this->tax();
return $this;
}
public function taxShipping(): self
{
$this->tax();
return $this;
}
public function taxPhysical(): self
{
$this->tax();
return $this;
}
public function default(): self
{
$this->tax_name1 = '';
$this->tax_rate1 = 0;
return $this;
}
public function override(): self
{
return $this;
}
public function calculateRates(): self
{
if ($this->client->is_tax_exempt) {
$this->vat_rate = 0;
$this->reduced_vat_rate = 0;
}
elseif($this->client_country_code != $this->vendor_country_code && in_array($this->client_country_code, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt)
{
$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 {
$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("default tax");
}
return $this;
}
}

View File

@ -11,7 +11,36 @@
namespace App\DataMapper\Tax;
use App\Models\Client;
use App\DataMapper\Tax\ZipTax\Response;
interface RuleInterface
{
public function run();
public function init();
public function tax(mixed $type);
public function taxByType($type);
public function taxExempt();
public function taxDigital();
public function taxService();
public function taxShipping();
public function taxPhysical();
public function taxReduced();
public function default();
public function override();
public function setClient(Client $client);
public function setTaxData(Response $tax_data);
public function calculateRates();
}

View File

@ -0,0 +1,31 @@
<?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\DataMapper\Tax;
use App\DataMapper\Tax\ZipTax\Response;
/**
* InvoiceTaxData
*
* Definition for the invoice tax data structure
*/
class TaxData
{
public int $updated_at;
public function __construct(public Response $origin)
{
foreach($origin as $key => $value) {
$this->{$key} = $value;
}
}
}

View File

@ -0,0 +1,316 @@
<?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\DataMapper\Tax;
class TaxModel
{
// public string $seller_region = 'US';
public string $seller_subregion = 'CA';
public object $regions;
public function __construct(public ?TaxModel $model = null)
{
if(!$this->model)
$this->regions = $this->init();
else
$this->regions = $model;
}
public function init()
{
$this->regions = new \stdClass();
$this->regions->US = new \stdClass();
$this->regions->EU = new \stdClass();
$this->usRegion()
->euRegion();
return $this->regions;
}
private function usRegion(): self
{
$this->regions->US->has_sales_above_threshold = false;
$this->regions->US->tax_all_subregions = false;
$this->usSubRegions();
return $this;
}
private function euRegion(): self
{
$this->regions->EU->has_sales_above_threshold = false;
$this->regions->EU->tax_all_subregions = false;
$this->regions->EU->vat_threshold = 10000;
$this->euSubRegions();
return $this;
}
private function usSubRegions(): self
{
$this->regions->US->subregions = new \stdClass();
$this->regions->US->subregions->AL = new \stdClass();
$this->regions->US->subregions->AL->apply_tax = false;
$this->regions->US->subregions->AK = new \stdClass();
$this->regions->US->subregions->AK->apply_tax = false;
$this->regions->US->subregions->AZ = new \stdClass();
$this->regions->US->subregions->AZ->apply_tax = false;
$this->regions->US->subregions->AR = new \stdClass();
$this->regions->US->subregions->AR->apply_tax = false;
$this->regions->US->subregions->CA = new \stdClass();
$this->regions->US->subregions->CA->apply_tax = false;
$this->regions->US->subregions->CO = new \stdClass();
$this->regions->US->subregions->CO->apply_tax = false;
$this->regions->US->subregions->CT = new \stdClass();
$this->regions->US->subregions->CT->apply_tax = false;
$this->regions->US->subregions->DE = new \stdClass();
$this->regions->US->subregions->DE->apply_tax = false;
$this->regions->US->subregions->FL = new \stdClass();
$this->regions->US->subregions->FL->apply_tax = false;
$this->regions->US->subregions->GA = new \stdClass();
$this->regions->US->subregions->GA->apply_tax = false;
$this->regions->US->subregions->HI = new \stdClass();
$this->regions->US->subregions->HI->apply_tax = false;
$this->regions->US->subregions->ID = new \stdClass();
$this->regions->US->subregions->ID->apply_tax = false;
$this->regions->US->subregions->IL = new \stdClass();
$this->regions->US->subregions->IL->apply_tax = false;
$this->regions->US->subregions->IN = new \stdClass();
$this->regions->US->subregions->IN->apply_tax = false;
$this->regions->US->subregions->IA = new \stdClass();
$this->regions->US->subregions->IA->apply_tax = false;
$this->regions->US->subregions->KS = new \stdClass();
$this->regions->US->subregions->KS->apply_tax = false;
$this->regions->US->subregions->KY = new \stdClass();
$this->regions->US->subregions->KY->apply_tax = false;
$this->regions->US->subregions->LA = new \stdClass();
$this->regions->US->subregions->LA->apply_tax = false;
$this->regions->US->subregions->ME = new \stdClass();
$this->regions->US->subregions->ME->apply_tax = false;
$this->regions->US->subregions->MD = new \stdClass();
$this->regions->US->subregions->MD->apply_tax = false;
$this->regions->US->subregions->MA = new \stdClass();
$this->regions->US->subregions->MA->apply_tax = false;
$this->regions->US->subregions->MI = new \stdClass();
$this->regions->US->subregions->MI->apply_tax = false;
$this->regions->US->subregions->MN = new \stdClass();
$this->regions->US->subregions->MN->apply_tax = false;
$this->regions->US->subregions->MS = new \stdClass();
$this->regions->US->subregions->MS->apply_tax = false;
$this->regions->US->subregions->MO = new \stdClass();
$this->regions->US->subregions->MO->apply_tax = false;
$this->regions->US->subregions->MT = new \stdClass();
$this->regions->US->subregions->MT->apply_tax = false;
$this->regions->US->subregions->NE = new \stdClass();
$this->regions->US->subregions->NE->apply_tax = false;
$this->regions->US->subregions->NV = new \stdClass();
$this->regions->US->subregions->NV->apply_tax = false;
$this->regions->US->subregions->NH = new \stdClass();
$this->regions->US->subregions->NH->apply_tax = false;
$this->regions->US->subregions->NJ = new \stdClass();
$this->regions->US->subregions->NJ->apply_tax = false;
$this->regions->US->subregions->NM = new \stdClass();
$this->regions->US->subregions->NM->apply_tax = false;
$this->regions->US->subregions->NY = new \stdClass();
$this->regions->US->subregions->NY->apply_tax = false;
$this->regions->US->subregions->NC = new \stdClass();
$this->regions->US->subregions->NC->apply_tax = false;
$this->regions->US->subregions->ND = new \stdClass();
$this->regions->US->subregions->ND->apply_tax = false;
$this->regions->US->subregions->OH = new \stdClass();
$this->regions->US->subregions->OH->apply_tax = false;
$this->regions->US->subregions->OK = new \stdClass();
$this->regions->US->subregions->OK->apply_tax = false;
$this->regions->US->subregions->OR = new \stdClass();
$this->regions->US->subregions->OR->apply_tax = false;
$this->regions->US->subregions->PA = new \stdClass();
$this->regions->US->subregions->PA->apply_tax = false;
$this->regions->US->subregions->RI = new \stdClass();
$this->regions->US->subregions->RI->apply_tax = false;
$this->regions->US->subregions->SC = new \stdClass();
$this->regions->US->subregions->SC->apply_tax = false;
$this->regions->US->subregions->SD = new \stdClass();
$this->regions->US->subregions->SD->apply_tax = false;
$this->regions->US->subregions->TN = new \stdClass();
$this->regions->US->subregions->TN->apply_tax = false;
$this->regions->US->subregions->TX = new \stdClass();
$this->regions->US->subregions->TX->apply_tax = false;
$this->regions->US->subregions->UT = new \stdClass();
$this->regions->US->subregions->UT->apply_tax = false;
$this->regions->US->subregions->VT = new \stdClass();
$this->regions->US->subregions->VT->apply_tax = false;
$this->regions->US->subregions->VA = new \stdClass();
$this->regions->US->subregions->VA->apply_tax = false;
$this->regions->US->subregions->WA = new \stdClass();
$this->regions->US->subregions->WA->apply_tax = false;
$this->regions->US->subregions->WV = new \stdClass();
$this->regions->US->subregions->WV->apply_tax = false;
$this->regions->US->subregions->WI = new \stdClass();
$this->regions->US->subregions->WI->apply_tax = false;
$this->regions->US->subregions->WY = new \stdClass();
$this->regions->US->subregions->WY->apply_tax = false;
return $this;
}
private function euSubRegions(): self
{
$this->regions->EU->subregions = new \stdClass();
$this->regions->EU->subregions->AT = new \stdClass();
$this->regions->EU->subregions->AT->vat_rate = 21;
$this->regions->EU->subregions->AT->reduced_vat_rate = 11;
$this->regions->EU->subregions->AT->apply_tax = false;
$this->regions->EU->subregions->BE = new \stdClass();
$this->regions->EU->subregions->BE->vat_rate = 21;
$this->regions->EU->subregions->BE->reduced_vat_rate = 6;
$this->regions->EU->subregions->BE->apply_tax = false;
$this->regions->EU->subregions->BG = new \stdClass();
$this->regions->EU->subregions->BG->vat_rate = 20;
$this->regions->EU->subregions->BG->reduced_vat_rate = 9;
$this->regions->EU->subregions->BG->apply_tax = false;
$this->regions->EU->subregions->CY = new \stdClass();
$this->regions->EU->subregions->CY->vat_rate = 19;
$this->regions->EU->subregions->CY->reduced_vat_rate = 9;
$this->regions->EU->subregions->CY->apply_tax = false;
$this->regions->EU->subregions->CZ = new \stdClass();
$this->regions->EU->subregions->CZ->vat_rate = 21;
$this->regions->EU->subregions->CZ->reduced_vat_rate = 15;
$this->regions->EU->subregions->CZ->apply_tax = false;
$this->regions->EU->subregions->DE = new \stdClass();
$this->regions->EU->subregions->DE->vat_rate = 19;
$this->regions->EU->subregions->DE->reduced_vat_rate = 7;
$this->regions->EU->subregions->DE->apply_tax = false;
$this->regions->EU->subregions->DK = new \stdClass();
$this->regions->EU->subregions->DK->vat_rate = 25;
$this->regions->EU->subregions->DK->reduced_vat_rate = 0;
$this->regions->EU->subregions->DK->apply_tax = false;
$this->regions->EU->subregions->EE = new \stdClass();
$this->regions->EU->subregions->EE->vat_rate = 20;
$this->regions->EU->subregions->EE->reduced_vat_rate = 9;
$this->regions->EU->subregions->EE->apply_tax = false;
$this->regions->EU->subregions->ES = new \stdClass();
$this->regions->EU->subregions->ES->vat_rate = 21;
$this->regions->EU->subregions->ES->reduced_vat_rate = 10;
$this->regions->EU->subregions->ES->apply_tax = false;
$this->regions->EU->subregions->FI = new \stdClass();
$this->regions->EU->subregions->FI->vat_rate = 24;
$this->regions->EU->subregions->FI->reduced_vat_rate = 14;
$this->regions->EU->subregions->FI->apply_tax = false;
$this->regions->EU->subregions->FR = new \stdClass();
$this->regions->EU->subregions->FR->vat_rate = 20;
$this->regions->EU->subregions->FR->reduced_vat_rate = 5.5;
$this->regions->EU->subregions->FR->apply_tax = false;
// $this->regions->EU->subregions->GB = new \stdClass();
// $this->regions->EU->subregions->GB->vat_rate = 20;
// $this->regions->EU->subregions->GB->reduced_vat_rate = 0;
// $this->regions->EU->subregions->GB->apply_tax = false;
$this->regions->EU->subregions->GR = new \stdClass();
$this->regions->EU->subregions->GR->vat_rate = 24;
$this->regions->EU->subregions->GR->reduced_vat_rate = 13;
$this->regions->EU->subregions->GR->apply_tax = false;
$this->regions->EU->subregions->HR = new \stdClass();
$this->regions->EU->subregions->HR->vat_rate = 25;
$this->regions->EU->subregions->HR->reduced_vat_rate = 5;
$this->regions->EU->subregions->HR->apply_tax = false;
$this->regions->EU->subregions->HU = new \stdClass();
$this->regions->EU->subregions->HU->vat_rate = 27;
$this->regions->EU->subregions->HU->reduced_vat_rate = 5;
$this->regions->EU->subregions->HU->apply_tax = false;
$this->regions->EU->subregions->IE = new \stdClass();
$this->regions->EU->subregions->IE->vat_rate = 23;
$this->regions->EU->subregions->IE->reduced_vat_rate = 0;
$this->regions->EU->subregions->IE->apply_tax = false;
$this->regions->EU->subregions->IT = new \stdClass();
$this->regions->EU->subregions->IT->vat_rate = 22;
$this->regions->EU->subregions->IT->reduced_vat_rate = 10;
$this->regions->EU->subregions->IT->apply_tax = false;
$this->regions->EU->subregions->LT = new \stdClass();
$this->regions->EU->subregions->LT->vat_rate = 21;
$this->regions->EU->subregions->LT->reduced_vat_rate = 9;
$this->regions->EU->subregions->LT->apply_tax = false;
$this->regions->EU->subregions->LU = new \stdClass();
$this->regions->EU->subregions->LU->vat_rate = 17;
$this->regions->EU->subregions->LU->reduced_vat_rate = 3;
$this->regions->EU->subregions->LU->apply_tax = false;
$this->regions->EU->subregions->LV = new \stdClass();
$this->regions->EU->subregions->LV->vat_rate = 21;
$this->regions->EU->subregions->LV->reduced_vat_rate = 12;
$this->regions->EU->subregions->LV->apply_tax = false;
$this->regions->EU->subregions->MT = new \stdClass();
$this->regions->EU->subregions->MT->vat_rate = 18;
$this->regions->EU->subregions->MT->reduced_vat_rate = 5;
$this->regions->EU->subregions->MT->apply_tax = false;
$this->regions->EU->subregions->NL = new \stdClass();
$this->regions->EU->subregions->NL->vat_rate = 21;
$this->regions->EU->subregions->NL->reduced_vat_rate = 9;
$this->regions->EU->subregions->NL->apply_tax = false;
$this->regions->EU->subregions->PT = new \stdClass();
$this->regions->EU->subregions->PT->vat_rate = 23;
$this->regions->EU->subregions->PT->reduced_vat_rate = 6;
$this->regions->EU->subregions->PT->apply_tax = false;
$this->regions->EU->subregions->RO = new \stdClass();
$this->regions->EU->subregions->RO->vat_rate = 19;
$this->regions->EU->subregions->RO->reduced_vat_rate = 5;
$this->regions->EU->subregions->RO->apply_tax = false;
$this->regions->EU->subregions->SE = new \stdClass();
$this->regions->EU->subregions->SE->vat_rate = 25;
$this->regions->EU->subregions->SE->reduced_vat_rate = 12;
$this->regions->EU->subregions->SE->apply_tax = false;
$this->regions->EU->subregions->SI = new \stdClass();
$this->regions->EU->subregions->SI->vat_rate = 22;
$this->regions->EU->subregions->SI->reduced_vat_rate = 9.5;
$this->regions->EU->subregions->SI->apply_tax = false;
$this->regions->EU->subregions->SK = new \stdClass();
$this->regions->EU->subregions->SK->vat_rate = 20;
$this->regions->EU->subregions->SK->reduced_vat_rate = 10;
$this->regions->EU->subregions->SK->apply_tax = false;
return $this;
}
}

View File

@ -0,0 +1,161 @@
<?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\DataMapper\Tax\US;
use App\Models\Client;
use App\Models\Product;
use App\DataMapper\Tax\RuleInterface;
use App\DataMapper\Tax\ZipTax\Response;
class Rule implements RuleInterface
{
public string $tax_name1 = '';
public float $tax_rate1 = 0;
public string $tax_name2 = '';
public float $tax_rate2 = 0;
public string $tax_name3 = '';
public float $tax_rate3 = 0;
public ?Client $client;
public ?Response $tax_data;
public function __construct()
{
}
public function override()
{
return $this;
}
public function setTaxData(Response $tax_data): self
{
$this->tax_data = $tax_data;
return $this;
}
public function setClient(Client $client):self
{
$this->client = $client;
return $this;
}
public function tax($type): self
{
if ($this->client->is_tax_exempt) {
return $this->taxExempt();
}
else if($this->client->company->tax_data->regions->US->tax_all){
$this->tax_rate1 = $this->tax_data->taxSales * 100;
$this->tax_name1 = "{$this->tax_data->geoState} Sales Tax";
return $this;
}
if($type)
return $this->taxByType($type);
return $this;
}
public function taxByType($product_tax_type): self
{
if(!$product_tax_type)
return $this;
match($product_tax_type){
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt(),
Product::PRODUCT_TYPE_DIGITAL => $this->taxDigital(),
Product::PRODUCT_TYPE_SERVICE => $this->taxService(),
Product::PRODUCT_TYPE_SHIPPING => $this->taxShipping(),
Product::PRODUCT_TYPE_PHYSICAL => $this->taxPhysical(),
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced(),
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override(),
default => $this->default(),
};
return $this;
}
public function taxExempt(): self
{
$this->tax_name1 = '';
$this->tax_rate1 = 0;
return $this;
}
public function taxDigital(): self
{
$this->default();
return $this;
}
public function taxService(): self
{
if($this->tax_data->txbService == 'Y')
$this->default();
return $this;
}
public function taxShipping(): self
{
if($this->tax_data->txbFreight == 'Y')
$this->default();
return $this;
}
public function taxPhysical(): self
{
$this->default();
return $this;
}
public function default(): self
{
$this->tax_rate1 = $this->tax_data->taxSales * 100;
$this->tax_name1 = "{$this->tax_data->geoState} Sales Tax";
return $this;
}
public function taxReduced(): self
{
$this->default();
return $this;
}
public function init(): self
{
return $this;
}
public function calculateRates(): self
{
return $this;
}
}

View File

@ -18,8 +18,7 @@ class Response
public int $rCode = 100;
/**
* ["results" => [
* [
* [
* "geoPostalCode" => "92582",
* "geoCity" => "SAN JACINTO",
* "geoCounty" => "RIVERSIDE",
@ -54,13 +53,56 @@ class Response
* "district5SalesTax" => 0,
* "district5UseTax" => 0,
* "originDestination" => "D",
* ],
* ]
*
* ];
*
* @var mixed[]
*
*/
public array $results = [];
public string $seller_region = "";
//US
public string $geoPostalCode = "";
public string $geoCity = "";
public string $geoCounty = "";
public string $geoState = "";
public float $taxSales = 0;
public float $taxUse = 0;
public string $txbService = ""; // N = No, Y = Yes
public string $txbFreight = ""; // N = No, Y = Yes
public float $stateSalesTax = 0;
public float $stateUseTax = 0;
public float $citySalesTax = 0;
public float $cityUseTax = 0;
public string $cityTaxCode = "";
public float $countySalesTax = 0;
public float $countyUseTax = 0;
public string $countyTaxCode = "";
public float $districtSalesTax = 0;
public float $districtUseTax = 0;
public string $district1Code = "";
public float $district1SalesTax = 0;
public float $district1UseTax = 0;
public string $district2Code = "";
public float $district2SalesTax = 0;
public float $district2UseTax = 0;
public string $district3Code = "";
public float $district3SalesTax = 0;
public float $district3UseTax = 0;
public string $district4Code = "";
public float $district4SalesTax = 0;
public float $district4UseTax = 0;
public string $district5Code = "";
public float $district5SalesTax = 0;
public float $district5UseTax = 0;
public string $originDestination = "";
public function __construct($data)
{
foreach($data as $key => $value){
$this->{$key} = $value;
}
}
}

View File

@ -1,96 +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\DataMapper\Tax\de;
use App\DataMapper\Tax\RuleInterface;
class Rule implements RuleInterface
{
public float $vat_rate = 19;
public float $vat_threshold = 10000;
public float $vat_reduced_rate = 7;
public float $vat_reduced_threshold = 10000;
public float $at_vat_rate = 20; // Austria
public float $be_vat_rate = 21; // Belgium
public float $bg_vat_rate = 20; // Bulgaria
public float $hr_vat_rate = 25; // Croatia
public float $cy_vat_rate = 19; // Cyprus
public float $cz_vat_rate = 21; // Czech Republic
public float $dk_vat_rate = 25; // Denmark
public float $ee_vat_rate = 20; // Estonia
public float $fi_vat_rate = 24; // Finland
public float $fr_vat_rate = 20; // France
public float $de_vat_rate = 19; // Germany
public float $gr_vat_rate = 24; // Greece
public float $hu_vat_rate = 27; // Hungary
public float $ie_vat_rate = 23; // Ireland
public float $it_vat_rate = 22; // Italy
public float $lv_vat_rate = 21; // Latvia
public float $lt_vat_rate = 21; // Lithuania
public float $lu_vat_rate = 17; // Luxembourg
public float $mt_vat_rate = 18; // Malta
public float $nl_vat_rate = 21; // Netherlands
public float $pl_vat_rate = 23; // Poland
public float $pt_vat_rate = 23; // Portugal
public float $ro_vat_rate = 19; // Romania
public float $sk_vat_rate = 20; // Slovakia
public float $si_vat_rate = 22; // Slovenia
public float $es_vat_rate = 21; // Spain
public float $se_vat_rate = 25; // Sweden
public float $gb_vat_rate = 20; // United Kingdom
public bool $consumer_tax_exempt = false;
public bool $business_tax_exempt = true;
public bool $eu_business_tax_exempt = true;
public bool $foreign_business_tax_exempt = true;
public bool $foreign_consumer_tax_exempt = true;
public function run()
{
return $this;
}
}

View File

@ -0,0 +1,220 @@
region:
US:
tax_all_subregions: false
seller_subregion: CA
has_sales_above_threshold: false
subregions:
AL:
apply_tax: false
AK:
apply_tax: false
AZ:
apply_tax: false
AR:
apply_tax: false
CA:
apply_tax: false
CO:
apply_tax: false
CT:
apply_tax: false
DE:
apply_tax: false
FL:
apply_tax: false
GA:
apply_tax: false
HI:
apply_tax: false
ID:
apply_tax: false
IL:
apply_tax: false
IN:
apply_tax: false
IA:
apply_tax: false
KS:
apply_tax: false
KY:
apply_tax: false
LA:
apply_tax: false
ME:
apply_tax: false
MD:
apply_tax: false
MA:
apply_tax: false
MI:
apply_tax: false
MN:
apply_tax: false
MS:
apply_tax: false
MO:
apply_tax: false
MT:
apply_tax: false
NE:
apply_tax: false
NV:
apply_tax: false
NH:
apply_tax: false
NJ:
apply_tax: false
NM:
apply_tax: false
NY:
apply_tax: false
NC:
apply_tax: false
ND:
apply_tax: false
OH:
apply_tax: false
OK:
apply_tax: false
OR:
apply_tax: false
PA:
apply_tax: false
RI:
apply_tax: false
SC:
apply_tax: false
SD:
apply_tax: false
TN:
apply_tax: false
TX:
apply_tax: false
UT:
apply_tax: false
VT:
apply_tax: false
VA:
apply_tax: false
WA:
apply_tax: false
WV:
apply_tax: false
WI:
apply_tax: false
WY:
apply_tax: false
EU:
tax_all: false
vat_threshold: 10000
has_sales_above_threshold: false
seller_region: DE
subregions:
AT:
vat: 21
reduced_vat: 11
apply_tax: false
BE:
vat: 21
reduced_vat: 6
apply_tax: false
BG:
vat: 20
reduced_vat: 9
apply_tax: false
CY:
vat: 19
reduced_vat: 9
apply_tax: false
CZ:
vat: 21
reduced_vat: 15
apply_tax: false
DE:
vat: 19
reduced_vat: 7
apply_tax: false
DK:
vat: 25
reduced_vat: 0
apply_tax: false
EE:
vat: 20
reduced_vat: 9
apply_tax: false
ES:
vat: 21
reduced_vat: 10
apply_tax: false
FI:
vat: 24
reduced_vat: 14
apply_tax: false
FR:
vat: 20
reduced_vat: 5.5
apply_tax: false
GB:
vat: 20
reduced_vat: 0
apply_tax: false
GR:
vat: 24
reduced_vat: 13
apply_tax: false
HR:
vat: 25
reduced_vat: 5
apply_tax: false
HU:
vat: 27
reduced_vat: 5
apply_tax: false
IE:
vat: 23
reduced_vat: 0
apply_tax: false
IT:
vat: 22
reduced_vat: 10
apply_tax: false
LT:
vat: 21
reduced_vat: 9
apply_tax: false
LU:
vat: 17
reduced_vat: 3
apply_tax: false
LV:
vat: 21
reduced_vat: 12
apply_tax: false
MT:
vat: 18
reduced_vat: 5
apply_tax: false
NL:
vat: 21
reduced_vat: 9
apply_tax: false
PT:
vat: 23
reduced_vat: 6
apply_tax: false
RO:
vat: 19
reduced_vat: 5
apply_tax: false
SE:
vat: 25
reduced_vat: 12
apply_tax: false
SI:
vat: 22
reduced_vat: 9.5
apply_tax: false
SK:
vat: 20
reduced_vat: 10
apply_tax: false

View File

@ -1,70 +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\DataMapper\Tax\us;
class Rule
{
public float $al_sales_tax_rate = 4; // Alabama
public float $ak_sales_tax_rate = 0; // Alaska
public float $az_sales_tax_rate = 5.6; // Arizona
public float $ar_sales_tax_rate = 6.5; // Arkansas
public float $ca_sales_tax_rate = 7.25; // California - https://services.maps.cdtfa.ca.gov/api/taxrate/GetRateByAddress?address=2444+s+alameda+st&city=los+angeles&zip=90058
public float $co_sales_tax_rate = 2.9; // Colorado
public float $ct_sales_tax_rate = 6.35; // Connecticut
public float $de_sales_tax_rate = 0; // Delaware
public float $fl_sales_tax_rate = 6; // Florida
public float $ga_sales_tax_rate = 4; // Georgia
public float $hi_sales_tax_rate = 4; // Hawaii
public float $id_sales_tax_rate = 6; // Idaho
public float $il_sales_tax_rate = 6.25; // Illinois
public float $in_sales_tax_rate = 7; // Indiana
public float $ia_sales_tax_rate = 6; // Iowa
public float $ks_sales_tax_rate = 6.5; // Kansas
public float $ky_sales_tax_rate = 6; // Kentucky
public float $la_sales_tax_rate = 4.45; // Louisiana
public float $me_sales_tax_rate = 5.5; // Maine
public float $md_sales_tax_rate = 6; // Maryland
public float $ma_sales_tax_rate = 6.25; // Massachusetts
public float $mi_sales_tax_rate = 6; // Michigan
public float $mn_sales_tax_rate = 6.875; // Minnesota
public float $ms_sales_tax_rate = 7; // Mississippi
public float $mo_sales_tax_rate = 4.225; // Missouri
public float $mt_sales_tax_rate = 0; // Montana
public float $ne_sales_tax_rate = 5.5; // Nebraska
public float $nv_sales_tax_rate = 6.85; // Nevada
public float $nh_sales_tax_rate = 0; // New Hampshire
public float $nj_sales_tax_rate = 6.625; // New Jersey
public float $nm_sales_tax_rate = 5.125; // New Mexico
public float $ny_sales_tax_rate = 4; // New York
public float $nc_sales_tax_rate = 4.75; // North Carolina
public float $nd_sales_tax_rate = 5; // North Dakota
public float $oh_sales_tax_rate = 5.75; // Ohio
public float $ok_sales_tax_rate = 4.5; // Oklahoma
public float $or_sales_tax_rate = 0; // Oregon
public float $pa_sales_tax_rate = 6; // Pennsylvania
public float $ri_sales_tax_rate = 7; // Rhode Island
public float $sc_sales_tax_rate = 6; // South Carolina
public float $sd_sales_tax_rate = 4.5; // South Dakota
public float $tn_sales_tax_rate = 7; // Tennessee
public float $tx_sales_tax_rate = 6.25; // Texas
public float $ut_sales_tax_rate = 4.7; // Utah
public float $vt_sales_tax_rate = 6; // Vermont
public float $va_sales_tax_rate = 5.3; // Virginia
public float $wa_sales_tax_rate = 6.5; // Washington
public float $wv_sales_tax_rate = 6; // West Virginia
public float $wi_sales_tax_rate = 5; // Wisconsin
public float $wy_sales_tax_rate = 4; // Wyoming
public float $dc_sales_tax_rate = 6; // District of Columbia
public float $pr_sales_tax_rate = 11.5; // Puerto Rico
}

View File

@ -34,6 +34,8 @@ class InvoiceItemExport extends BaseExport
'amount' => 'amount',
'balance' => 'balance',
'client' => 'client_id',
'client_number' => 'client.number',
'client_id_number' => 'client.id_number',
'custom_surcharge1' => 'custom_surcharge1',
'custom_surcharge2' => 'custom_surcharge2',
'custom_surcharge3' => 'custom_surcharge3',
@ -198,6 +200,8 @@ class InvoiceItemExport extends BaseExport
// if(in_array('client_id', $this->input['report_keys']))
$entity['client'] = $invoice->client->present()->name();
$entity['client_id_number'] = $invoice->client->id_number;
$entity['client_number'] = $invoice->client->number;
// if(in_array('status_id', $this->input['report_keys']))
$entity['status'] = $invoice->stringStatus($invoice->status_id);

View File

@ -24,7 +24,7 @@ class DesignFactory
$design->is_active = true;
$design->is_custom = true;
$design->name = '';
$design->design = '';
$design->design = '[]';
return $design;
}

View File

@ -35,7 +35,8 @@ class ProductFactory
$product->custom_value3 = '';
$product->custom_value4 = '';
$product->is_deleted = 0;
$product->tax_id = 1;
return $product;
}
}

View File

@ -131,7 +131,7 @@ class InvoiceFilters extends QueryFilters
*/
public function upcoming(): Builder
{
return $this->builder
return $this->builder->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
->where(function ($query) {
$query->whereNull('due_date')
->orWhere('due_date', '>', now());

View File

@ -11,10 +11,13 @@
namespace App\Helpers\Invoice;
use App\DataMapper\BaseSettings;
use App\DataMapper\InvoiceItem;
use App\Models\Client;
use App\Models\Invoice;
use App\DataMapper\InvoiceItem;
use App\DataMapper\BaseSettings;
use App\DataMapper\Tax\RuleInterface;
use App\Utils\Traits\NumberFormatter;
use App\DataMapper\Tax\ZipTax\Response;
class InvoiceItemSum
{
@ -22,6 +25,38 @@ class InvoiceItemSum
use Discounter;
use Taxer;
private array $tax_jurisdictions = [
'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
'US', //USA
];
protected $invoice;
private $items;
@ -48,6 +83,12 @@ class InvoiceItemSum
private $tax_collection;
private ?Client $client;
private bool $calc_tax = false;
private RuleInterface $rule;
public function __construct($invoice)
{
$this->tax_collection = collect([]);
@ -56,6 +97,8 @@ class InvoiceItemSum
if ($this->invoice->client) {
$this->currency = $this->invoice->client->currency();
$this->client = $this->invoice->client;
$this->shouldCalculateTax();
} else {
$this->currency = $this->invoice->vendor->currency();
}
@ -89,6 +132,33 @@ class InvoiceItemSum
return $this;
}
private function shouldCalculateTax(): self
{
if (!$this->invoice->company->calculate_taxes) {
$this->calc_tax = false;
return $this;
}
//should we be filtering by client country here? do we need to reflect at the company <=> client level?
if (in_array($this->client->country->iso_3166_2, $this->tax_jurisdictions)) { //only calculate for supported tax jurisdictions
$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)
->init();
$this->calc_tax = true;
return $this;
}
return $this;
}
private function push()
{
$this->sub_total += $this->getLineTotal();
@ -122,8 +192,33 @@ class InvoiceItemSum
return $this;
}
/**
* Attempts to calculate taxes based on the clients location
*
* @return self
*/
private function calcTaxesAutomatically(): self
{
$this->rule->tax($this->item->tax_id ?? null);
$this->item->tax_name1 = $this->rule->tax_name1;
$this->item->tax_rate1 = $this->rule->tax_rate1;
$this->item->tax_name2 = $this->rule->tax_name2;
$this->item->tax_rate2 = $this->rule->tax_rate2;
$this->item->tax_name3 = $this->rule->tax_name3;
$this->item->tax_rate3 = $this->rule->tax_rate3;
return $this;
}
private function calcTaxes()
{
if ($this->calc_tax) {
$this->calcTaxesAutomatically();
}
$item_tax = 0;
$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / 100));
@ -131,7 +226,6 @@ class InvoiceItemSum
$item_tax += $item_tax_rate1_total;
// if($item_tax_rate1_total != 0)
if (strlen($this->item->tax_name1) > 1) {
$this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $item_tax_rate1_total);
}
@ -155,7 +249,7 @@ class InvoiceItemSum
$this->setTotalTaxes($this->formatValue($item_tax, $this->currency->precision));
$this->item->gross_line_total = $this->getLineTotal() + $item_tax;
$this->item->tax_amount = $item_tax;
return $this;

View File

@ -45,6 +45,8 @@ class InvoiceSum
private $precision;
public InvoiceItemSum $invoice_items;
/**
* Constructs the object with Invoice and Settings object.
*

View File

@ -11,16 +11,17 @@
namespace App\Http\Controllers;
use App\Http\Requests\Account\CreateAccountRequest;
use App\Http\Requests\Account\UpdateAccountRequest;
use App\Jobs\Account\CreateAccount;
use App\Models\Account;
use App\Libraries\MultiDB;
use App\Utils\TruthSource;
use App\Models\CompanyUser;
use Illuminate\Http\Response;
use App\Jobs\Account\CreateAccount;
use App\Transformers\AccountTransformer;
use App\Transformers\CompanyUserTransformer;
use App\Utils\TruthSource;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Http\Response;
use App\Http\Requests\Account\CreateAccountRequest;
use App\Http\Requests\Account\UpdateAccountRequest;
class AccountController extends BaseController
{
@ -146,15 +147,20 @@ class AccountController extends BaseController
if (! ($account instanceof Account)) {
return $account;
}
MultiDB::findAndSetDbByAccountKey($account->key);
$ct = CompanyUser::whereUserId(auth()->user()->id);
$cu = CompanyUser::where('user_id', $account->users()->first()->id);
$company_user = $cu->first();
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($ct->first());
$truth->setUser(auth()->user());
$truth->setCompany($ct->first()->company);
$truth->setCompanyUser($company_user);
$truth->setUser($company_user->user);
$truth->setCompany($company_user->company);
$truth->setCompanyToken($company_user->tokens()->where('user_id', $company_user->user_id)->where('company_id', $company_user->company_id)->first());
return $this->listResponse($ct);
return $this->listResponse($cu);
}
public function update(UpdateAccountRequest $request, Account $account)

View File

@ -33,6 +33,7 @@ use App\Utils\Statics;
use App\Utils\Traits\AppSetup;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
@ -565,7 +566,7 @@ class BaseController extends Controller
/**
* Mini Load Query
*
* @param mixed $query
* @param Builder $query
* @return void
*/
protected function miniLoadResponse($query)
@ -667,7 +668,7 @@ class BaseController extends Controller
/**
* Passes back the miniloaded data response
*
* @param mixed $query
* @param Builder $query
* @return void
*/
protected function timeConstrainedResponse($query)
@ -911,8 +912,8 @@ class BaseController extends Controller
/**
* List response
*
* @param mixed $query
*
* @param Builder $query
*/
protected function listResponse($query)
{
@ -926,24 +927,26 @@ class BaseController extends Controller
$query->with($includes);
if (auth()->user() && ! auth()->user()->hasPermission('view_'.Str::snake(class_basename($this->entity_type)))) {
$user = Auth::user();
if ($user && ! $user->hasPermission('view_'.Str::snake(class_basename($this->entity_type)))) {
if (in_array($this->entity_type, [User::class])) {
$query->where('id', auth()->user()->id);
$query->where('id', $user->id);
} elseif (in_array($this->entity_type, [BankTransactionRule::class,CompanyGateway::class, TaxRate::class, BankIntegration::class, Scheduler::class, BankTransaction::class, Webhook::class, ExpenseCategory::class])) { //table without assigned_user_id
if ($this->entity_type == BankIntegration::class && !auth()->user()->isSuperUser() && auth()->user()->hasIntersectPermissions(['create_bank_transaction','edit_bank_transaction','view_bank_transaction'])) {
if ($this->entity_type == BankIntegration::class && !$user->isSuperUser() && $user->hasIntersectPermissions(['create_bank_transaction','edit_bank_transaction','view_bank_transaction'])) {
$query->exclude(["balance"]);
} //allows us to selective display bank integrations back to the user if they can view / create bank transactions but without the bank balance being present in the response
else {
$query->where('user_id', '=', auth()->user()->id);
$query->where('user_id', '=', $user->id);
}
} elseif (in_array($this->entity_type, [Design::class, GroupSetting::class, PaymentTerm::class, TaskStatus::class])) {
// nlog($this->entity_type);
} else {
$query->where('user_id', '=', auth()->user()->id)->orWhere('assigned_user_id', auth()->user()->id);
$query->where('user_id', '=', $user->id)->orWhere('assigned_user_id', $user->id);
}
}
if ($this->entity_type == Client::class && auth()->user()->hasExcludedPermissions($this->client_excludable_permissions, $this->client_excludable_overrides)) {
if ($this->entity_type == Client::class && $user->hasExcludedPermissions($this->client_excludable_permissions, $this->client_excludable_overrides)) {
$query->exclude($this->client_exclusion_fields);
}
@ -1085,7 +1088,7 @@ class BaseController extends Controller
{
if ((bool) $this->checkAppSetup() !== false && $account = Account::first()) {
//always redirect invoicing.co to invoicing.co
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co'])) {
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co', 'https://invoiceninja.net'])) {
return redirect()->secure('https://invoicing.co');
}

View File

@ -80,8 +80,6 @@ class InvoiceController extends Controller
/**
* Pay one or more invoices.
*
* @param ProcessInvoicesInBulkRequest $request
* @return mixed
*/
public function catch_bulk()
{

View File

@ -38,11 +38,15 @@ class PrePaymentController extends Controller
*/
public function index()
{
$client = auth()->guard('contact')->user()->client;
$minimum = $client->getSetting('client_initiated_payments_minimum');
$minimum_amount = $minimum == 0 ? "" : Number::formatMoney($minimum, $client);
$data = [
'title' => ctrans('texts.amount'). " " .auth()->guard('contact')->user()->client->currency()->code." (".auth()->guard('contact')->user()->client->currency()->symbol . ")",
'allows_recurring' => auth()->guard('contact')->user()->client->getSetting('client_initiated_payments_recurring'),
'title' => ctrans('texts.amount'). " " .$client->currency()->code." (".auth()->guard('contact')->user()->client->currency()->symbol . ")",
'allows_recurring' => true,
'minimum_amount' => auth()->guard('contact')->user()->client->getSetting('client_initiated_payments_minimum'),
'minimum' => $minimum,
'minimum_amount' => $minimum_amount,
];
return $this->render('pre_payments.index', $data);

View File

@ -19,22 +19,28 @@ use App\Utils\Ninja;
class SubscriptionController extends Controller
{
/**
* This function is used to display the subscription page.
*
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
if (Ninja::isHosted()) {
$count = RecurringInvoice::query()
->where('client_id', auth()->guard('contact')->user()->client->id)
->where('company_id', auth()->guard('contact')->user()->client->company_id)
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
->where('is_deleted', 0)
->whereNotNull('subscription_id')
->withTrashed()
->count();
// if (Ninja::isHosted()) {
// $count = RecurringInvoice::query()
// ->where('client_id', auth()->guard('contact')->user()->client->id)
// ->where('company_id', auth()->guard('contact')->user()->client->company_id)
// ->where('status_id', RecurringInvoice::STATUS_ACTIVE)
// ->where('is_deleted', 0)
// ->whereNotNull('subscription_id')
// ->withTrashed()
// ->count();
if ($count == 0) {
return redirect()->route('client.ninja_contact_login', ['contact_key' => auth()->guard('contact')->user()->contact_key, 'company_key' => auth()->guard('contact')->user()->company->company_key]);
}
}
// if ($count == 0) {
// return redirect()->route('client.ninja_contact_login', ['contact_key' => auth()->guard('contact')->user()->contact_key, 'company_key' => auth()->guard('contact')->user()->company->company_key]);
// }
// }
return render('subscriptions.index');
}
@ -44,7 +50,6 @@ class SubscriptionController extends Controller
*
* @param ShowRecurringInvoiceRequest $request
* @param RecurringInvoice $recurring_invoice
* @return Factory|View
*/
public function show(ShowRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
{

View File

@ -136,7 +136,7 @@ class EmailController extends BaseController
$mo->email_template_body = $request->input('template');
$mo->email_template_subject = str_replace("template", "subject", $request->input('template'));
if ($request->has('cc_email')) {
if ($request->has('cc_email') && $request->cc_email) {
$mo->cc[] = new Address($request->cc_email);
}

View File

@ -38,6 +38,8 @@ class HostedMigrationController extends Controller
$account->hosted_company_count = 10;
$account->save();
MultiDB::findAndSetDbByAccountKey($account->key);
$company = $account->companies->first();
$company_token = CompanyToken::where('user_id', auth()->user()->id)

View File

@ -144,7 +144,7 @@ class PreviewController extends BaseController
$maker
->design($design)
->build();
if (request()->query('html') == 'true') {
return $maker->getCompiledHTML();
}

View File

@ -556,4 +556,29 @@ class RecurringInvoiceController extends BaseController
return $this->itemResponse($recurring_invoice->fresh());
}
public function downloadPdf(string $invitation_key)
{
$invitation = $this->recurring_invoice_repo->getInvitationByKey($invitation_key);
if (! $invitation) {
return response()->json(['message' => 'no record found'], 400);
}
$contact = $invitation->contact;
$invoice = $invitation->recurring_invoice;
$file = $invoice->service()->getInvoicePdf($contact);
$headers = ['Content-Type' => 'application/pdf'];
if (request()->input('inline') == 'true') {
$headers = array_merge($headers, ['Content-Disposition' => 'inline']);
}
return response()->streamDownload(function () use ($file) {
echo Storage::get($file);
}, basename($file), $headers);
}
}

View File

@ -26,7 +26,17 @@ class StorePrePaymentRequest extends FormRequest
{
return [
'notes' => 'required|bail|',
'amount' => 'required|bail|',
'amount' => 'required|bail|gte:minimum_amount|numeric',
'minimum_amount' => '',
];
}
public function prepareForValidation()
{
$input = $this->all();
$this->replace($input);
}
}

View File

@ -32,7 +32,7 @@ class StoreDesignRequest extends Request
return [
//'name' => 'required',
'name' => 'required|unique:designs,name,null,null,company_id,'.auth()->user()->companyId(),
'design' => 'required',
'design' => 'required|array',
];
}

View File

@ -43,7 +43,7 @@ class SendEmailRequest extends Request
'template' => 'bail|required',
'entity' => 'bail|required',
'entity_id' => 'bail|required',
'cc_email' => 'bail|sometimes|email',
'cc_email' => 'bail|sometimes|email|nullable',
];
}

View File

@ -12,6 +12,7 @@
namespace App\Http\Requests\Invoice;
use App\Http\Requests\Request;
use Illuminate\Http\UploadedFile;
class UploadInvoiceRequest extends Request
{
@ -46,5 +47,24 @@ class UploadInvoiceRequest extends Request
public function prepareForValidation()
{
//tests to see if upload via binary data works.
// if(request()->getContent())
// {
// // $file = new UploadedFile(request()->getContent(), request()->header('filename'));
// $file = new UploadedFile(request()->getContent(), 'something.png');
// // request()->files->set('documents', $file);
// $this->files->add(['file' => $file]);
// // Merge it in request also (As I found this is not needed in every case)
// $this->merge(['file' => $file]);
// }
}
}

View File

@ -47,6 +47,7 @@ class DesignPreviewRequest extends Request
'settings' => 'sometimes',
'group_id' => 'sometimes',
'client_id' => 'sometimes',
'design' => 'bail|sometimes|array'
];
return $rules;

View File

@ -32,7 +32,7 @@ class StoreSchedulerRequest extends Request
public function rules()
{
$rules = [
'name' => ['bail', 'required', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)],
'name' => 'bail|sometimes|nullable|string',
'is_paused' => 'bail|sometimes|boolean',
'frequency_id' => 'bail|sometimes|integer|digits_between:1,12',
'next_run' => 'bail|required|date:Y-m-d|after_or_equal:today',

View File

@ -29,7 +29,7 @@ class UpdateSchedulerRequest extends Request
public function rules(): array
{
$rules = [
'name' => ['bail', 'sometimes', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)->ignore($this->task_scheduler->id)],
'name' => 'bail|sometimes|nullable|string',
'is_paused' => 'bail|sometimes|boolean',
'frequency_id' => 'bail|sometimes|integer|digits_between:1,12',
'next_run' => 'bail|required|date:Y-m-d|after_or_equal:today',

View File

@ -138,9 +138,9 @@ class PortalComposer
$data[] = ['title' => ctrans('texts.subscriptions'), 'url' => 'client.subscriptions.index', 'icon' => 'calendar'];
}
// if (property_exists($this->settings, 'client_initiated_payments') && $this->settings->client_initiated_payments) {
if (auth()->guard('contact')->user()->client->getSetting('client_initiated_payments')) {
$data[] = ['title' => ctrans('texts.pre_payment'), 'url' => 'client.pre_payments.index', 'icon' => 'dollar-sign'];
// }
}
return $data;
}

View File

@ -115,9 +115,9 @@ class AdjustProductInventory implements ShouldQueue
$p->in_stock_quantity -= $i->quantity;
$p->saveQuietly();
nlog($p->stock_notification_threshold);
nlog($p->in_stock_quantity);
nlog($p->stock_notification_threshold);
nlog("threshold ".$p->stock_notification_threshold);
nlog("stock q".$p->in_stock_quantity);
nlog("p stock not".$p->stock_notification_threshold);
if ($this->company->stock_notification && $p->stock_notification && $p->stock_notification_threshold && $p->in_stock_quantity <= $p->stock_notification_threshold) {
$this->notifyStockLevels($p, 'product');
@ -131,7 +131,7 @@ class AdjustProductInventory implements ShouldQueue
private function existingInventoryAdjustment()
{
collect($this->invoice->line_items)->filter(function ($item) {
collect($this->old_invoice)->filter(function ($item) {
return $item->type_id == '1';
})->each(function ($i) {
$p = Product::where('product_key', $i->product_key)->where('company_id', $this->company->id)->first();

View File

@ -128,7 +128,7 @@ class NinjaMailerJob implements ShouldQueue
}
if ($this->client_mailgun_secret) {
$mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain);
$mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain, $this->nmo->settings->mailgun_endpoint);
}
$mailer
@ -188,6 +188,8 @@ class NinjaMailerJob implements ShouldQueue
}
/* Releasing immediately does not add in the backoff */
sleep(rand(0, 3));
$this->release($this->backoff()[$this->attempts()-1]);
}

View File

@ -65,8 +65,8 @@ class PaymentFailedMailer implements ShouldQueue
*/
public function handle()
{
if (!is_string($this->error)) {
$this->error = "Payment failed, no reason given.";
if (!is_string($this->error) || strlen($this->error) <=1) {
$this->error = "";
}
//Set DB
@ -79,7 +79,8 @@ class PaymentFailedMailer implements ShouldQueue
$invoice = false;
if ($this->payment_hash) {
$amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
// $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
$amount =$this->payment_hash?->amount_with_fee() ?: 0;
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
}

View File

@ -40,6 +40,8 @@ class UpdateRecurring implements ShouldQueue
{
MultiDB::setDb($this->company->db);
$this->user->setCompany($this->company);
RecurringInvoice::where('company_id', $this->company->id)
->whereIn('id', $this->ids)
->chunk(100, function ($recurring_invoices) {

View File

@ -37,6 +37,8 @@ class CleanStaleInvoiceOrder implements ShouldQueue
*/
public function handle(InvoiceRepository $repo) : void
{
nlog("Cleaning Stale Invoices:");
if (! config('ninja.db.multi_db_enabled')) {
Invoice::query()
->withTrashed()
@ -48,6 +50,20 @@ class CleanStaleInvoiceOrder implements ShouldQueue
$repo->delete($invoice);
});
Invoice::query()
->withTrashed()
->where('status_id', Invoice::STATUS_SENT)
->where('created_at', '<', now()->subHours(2))
->where('balance', '>', 0)
->cursor()
->each(function ($invoice){
if (collect($invoice->line_items)->contains('type_id', 3)) {
$invoice->service()->removeUnpaidGatewayFees();
}
});
return;
}

View File

@ -63,7 +63,7 @@ class WebhookSingle implements ShouldQueue
public function backoff()
{
return [10, 30, 60, 180, 3600];
return [15, 35, 65, 185, 3605];
}
/**
@ -223,6 +223,9 @@ class WebhookSingle implements ShouldQueue
$this->company,
))->handle();
//add some entropy to the retry
sleep(rand(0, 3));
$this->release($this->backoff()[$this->attempts()-1]);
}
}

View File

@ -50,10 +50,10 @@ class InvoiceEmailActivity implements ShouldQueue
$fields->user_id = $user_id;
$fields->invoice_id = $event->invitation->invoice->id;
$fields->company_id = $event->invitation->invoice->company_id;
$fields->client_contact_id = $event->invitation->invoice->client_contact_id;
$fields->client_contact_id = $event->invitation->client_contact_id;
$fields->client_id = $event->invitation->invoice->client_id;
$fields->activity_type_id = Activity::EMAIL_INVOICE;
$this->activity_repo->save($fields, $event->invitation->invoice, $event->event_vars);
$this->activity_repo->save($fields, $event->invitation, $event->event_vars);
}
}

View File

@ -47,11 +47,12 @@ class InvoiceReminderEmailActivity implements ShouldQueue
$user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
$fields->user_id = $user_id;
$fields->invoice_id = $event->invitation->invoice->id;
$fields->company_id = $event->invitation->invoice->company_id;
$fields->client_contact_id = $event->invitation->invoice->client_contact_id;
$fields->invoice_id = $event->invitation->invoice_id;
$fields->company_id = $event->invitation->company_id;
$fields->client_contact_id = $event->invitation->client_contact_id;
$fields->client_id = $event->invitation->invoice->client_id;
$fields->activity_type_id = $event->reminder;
$this->activity_repo->save($fields, $event->invitation->invoice, $event->event_vars);
$this->activity_repo->save($fields, $event->invitation, $event->event_vars);
}
}

View File

@ -39,7 +39,6 @@ class PaymentNotification implements ShouldQueue
* Handle the event.
*
* @param object $event
* @return bool
*/
public function handle($event)
{
@ -51,6 +50,15 @@ class PaymentNotification implements ShouldQueue
$payment = $event->payment;
/*Google Analytics Track Revenue*/
if (isset($payment->company->google_analytics_key)) {
$this->trackRevenue($event);
}
if($payment->is_manual)
return;
/*User notifications*/
foreach ($payment->company->company_users as $company_user) {
$user = $company_user->user;
@ -80,10 +88,6 @@ class PaymentNotification implements ShouldQueue
}
}
/*Google Analytics Track Revenue*/
if (isset($payment->company->google_analytics_key)) {
$this->trackRevenue($event);
}
}
private function trackRevenue($event)

View File

@ -49,11 +49,11 @@ class PurchaseOrderEmailActivity implements ShouldQueue
$fields->user_id = $user_id;
$fields->purchase_order_id = $event->invitation->purchase_order->id;
$fields->company_id = $event->invitation->purchase_order->company_id;
$fields->vendor_contact_id = $event->invitation->purchase_order->vendor_contact_id;
$fields->company_id = $event->invitation->company_id;
$fields->vendor_contact_id = $event->invitation->vendor_contact_id;
$fields->vendor_id = $event->invitation->purchase_order->vendor_id;
$fields->activity_type_id = Activity::EMAIL_PURCHASE_ORDER;
$this->activity_repo->save($fields, $event->invitation->purchase_order, $event->event_vars);
$this->activity_repo->save($fields, $event->invitation, $event->event_vars);
}
}

View File

@ -56,6 +56,6 @@ class QuoteEmailActivity implements ShouldQueue
$fields->client_id = $event->invitation->quote->client_id;
$fields->activity_type_id = Activity::EMAIL_QUOTE;
$this->activity_repo->save($fields, $event->invitation->quote, $event->event_vars);
$this->activity_repo->save($fields, $event->invitation, $event->event_vars);
}
}

View File

@ -124,6 +124,10 @@ class ClientPaymentFailureObject
'company' => $this->company,
];
if (strlen($this->error > 1)) {
$data['content'] .= "\n\n".$this->error;
}
return $data;
}
}

View File

@ -120,6 +120,10 @@ class PaymentFailureObject
'additional_info' => $this->error,
];
if (strlen($this->error > 1)) {
$data['content'] .= "\n\n".$this->error;
}
return $data;
}

View File

@ -261,7 +261,7 @@ class PaymentEmailEngine extends BaseEmailEngine
$data['$invoices.balance'] = ['value' => $this->formatInvoiceField('balance'), 'label' => ctrans('texts.invoices')];
$data['$invoices.due_date'] = ['value' => $this->formatInvoiceField('due_date'), 'label' => ctrans('texts.invoices')];
$data['$invoices.po_number'] = ['value' => $this->formatInvoiceField('po_number'), 'label' => ctrans('texts.invoices')];
$data['$invoice_numbers'] = ['value' => $this->formatInvoiceNumbersRaw(), 'label' => ctrans('texts.invoices')];
if ($this->payment->status_id == 4) {
$data['$status_logo'] = ['value' => '<div class="stamp is-paid"> ' . ctrans('texts.paid') .'</div>', 'label' => ''];
@ -347,6 +347,11 @@ class PaymentEmailEngine extends BaseEmailEngine
}
private function formatInvoiceNumbersRaw(){
return collect($this->payment->invoices->pluck('number')->toArray())->implode(', ');
}
private function formatInvoiceReferences()
{

View File

@ -134,6 +134,34 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Account extends BaseModel

View File

@ -33,6 +33,13 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|BankAccount withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|BankAccount withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankSubaccount> $bank_subaccounts
* @mixin \Eloquent
*/
class BankAccount extends BaseModel

View File

@ -76,6 +76,13 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|BankIntegration withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|BankIntegration withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\BankTransaction> $transactions
* @mixin \Eloquent
*/
class BankIntegration extends BaseModel

View File

@ -185,6 +185,129 @@ use Laracasts\Presenter\PresentableTrait;
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
* @method static \Illuminate\Database\Eloquent\Builder|Client wherePaymentBalance($value)
* @property mixed $tax_data
* @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
* @method static \Illuminate\Database\Eloquent\Builder|Client whereTaxData($value)
* @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
* @property int $is_tax_exempt
* @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
* @method static \Illuminate\Database\Eloquent\Builder|Client whereIsTaxExempt($value)
* @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
* @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
* @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
* @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
*/
class Client extends BaseModel implements HasLocalePreference
@ -255,6 +378,7 @@ class Client extends BaseModel implements HasLocalePreference
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
'last_login' => 'timestamp',
'tax_data' => 'object',
];
protected $touches = [];

View File

@ -128,6 +128,41 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class ClientContact extends Authenticatable implements HasLocalePreference

View File

@ -326,6 +326,319 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @property int $calculate_taxes
* @property mixed $tax_data
* @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
* @method static \Illuminate\Database\Eloquent\Builder|Company whereCalculateTaxes($value)
* @method static \Illuminate\Database\Eloquent\Builder|Company whereTaxAllProducts($value)
* @method static \Illuminate\Database\Eloquent\Builder|Company whereTaxData($value)
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Company extends BaseModel
@ -363,6 +676,39 @@ class Company extends BaseModel
protected $presenter = CompanyPresenter::class;
protected array $tax_coverage_countries = [
'US',
// //EU countries
// '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 Countries
];
protected $fillable = [
'invoice_task_hours',
'markdown_enabled',
@ -429,6 +775,7 @@ class Company extends BaseModel
'convert_payment_currency',
'convert_expense_currency',
'notify_vendor_when_paid',
'calculate_taxes',
];
protected $hidden = [
@ -446,6 +793,7 @@ class Company extends BaseModel
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
'client_registration_fields' => 'array',
'tax_data' => 'object',
];
protected $with = [];
@ -466,6 +814,16 @@ class Company extends BaseModel
self::ENTITY_RECURRING_QUOTE => 2048,
];
public function shouldCalculateTax()
{
return $this->calculate_taxes && in_array($this->getSetting('country_id'), $this->tax_coverage_countries);
}
public function refreshTaxData()
{
}
public function documents()
{
return $this->morphMany(Document::class, 'documentable');

View File

@ -93,6 +93,13 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
* @mixin \Eloquent
*/
class CompanyGateway extends BaseModel

View File

@ -70,6 +70,27 @@ 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> $tokens
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class CompanyUser extends Pivot

View File

@ -192,6 +192,55 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Credit extends BaseModel

View File

@ -131,6 +131,13 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|Expense withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Expense withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @mixin \Eloquent
*/
class Expense extends BaseModel

View File

@ -29,6 +29,13 @@ namespace App\Models;
* @method static \Illuminate\Database\Eloquent\Builder|GatewayType whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|GatewayType whereName($value)
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
* @mixin \Eloquent
*/
class GatewayType extends StaticModel

View File

@ -56,6 +56,20 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|GroupSetting withoutTrashed()
* @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\Client> $clients
* @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
* @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\Client> $clients
* @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
* @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\Client> $clients
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @mixin \Eloquent
*/
class GroupSetting extends StaticModel

View File

@ -212,6 +212,71 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @property object|null $tax_data
* @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
* @method static \Illuminate\Database\Eloquent\Builder|Invoice whereTaxData($value)
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Invoice extends BaseModel
@ -277,9 +342,6 @@ class Invoice extends BaseModel
];
protected $casts = [
// 'date' => 'date:Y-m-d',
// 'due_date' => 'date:Y-m-d',
// 'partial_due_date' => 'date:Y-m-d',
'line_items' => 'object',
'backup' => 'object',
'updated_at' => 'timestamp',
@ -287,6 +349,7 @@ class Invoice extends BaseModel
'deleted_at' => 'timestamp',
'is_deleted' => 'bool',
'is_amount_discount' => 'bool',
'tax_data' => 'object',
];
protected $with = [];
@ -582,7 +645,7 @@ class Invoice extends BaseModel
/**
* Access the invoice calculator object.
*
* @return stdClass The invoice calculator object getters
* @return \stdClass The invoice calculator object getters
*/
public function calc()
{

View File

@ -137,6 +137,41 @@ 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\Invoice> $invoices
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Payment extends BaseModel

View File

@ -97,6 +97,15 @@ use League\CommonMark\CommonMarkConverter;
* @method static \Illuminate\Database\Eloquent\Builder|Product withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Product withoutTrashed()
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @property int|null $tax_id
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @method static \Illuminate\Database\Eloquent\Builder|Product whereTaxId($value)
* @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
*/
class Product extends BaseModel
@ -105,6 +114,14 @@ class Product extends BaseModel
use SoftDeletes;
use Filterable;
public const PRODUCT_TYPE_PHYSICAL = 1;
public const PRODUCT_TYPE_SERVICE = 2;
public const PRODUCT_TYPE_DIGITAL = 3;
public const PRODUCT_TYPE_SHIPPING = 4;
public const PRODUCT_TYPE_EXEMPT = 5;
public const PRODUCT_TYPE_REDUCED_TAX = 6;
public const PRODUCT_TYPE_OVERRIDE_TAX = 7;
protected $fillable = [
'custom_value1',
'custom_value2',
@ -126,6 +143,7 @@ class Product extends BaseModel
'stock_notification',
'max_quantity',
'product_image',
'tax_id',
];
protected $touches = [];

View File

@ -74,6 +74,20 @@ use Laracasts\Presenter\PresentableTrait;
* @method static \Illuminate\Database\Eloquent\Builder|Project withoutTrashed()
* @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\Document> $documents
* @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
* @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\Document> $documents
* @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
* @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\Document> $documents
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
* @mixin \Eloquent
*/
class Project extends BaseModel

View File

@ -29,6 +29,13 @@ use App\Utils\Traits\MakesHash;
* @method static \Illuminate\Database\Eloquent\Builder|Proposal query()
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel scope()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @mixin \Eloquent
*/
class Proposal extends BaseModel

View File

@ -186,6 +186,48 @@ 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\Invoice> $invoices
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class PurchaseOrder extends BaseModel

View File

@ -185,6 +185,34 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Quote extends BaseModel

View File

@ -140,6 +140,13 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|RecurringExpense withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RecurringExpense withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @mixin \Eloquent
*/
class RecurringExpense extends BaseModel

View File

@ -182,6 +182,43 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @property int $is_proforma
* @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
* @method static \Illuminate\Database\Eloquent\Builder|RecurringInvoice whereIsProforma($value)
* @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
* @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
* @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
* @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
* @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
* @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
*/
class RecurringInvoice extends BaseModel

View File

@ -176,6 +176,41 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class RecurringQuote extends BaseModel

View File

@ -92,6 +92,13 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|Task withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Task withoutTrashed()
* @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
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @mixin \Eloquent
*/
class Task extends BaseModel

View File

@ -146,6 +146,55 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class User extends Authenticatable implements MustVerifyEmail

View File

@ -108,6 +108,34 @@ use Laracasts\Presenter\PresentableTrait;
* @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
* @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
* @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
* @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
* @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
* @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
* @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
* @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
*/
class Vendor extends BaseModel

View File

@ -112,6 +112,20 @@ use Laracasts\Presenter\PresentableTrait;
* @method static \Illuminate\Database\Eloquent\Builder|VendorContact withoutTrashed()
* @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\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @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
* @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\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @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
* @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\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $purchase_order_invitations
* @mixin \Eloquent
*/
class VendorContact extends Authenticatable implements HasLocalePreference

View File

@ -739,7 +739,9 @@ class BaseDriver extends AbstractPaymentDriver
$invoices_string = \implode(', ', collect($this->payment_hash->invoices())->pluck('invoice_number')->toArray()) ?: null;
$amount = Number::formatMoney($this->payment_hash?->amount_with_fee() ?: 0, $this->client);
if ($abbreviated || ! $invoices_string) {
if($abbreviated && $invoices_string){
return $invoices_string;
} elseif ($abbreviated || ! $invoices_string) {
return ctrans('texts.gateway_payment_text_no_invoice', [
'amount' => $amount,
'client' => $this->client->present()->name(),

View File

@ -30,6 +30,7 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;
//@deprecated
class ACH implements MethodInterface
{
use MakesHash;
@ -172,10 +173,13 @@ class ACH implements MethodInterface
$description = "Amount {$request->amount} from client {$this->go_cardless->client->present()->name()}";
}
$amount = $this->go_cardless->convertToGoCardlessAmount($this->go_cardless->payment_hash?->amount_with_fee(), $this->go_cardless->client->currency()->precision);
try {
$payment = $this->go_cardless->gateway->payments()->create([
'params' => [
'amount' => $request->amount,
// 'amount' => $request->amount,
'amount' => $amount,
'currency' => $request->currency,
'description' => $description,
'metadata' => [

View File

@ -49,37 +49,97 @@ class DirectDebit implements MethodInterface
* @return Redirector|RedirectResponse|void
*/
public function authorizeView(array $data)
{
return $this->billingRequestFlows($data);
// $session_token = \Illuminate\Support\Str::uuid()->toString();
// try {
// $redirect = $this->go_cardless->gateway->redirectFlows()->create([
// 'params' => [
// 'session_token' => $session_token,
// 'success_redirect_url' => route('client.payment_methods.confirm', [
// 'method' => GatewayType::DIRECT_DEBIT,
// 'session_token' => $session_token,
// ]),
// 'prefilled_customer' => [
// 'given_name' => auth()->guard('contact')->user()->first_name ?: '',
// 'family_name' => auth()->guard('contact')->user()->last_name ?: '',
// 'email' => auth()->guard('contact')->user()->email ?: '',
// 'address_line1' => auth()->guard('contact')->user()->client->address1 ?: '',
// 'city' => auth()->guard('contact')->user()->client->city ?: '',
// 'postal_code' => auth()->guard('contact')->user()->client->postal_code ?: '',
// 'country_code' => auth()->guard('contact')->user()->client->country->iso_3166_2,
// ],
// ],
// ]);
// return redirect(
// $redirect->redirect_url
// );
// } catch (\Exception $exception) {
// return $this->processUnsuccessfulAuthorization($exception);
// }
}
/**
* Response
* {
* "billing_request_flows": {
* "authorisation_url": "https://pay.gocardless.com/flow/static/billing_request?id=<br_id>",
* "lock_customer_details": false,
* "lock_bank_account": false,
* "auto_fulfil": true,
* "created_at": "2021-03-30T16:23:10.679Z",
* "expires_at": "2021-04-06T16:23:10.679Z",
* "redirect_uri": "https://my-company.com/completed",
* "links": {
* "billing_request": "BRQ123"
* }
* }
* }
*
*
*/
public function billingRequestFlows(array $data)
{
$session_token = \Illuminate\Support\Str::uuid()->toString();
$exit_uri = route('client.payment_methods.index');
$response = $this->go_cardless->gateway->billingRequests()->create([
"params" => [
"mandate_request" => [
"currency" => auth()->guard('contact')->user()->client->currency()->code
]
]
]);
try {
$redirect = $this->go_cardless->gateway->redirectFlows()->create([
'params' => [
'session_token' => $session_token,
'success_redirect_url' => route('client.payment_methods.confirm', [
'method' => GatewayType::DIRECT_DEBIT,
'session_token' => $session_token,
]),
'prefilled_customer' => [
'given_name' => auth()->guard('contact')->user()->first_name ?: '',
'family_name' => auth()->guard('contact')->user()->last_name ?: '',
'email' => auth()->guard('contact')->user()->email ?: '',
'address_line1' => auth()->guard('contact')->user()->client->address1 ?: '',
'city' => auth()->guard('contact')->user()->client->city ?: '',
'postal_code' => auth()->guard('contact')->user()->client->postal_code ?: '',
'country_code' => auth()->guard('contact')->user()->client->country->iso_3166_2,
$brf = $this->go_cardless->gateway->billingRequestFlows()->create([
"params" => [
"redirect_uri" => route('client.payment_methods.confirm', [
'method' => GatewayType::DIRECT_DEBIT,
'session_token' => $session_token,
'billing_request' => $response->id,
]),
"exit_uri" => $exit_uri,
"links" => [
"billing_request" => $response->id
],
],
"show_redirect_buttons" => true,
"show_success_redirect_button" => true,
]
]);
return redirect(
$redirect->redirect_url
);
return redirect($brf->authorisation_url);
} catch (\Exception $exception) {
nlog($exception->getMessage());
return $this->processUnsuccessfulAuthorization($exception);
}
}
/**
* Handle unsuccessful authorization.
*
@ -109,37 +169,68 @@ class DirectDebit implements MethodInterface
*/
public function authorizeResponse(Request $request)
{
try {
$redirect_flow = $this->go_cardless->gateway->redirectFlows()->complete(
$request->redirect_flow_id,
['params' => [
'session_token' => $request->session_token,
]],
);
try{
$billing_request = $this->go_cardless->gateway->billingRequests()->get($request->billing_request);
$payment_meta = new \stdClass;
$payment_meta->brand = ctrans('texts.payment_type_direct_debit');
$payment_meta->type = GatewayType::DIRECT_DEBIT;
$payment_meta->state = 'authorized';
$payment_meta->brand = $billing_request->resources->customer_bank_account->bank_name;
$payment_meta->type = $this->resolveScheme($billing_request->mandate_request->scheme);
$payment_meta->state = 'pending';
$payment_meta->last4 = $billing_request->resources->customer_bank_account->account_number_ending;
$data = [
'payment_meta' => $payment_meta,
'token' => $redirect_flow->links->mandate,
'payment_method_id' => $this->resolveScheme($redirect_flow->scheme),
'token' => $billing_request->mandate_request->links->mandate,
'payment_method_id' => $this->resolveScheme($billing_request->mandate_request->scheme),
];
$payment_method = $this->go_cardless->storeGatewayToken($data, ['gateway_customer_reference' => $redirect_flow->links->customer]);
$payment_method = $this->go_cardless->storeGatewayToken($data, ['gateway_customer_reference' => $billing_request->resources->customer->id]);
$mandate = $this->go_cardless->gateway->mandates()->get($billing_request->mandate_request->links->mandate);
nlog($mandate);
return redirect()->route('client.payment_methods.show', $payment_method->hashed_id);
} catch (\Exception $exception) {
}
catch (\Exception $exception) {
return $this->processUnsuccessfulAuthorization($exception);
}
// try {
// $redirect_flow = $this->go_cardless->gateway->redirectFlows()->complete(
// $request->redirect_flow_id,
// ['params' => [
// 'session_token' => $request->session_token,
// ]],
// );
// $payment_meta = new \stdClass;
// $payment_meta->brand = ctrans('texts.payment_type_direct_debit');
// $payment_meta->type = GatewayType::DIRECT_DEBIT;
// $payment_meta->state = 'authorized';
// $data = [
// 'payment_meta' => $payment_meta,
// 'token' => $redirect_flow->links->mandate,
// 'payment_method_id' => $this->resolveScheme($redirect_flow->scheme),
// ];
// $payment_method = $this->go_cardless->storeGatewayToken($data, ['gateway_customer_reference' => $redirect_flow->links->customer]);
// return redirect()->route('client.payment_methods.show', $payment_method->hashed_id);
// } catch (\Exception $exception) {
// return $this->processUnsuccessfulAuthorization($exception);
// }
}
private function resolveScheme(string $scheme): int
{
match ($scheme) {
'sepa_core' => $type = GatewayType::SEPA,
'ach' => $type = GatewayType::BANK_TRANSFER,
default => $type = GatewayType::DIRECT_DEBIT,
};
@ -176,10 +267,13 @@ class DirectDebit implements MethodInterface
$description = "Amount {$request->amount} from client {$this->go_cardless->client->present()->name()}";
}
$amount = $this->go_cardless->convertToGoCardlessAmount($this->go_cardless->payment_hash?->amount_with_fee(), $this->go_cardless->client->currency()->precision);
try {
$payment = $this->go_cardless->gateway->payments()->create([
'params' => [
'amount' => $request->amount,
// 'amount' => $request->amount,
'amount' => $amount,
'currency' => $request->currency,
'description' => $description,
'metadata' => [

View File

@ -172,10 +172,12 @@ class SEPA implements MethodInterface
$description = "Amount {$request->amount} from client {$this->go_cardless->client->present()->name()}";
}
$amount = $this->go_cardless->convertToGoCardlessAmount($this->go_cardless->payment_hash?->amount_with_fee(), $this->go_cardless->client->currency()->precision);
try {
$payment = $this->go_cardless->gateway->payments()->create([
'params' => [
'amount' => $request->amount,
'amount' => $amount,
'currency' => $request->currency,
'description' => $description,
'metadata' => [

View File

@ -14,6 +14,7 @@ namespace App\PaymentDrivers;
use App\Factory\ClientContactFactory;
use App\Factory\ClientFactory;
use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Mail\PaymentFailedMailer;
use App\Jobs\Util\SystemLogger;
use App\Models\Client;
use App\Models\ClientGatewayToken;
@ -46,7 +47,7 @@ class GoCardlessPaymentDriver extends BaseDriver
private bool $completed = true;
public static $methods = [
GatewayType::BANK_TRANSFER => \App\PaymentDrivers\GoCardless\ACH::class,
GatewayType::BANK_TRANSFER => \App\PaymentDrivers\GoCardless\DirectDebit::class,
GatewayType::DIRECT_DEBIT => \App\PaymentDrivers\GoCardless\DirectDebit::class,
GatewayType::SEPA => \App\PaymentDrivers\GoCardless\SEPA::class,
GatewayType::INSTANT_BANK_PAY => \App\PaymentDrivers\GoCardless\InstantBankPay::class,
@ -79,7 +80,7 @@ class GoCardlessPaymentDriver extends BaseDriver
$this->client
&& isset($this->client->country)
// && in_array($this->client->country->iso_3166_3, ['GBR'])
&& in_array($this->client->currency()->code, ['EUR', 'GBP','DKK','SEK','AUD','NZD','USD'])
&& in_array($this->client->currency()->code, ['EUR', 'GBP','DKK','SEK','AUD','NZD'])
) {
$types[] = GatewayType::DIRECT_DEBIT;
}
@ -242,7 +243,6 @@ class GoCardlessPaymentDriver extends BaseDriver
$this->init();
nlog('GoCardless Event');
nlog($request->all());
if (! $request->has('events')) {
nlog('No GoCardless events to process in response?');
@ -278,9 +278,26 @@ class GoCardlessPaymentDriver extends BaseDriver
->first();
if ($payment) {
if ($payment->status_id == Payment::STATUS_PENDING) {
$payment->service()->deletePayment();
}
$payment->status_id = Payment::STATUS_FAILED;
$payment->save();
nlog('GoCardless completed');
$payment_hash = PaymentHash::where('payment_id', $payment->id)->first();
$error = '';
if (isset($event['details']['description'])) {
$error = $event['details']['description'];
}
PaymentFailedMailer::dispatch(
$payment_hash,
$payment->client->company,
$payment->client,
$error
);
}
}

View File

@ -106,8 +106,7 @@ class BankTransfer
/**
* paymentResponse
*
* @param mixed $request
* @return void
* @param PaymentResponseRequest $request
*/
public function paymentResponse(PaymentResponseRequest $request)
{

View File

@ -101,12 +101,12 @@ class AppServiceProvider extends ServiceProvider
return $this;
});
Mailer::macro('mailgun_config', function (string $secret, string $domain) {
Mailer::macro('mailgun_config', function (string $secret, string $domain, string $endpoint = 'api.mailgun.net') {
Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport([
'transport' => 'mailgun',
'secret' => $secret,
'domain' => $domain,
'endpoint' => config('services.mailgun.endpoint'),
'endpoint' => $endpoint,
'scheme' => config('services.mailgun.scheme'),
]));
@ -114,11 +114,17 @@ class AppServiceProvider extends ServiceProvider
});
/* Extension for custom mailers */
/* Convenience helper for testing s*/
ParallelTesting::setUpTestDatabase(function ($database, $token) {
Artisan::call('db:seed');
});
}
public function register(): void
{
if (Ninja::isHosted()) {
$this->app->register(\App\Providers\BroadcastServiceProvider::class);
}
}
}

View File

@ -28,6 +28,6 @@ class RecurringInvoiceRepository extends BaseRepository
public function getInvitationByKey($key) :?RecurringInvoiceInvitation
{
return RecurringInvoiceInvitation::where('key', $key)->first();
return RecurringInvoiceInvitation::withTrashed()->where('key', $key)->first();
}
}

View File

@ -58,6 +58,8 @@ class Email implements ShouldQueue
protected ?string $client_mailgun_domain = null;
protected ?string $client_mailgun_endpoint = null;
private string $mailer = 'default';
public Mailable $mailable;
@ -143,6 +145,8 @@ class Email implements ShouldQueue
$this->email_object->signature = $this->email_object->settings->email_signature;
$this->email_object->invitation_key = $this->email_object->invitation ? $this->email_object->invitation->key : null;
$this->resolveVariables();
return $this;
@ -233,7 +237,8 @@ class Email implements ShouldQueue
}
if ($this->client_mailgun_secret) {
$mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain);
$mailer->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain, $this->client_mailgun_endpoint);
}
/* Attempt the send! */
@ -304,6 +309,9 @@ class Email implements ShouldQueue
$this->tearDown();
/* Releasing immediately does not add in the backoff */
sleep(rand(0, 3));
$this->release($this->backoff()[$this->attempts()-1]);
$message = null;
@ -479,6 +487,8 @@ class Email implements ShouldQueue
$this->client_mailgun_domain = null;
$this->client_mailgun_endpoint = null;
//always dump the drivers to prevent reuse
app('mail.manager')->forgetMailers();
}
@ -528,6 +538,8 @@ class Email implements ShouldQueue
if (strlen($this->email_object->settings->mailgun_secret) > 2 && strlen($this->email_object->settings->mailgun_domain) > 2) {
$this->client_mailgun_secret = $this->email_object->settings->mailgun_secret;
$this->client_mailgun_domain = $this->email_object->settings->mailgun_domain;
$this->client_mailgun_endpoint = $this->email_object->settings->mailgun_endpoint;
} else {
$this->email_object->settings->email_sending_method = 'default';
return $this->setMailDriver();

View File

@ -76,7 +76,8 @@ class EmailDefaults
->setReplyTo()
->setBcc()
->setAttachments()
->setVariables();
->setVariables()
->setHeaders();
return $this->email->email_object;
}
@ -369,7 +370,7 @@ class EmailDefaults
private function setHeaders(): self
{
if ($this->email->email_object->invitation_key) {
$this->email->email_object->headers = array_merge($this->email->email_object->headers, ['x-invitation-key' => $this->email->email_object->invitation_key]);
$this->email->email_object->headers = array_merge($this->email->email_object->headers, ['x-invitation' => $this->email->email_object->invitation_key]);
}
return $this;

View File

@ -136,6 +136,8 @@ class EmailMailer implements ShouldQueue
/* Releasing immediately does not add in the backoff */
sleep(rand(0, 3));
$this->release($this->backoff()[$this->attempts()-1]);
$message = null;

View File

@ -11,11 +11,9 @@
namespace App\Services\Payment;
use App\Events\Payment\PaymentWasEmailed;
use App\Jobs\Payment\EmailPayment;
use App\Models\ClientContact;
use App\Models\Payment;
use App\Utils\Ninja;
class SendEmail
{
@ -40,7 +38,7 @@ class SendEmail
// if (!$invitation->contact->trashed() && $invitation->contact->email) {
EmailPayment::dispatch($this->payment, $this->payment->company, $this->contact);
event(new PaymentWasEmailed($this->payment, $this->payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
// event(new PaymentWasEmailed($this->payment, $this->payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
// }
// });
// });

View File

@ -47,6 +47,15 @@ class PdfDesigner
return $this;
}
public function buildFromPartials(array $partials): self
{
$this->template = $this->composeFromPartials($partials);
return $this;
}
/**
* If the user has implemented a custom design, then we need to rebuild the design at this point
*/
@ -54,10 +63,8 @@ class PdfDesigner
/**
* Returns the custom HTML design as
* a string
*
* @param array
* @param array $partials
* @return string
*
*/
private function composeFromPartials(array $partials) :string
{

View File

@ -69,7 +69,11 @@ class PdfMock
$pdf_service->config = $pdf_config;
$pdf_designer = (new PdfDesigner($pdf_service))->build();
if(isset($this->request['design']))
$pdf_designer = (new PdfDesigner($pdf_service))->buildFromPartials($this->request['design']);
else
$pdf_designer = (new PdfDesigner($pdf_service))->build();
$pdf_service->designer = $pdf_designer;
$pdf_service->html_variables = $document_type == 'purchase_order' ? $this->getVendorStubVariables() : $this->getStubVariables();

View File

@ -26,17 +26,19 @@ class UpdatePrice extends AbstractService
$line_items = $this->recurring_invoice->line_items;
foreach ($line_items as $key => $line_item) {
$product = Product::where('company_id', $this->recurring_invoice->company_id)
->where('product_key', $line_item->product_key)
->where('is_deleted', 0)
->first();
if ($product) {
$line_items[$key]->cost = $product->cost;
$line_items[$key]->cost = floatval($product->price);
}
}
$this->recurring_invoice->line_items = $line_items;
$this->recurring_invoice->calc()->getInvoice()->save();
}
}

View File

@ -15,7 +15,7 @@ use App\Models\Scheduler;
use Illuminate\Support\Str;
use App\Utils\Traits\MakesHash;
class ScheduleEntity
class EmailRecord
{
use MakesHash;

View File

@ -38,9 +38,9 @@ class SchedulerService
}
}
private function schedule_entity()
private function email_record()
{
(new ScheduleEntity($this->scheduler))->run();
(new EmailRecord($this->scheduler))->run();
}

View File

@ -1,153 +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;
use App\Models\Client;
use App\Models\Company;
use Illuminate\Support\Str;
use App\DataMapper\Tax\de\Rule;
use App\Services\Tax\VatNumberCheck;
class ProcessRule
{
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 $vat_reduced_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->vat_reduced_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) ||
(in_array($this->client_country_code, $this->eu_country_codes) && $this->valid_vat_number && $this->rule->business_tax_exempt)
) {
$this->vat_rate = 0.0;
$this->vat_reduced_rate = 0.0;
}
elseif(!in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && ($this->rule->foreign_consumer_tax_exempt || $this->rule->foreign_business_tax_exempt)) {
nlog($this->client_country_code);
$this->vat_rate = 0.0;
$this->vat_reduced_rate = 0.0;
}
elseif(in_array(strtoupper($this->client_country_code), $this->eu_country_codes) && !$this->valid_vat_number) {
$rate_name = $this->client_country_code."_vat_rate";
$this->vat_rate = $this->rule->{$rate_name};
$this->vat_reduced_rate = $this->rule->vat_reduced_rate;
}
else {
$rate_name = $this->vendor_country_code."_vat_rate";
$this->vat_rate = $this->rule->{$rate_name};
$this->vat_reduced_rate = $this->rule->vat_reduced_rate;
}
return $this;
}
}

View File

@ -0,0 +1,189 @@
<?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 App\Services\Tax\Providers\EuTax;
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;
private mixed $api_credentials;
public function __construct(protected Company $company, protected Client $client)
{
}
public function updateCompanyTaxData(): self
{
$this->configureProvider($this->provider); //hard coded for now to one provider, but we'll be able to swap these out later
$company_details = [
'address1' => $this->company->settings->address1,
'address2' => $this->company->settings->address2,
'city' => $this->company->settings->city,
'state' => $this->company->settings->state,
'postal_code' => $this->company->settings->postal_code,
'country_id' => $this->company->settings->country_id,
];
$tax_provider = new $this->provider($company_details);
$tax_provider->setApiCredentials($this->api_credentials);
$tax_data = $tax_provider->run();
$this->company->tax_data = $tax_data;
$this->company->save();
return $this;
}
public function updateClientTaxData(): self
{
$this->configureProvider($this->provider); //hard coded for now to one provider, but we'll be able to swap these out later
$billing_details =[
'address1' => $this->client->address1,
'address2' => $this->client->address2,
'city' => $this->client->city,
'state' => $this->client->state,
'postal_code' => $this->client->postal_code,
'country_id' => $this->client->country_id,
];
$shipping_details =[
'address1' => $this->client->shipping_address1,
'address2' => $this->client->shipping_address2,
'city' => $this->client->shipping_city,
'state' => $this->client->shipping_state,
'postal_code' => $this->client->shipping_postal_code,
'country_id' => $this->client->shipping_country_id,
];
$tax_provider = new $this->provider();
$tax_provider->setApiCredentials($this->api_credentials);
$tax_data = $tax_provider->run();
$this->company->tax_data = $tax_data;
$this->company->save();
return $this;
}
private function configureProvider(?string $provider): self
{
match($this->client->country->iso_3166_2){
'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;
}
private function configureEuTax(): self
{
$this->provider = EuTax::class;
return $this;
}
private function noTaxRegionDefined(): self
{
throw new \Exception("No tax region defined for this country");
return $this;
}
private function configureZipTax(): self
{
$this->provider = ZipTax::class;
$this->api_credentials = config('services.tax.zip_tax.key');
return $this;
}
}

View File

@ -0,0 +1,20 @@
<?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;
interface TaxProviderInterface
{
public function run();
public function setApiCredentials(mixed $credentials);
}

Some files were not shown because too many files have changed in this diff Show More