mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge branch 'v5-develop' into preview
This commit is contained in:
commit
a4ae273bed
@ -1 +1 @@
|
||||
5.5.122
|
||||
5.6.1
|
@ -127,7 +127,8 @@ class CheckData extends Command
|
||||
$this->checkClientSettings();
|
||||
$this->checkCompanyTokens();
|
||||
$this->checkUserState();
|
||||
|
||||
$this->checkContactEmailAndSendEmailStatus();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
$this->checkAccountStatuses();
|
||||
$this->checkNinjaPortalUrls();
|
||||
@ -434,11 +435,38 @@ class CheckData extends Command
|
||||
|
||||
private function checkEntityInvitations()
|
||||
{
|
||||
|
||||
RecurringInvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
InvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
QuoteInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
CreditInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
|
||||
InvoiceInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii){
|
||||
$ii->sent_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
InvoiceInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||
$ii->viewed_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
|
||||
QuoteInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||
$ii->sent_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
QuoteInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||
$ii->viewed_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
|
||||
CreditInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||
$ii->sent_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
CreditInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||
$ii->viewed_date = null;
|
||||
$ii->saveQuietly();
|
||||
});
|
||||
|
||||
collect([Invoice::class, Quote::class, Credit::class, PurchaseOrder::class])->each(function ($entity) {
|
||||
if ($entity::doesntHave('invitations')->count() > 0) {
|
||||
@ -1114,4 +1142,23 @@ class CheckData extends Command
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function checkContactEmailAndSendEmailStatus()
|
||||
{
|
||||
$q = ClientContact::whereNull('email')
|
||||
->where('send_email', true);
|
||||
|
||||
$this->logMessage($q->count() . " Contacts with Send Email = true but no email address");
|
||||
|
||||
if ($this->option('fix') == 'true') {
|
||||
|
||||
$q->cursor()->each(function ($c){
|
||||
$c->send_email = false;
|
||||
$c->saveQuietly();
|
||||
|
||||
$this->logMessage("Fixing - {$c->id}");
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
app/DataMapper/Tax/AT/Rule.php
Normal file
44
app/DataMapper/Tax/AT/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\AT;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'USt';
|
||||
|
||||
}
|
258
app/DataMapper/Tax/AU/Rule.php
Normal file
258
app/DataMapper/Tax/AU/Rule.php
Normal file
@ -0,0 +1,258 @@
|
||||
<?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\AU;
|
||||
|
||||
use App\DataMapper\Tax\BaseRule;
|
||||
use App\DataMapper\Tax\RuleInterface;
|
||||
use App\Models\Product;
|
||||
|
||||
class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'AU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
/**
|
||||
* Initializes the rules and builds any required data.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function init(): self
|
||||
{
|
||||
$this->calculateRates();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the correct tax rate based on the product type.
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return self
|
||||
*/
|
||||
public function taxByType($item): self
|
||||
{
|
||||
|
||||
if ($this->client->is_tax_exempt) {
|
||||
return $this->taxExempt($item);
|
||||
}
|
||||
|
||||
match(intval($item->tax_id)) {
|
||||
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item),
|
||||
Product::PRODUCT_TYPE_DIGITAL => $this->taxDigital($item),
|
||||
Product::PRODUCT_TYPE_SERVICE => $this->taxService($item),
|
||||
Product::PRODUCT_TYPE_SHIPPING => $this->taxShipping($item),
|
||||
Product::PRODUCT_TYPE_PHYSICAL => $this->taxPhysical($item),
|
||||
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item),
|
||||
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item),
|
||||
Product::PRODUCT_TYPE_ZERO_RATED => $this->zeroRated($item),
|
||||
Product::PRODUCT_TYPE_REVERSE_TAX => $this->reverseTax($item),
|
||||
default => $this->default($item),
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a reduced tax product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function reverseTax($item): self
|
||||
{
|
||||
$this->tax_rate1 = 10;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a reduced tax product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxReduced($item): self
|
||||
{
|
||||
$this->tax_rate1 = $this->reduced_tax_rate;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a zero rated tax product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function zeroRated($item): self
|
||||
{
|
||||
$this->tax_rate1 = 0;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a tax exempt product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxExempt($item): self
|
||||
{
|
||||
$this->tax_name1 = '';
|
||||
$this->tax_rate1 = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a digital product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxDigital($item): self
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a service product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxService($item): self
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a shipping product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxShipping($item): self
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a physical product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function taxPhysical($item): self
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'GST';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for a default product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function default($item): self
|
||||
{
|
||||
|
||||
$this->tax_name1 = '';
|
||||
$this->tax_rate1 = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rate for an override product
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function override($item): self
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tax rates based on the client's location.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function calculateRates(): self
|
||||
{
|
||||
if ($this->client->is_tax_exempt) {
|
||||
// nlog("tax exempt");
|
||||
$this->tax_rate = 0;
|
||||
$this->reduced_tax_rate = 0;
|
||||
// } elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt) {
|
||||
// nlog("euro zone and tax exempt");
|
||||
// $this->tax_rate = 0;
|
||||
// $this->reduced_tax_rate = 0;
|
||||
// } elseif(!in_array($this->client_subregion, $this->eu_country_codes) && ($this->foreign_consumer_tax_exempt || $this->foreign_business_tax_exempt)) { //foreign + tax exempt
|
||||
// nlog("foreign and tax exempt");
|
||||
// $this->tax_rate = 0;
|
||||
// $this->reduced_tax_rate = 0;
|
||||
// } elseif(!in_array($this->client_subregion, $this->eu_country_codes)) {
|
||||
// $this->defaultForeign();
|
||||
// } elseif(in_array($this->client_subregion, $this->eu_country_codes) && !$this->client->has_valid_vat_number) { //eu country / no valid vat
|
||||
// if(($this->client->company->tax_data->seller_subregion != $this->client_subregion) && $this->client->company->tax_data->regions->EU->has_sales_above_threshold) {
|
||||
// nlog("eu zone with sales above threshold");
|
||||
// $this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->tax_rate;
|
||||
// $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_tax_rate;
|
||||
// } else {
|
||||
// nlog("EU with intra-community supply ie DE to DE");
|
||||
// $this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
// $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
// }
|
||||
} else {
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
}
|
44
app/DataMapper/Tax/BE/Rule.php
Normal file
44
app/DataMapper/Tax/BE/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\BE;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'BTW';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/BG/Rule.php
Normal file
44
app/DataMapper/Tax/BG/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\BG;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'НДС';
|
||||
|
||||
}
|
@ -16,7 +16,6 @@ use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use App\DataProviders\USStates;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use App\Services\Tax\Providers\TaxProvider;
|
||||
|
||||
class BaseRule implements RuleInterface
|
||||
{
|
||||
@ -203,18 +202,9 @@ class BaseRule implements RuleInterface
|
||||
$tax_data = $company->origin_tax_data;
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
/** Ensures the client tax data has been updated */
|
||||
// if(!$this->client->tax_data && \DB::transactionLevel() == 0) {
|
||||
|
||||
// $tp = new TaxProvider($company, $this->client);
|
||||
// $tp->updateClientTaxData();
|
||||
// $this->client->fresh();
|
||||
// }
|
||||
|
||||
if($this->client->tax_data)
|
||||
$tax_data = $this->client->tax_data;
|
||||
elseif($this->client->tax_data){
|
||||
|
||||
$tax_data = $this->client->tax_data;
|
||||
|
||||
}
|
||||
|
||||
@ -273,7 +263,8 @@ class BaseRule implements RuleInterface
|
||||
|
||||
public function isTaxableRegion(): bool
|
||||
{
|
||||
return $this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions || $this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax;
|
||||
return $this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions ||
|
||||
(property_exists($this->client->company->tax_data->regions->{$this->client_region}->subregions, $this->client_subregion) && $this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax);
|
||||
}
|
||||
|
||||
public function defaultForeign(): self
|
||||
|
44
app/DataMapper/Tax/CY/Rule.php
Normal file
44
app/DataMapper/Tax/CY/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\CY;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'ΦΠΑ';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/CZ/Rule.php
Normal file
44
app/DataMapper/Tax/CZ/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\CZ;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'DPH';
|
||||
|
||||
}
|
@ -41,6 +41,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'MwSt.';
|
||||
/**
|
||||
* Initializes the rules and builds any required data.
|
||||
*
|
||||
@ -90,7 +91,6 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function reverseTax($item): self
|
||||
{
|
||||
$this->tax_rate1 = 0;
|
||||
$this->tax_name1 = 'ermäßigte MwSt.';
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -103,8 +103,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function taxReduced($item): self
|
||||
{
|
||||
$this->tax_rate1 = $this->reduced_tax_rate;
|
||||
$this->tax_name1 = 'ermäßigte MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -116,8 +115,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function zeroRated($item): self
|
||||
{
|
||||
$this->tax_rate1 = 0;
|
||||
$this->tax_name1 = 'ermäßigte MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -144,8 +142,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -158,8 +155,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -172,8 +168,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -186,8 +181,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
|
||||
$this->tax_rate1 = $this->tax_rate;
|
||||
$this->tax_name1 = 'MwSt.';
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -223,19 +217,20 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function calculateRates(): self
|
||||
{
|
||||
if ($this->client->is_tax_exempt) {
|
||||
nlog("tax exempt");
|
||||
// nlog("tax exempt");
|
||||
$this->tax_rate = 0;
|
||||
$this->reduced_tax_rate = 0;
|
||||
}
|
||||
elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt)
|
||||
elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->vat_number && $this->eu_business_tax_exempt)
|
||||
// elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt)
|
||||
{
|
||||
nlog("euro zone and tax exempt");
|
||||
// nlog("euro zone and tax exempt");
|
||||
$this->tax_rate = 0;
|
||||
$this->reduced_tax_rate = 0;
|
||||
}
|
||||
elseif(!in_array($this->client_subregion, $this->eu_country_codes) && ($this->foreign_consumer_tax_exempt || $this->foreign_business_tax_exempt)) //foreign + tax exempt
|
||||
{
|
||||
nlog("foreign and tax exempt");
|
||||
// nlog("foreign and tax exempt");
|
||||
$this->tax_rate = 0;
|
||||
$this->reduced_tax_rate = 0;
|
||||
}
|
||||
@ -243,22 +238,22 @@ class Rule extends BaseRule implements RuleInterface
|
||||
{
|
||||
$this->defaultForeign();
|
||||
}
|
||||
elseif(in_array($this->client_subregion, $this->eu_country_codes) && !$this->client->has_valid_vat_number) //eu country / no valid vat
|
||||
elseif(in_array($this->client_subregion, $this->eu_country_codes) && !$this->client->vat_number) //eu country / no valid vat
|
||||
{
|
||||
if(($this->client->company->tax_data->seller_subregion != $this->client_subregion) && $this->client->company->tax_data->regions->EU->has_sales_above_threshold)
|
||||
{
|
||||
nlog("eu zone with sales above threshold");
|
||||
// nlog("eu zone with sales above threshold");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_tax_rate;
|
||||
}
|
||||
else {
|
||||
nlog("EU with intra-community supply ie DE to DE");
|
||||
// nlog("EU with intra-community supply ie DE to DE");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nlog("default tax");
|
||||
// nlog("default tax");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
}
|
||||
|
44
app/DataMapper/Tax/DK/Rule.php
Normal file
44
app/DataMapper/Tax/DK/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\DK;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'Moms';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/EE/Rule.php
Normal file
44
app/DataMapper/Tax/EE/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\EE;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'KM';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/ES/Rule.php
Normal file
44
app/DataMapper/Tax/ES/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\ES;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'IVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/FI/Rule.php
Normal file
44
app/DataMapper/Tax/FI/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\FI;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'ALV';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/FR/Rule.php
Normal file
44
app/DataMapper/Tax/FR/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\FR;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'TVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/GR/Rule.php
Normal file
44
app/DataMapper/Tax/GR/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\GR;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'IVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/HR/Rule.php
Normal file
44
app/DataMapper/Tax/HR/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\HR;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'PDV';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/HU/Rule.php
Normal file
44
app/DataMapper/Tax/HU/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\HU;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'ÁFA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/IE/Rule.php
Normal file
44
app/DataMapper/Tax/IE/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\IE;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'VAT';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/IT/Rule.php
Normal file
44
app/DataMapper/Tax/IT/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\IT;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'IVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/LT/Rule.php
Normal file
44
app/DataMapper/Tax/LT/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\LT;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'PVM';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/LU/Rule.php
Normal file
44
app/DataMapper/Tax/LU/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\LU;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'TVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/LV/Rule.php
Normal file
44
app/DataMapper/Tax/LV/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\LV;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'PVN';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/MT/Rule.php
Normal file
44
app/DataMapper/Tax/MT/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\MT;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'VAT';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/NL/Rule.php
Normal file
44
app/DataMapper/Tax/NL/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\NL;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'BTW';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/PT/Rule.php
Normal file
44
app/DataMapper/Tax/PT/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\PT;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'IVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/RO/Rule.php
Normal file
44
app/DataMapper/Tax/RO/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\RO;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'TVA';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/SE/Rule.php
Normal file
44
app/DataMapper/Tax/SE/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\SE;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'Moms';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/SI/Rule.php
Normal file
44
app/DataMapper/Tax/SI/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\SI;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'DDV';
|
||||
|
||||
}
|
44
app/DataMapper/Tax/SK/Rule.php
Normal file
44
app/DataMapper/Tax/SK/Rule.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\SK;
|
||||
|
||||
use App\DataMapper\Tax\DE\Rule as DERule;
|
||||
|
||||
class Rule extends DERule
|
||||
{
|
||||
/** @var string $seller_region */
|
||||
public string $seller_region = 'EU';
|
||||
|
||||
/** @var bool $consumer_tax_exempt */
|
||||
public bool $consumer_tax_exempt = false;
|
||||
|
||||
/** @var bool $business_tax_exempt */
|
||||
public bool $business_tax_exempt = false;
|
||||
|
||||
/** @var bool $eu_business_tax_exempt */
|
||||
public bool $eu_business_tax_exempt = true;
|
||||
|
||||
/** @var bool $foreign_business_tax_exempt */
|
||||
public bool $foreign_business_tax_exempt = false;
|
||||
|
||||
/** @var bool $foreign_consumer_tax_exempt */
|
||||
public bool $foreign_consumer_tax_exempt = false;
|
||||
|
||||
/** @var float $tax_rate */
|
||||
public float $tax_rate = 0;
|
||||
|
||||
/** @var float $reduced_tax_rate */
|
||||
public float $reduced_tax_rate = 0;
|
||||
|
||||
public string $tax_name1 = 'DPH';
|
||||
|
||||
}
|
@ -344,9 +344,9 @@ class TaxModel
|
||||
$this->regions->EU->subregions = new \stdClass();
|
||||
|
||||
$this->regions->EU->subregions->AT = new \stdClass();
|
||||
$this->regions->EU->subregions->AT->tax_rate = 21;
|
||||
$this->regions->EU->subregions->AT->tax_rate = 20;
|
||||
$this->regions->EU->subregions->AT->tax_name = 'USt';
|
||||
$this->regions->EU->subregions->AT->reduced_tax_rate = 11;
|
||||
$this->regions->EU->subregions->AT->reduced_tax_rate = 10;
|
||||
$this->regions->EU->subregions->AT->apply_tax = false;
|
||||
|
||||
$this->regions->EU->subregions->BE = new \stdClass();
|
||||
|
@ -164,7 +164,6 @@ class Rule extends BaseRule implements RuleInterface
|
||||
|
||||
$this->tax_rate1 = $this->invoice->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->tax_rate;
|
||||
$this->tax_name1 = "Sales Tax";
|
||||
// $this->tax_name1 = $this->invoice->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->tax_name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -220,4 +219,4 @@ class Rule extends BaseRule implements RuleInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -67,8 +67,8 @@ class Response
|
||||
public float $taxSales = 0;
|
||||
public string $taxName = "";
|
||||
public float $taxUse = 0;
|
||||
public string $txbService = ""; // N = No, Y = Yes
|
||||
public string $txbFreight = ""; // N = No, Y = Yes
|
||||
public string $txbService = "Y"; // N = No, Y = Yes
|
||||
public string $txbFreight = "Y"; // N = No, Y = Yes
|
||||
public float $stateSalesTax = 0;
|
||||
public float $stateUseTax = 0;
|
||||
public float $citySalesTax = 0;
|
||||
@ -98,7 +98,7 @@ class Response
|
||||
public float $district5UseTax = 0;
|
||||
/* US SPECIFIC TAX CODES */
|
||||
|
||||
public string $originDestination = ""; // defines if the client origin is the locale where the tax is remitted to
|
||||
public string $originDestination = "D"; // defines if the client origin is the locale where the tax is remitted to
|
||||
|
||||
public function __construct($data = null)
|
||||
{
|
||||
|
@ -104,7 +104,8 @@ class Handler extends ExceptionHandler
|
||||
if (Ninja::isHosted()) {
|
||||
|
||||
if($exception instanceof ThrottleRequestsException && class_exists(\Modules\Admin\Events\ThrottledExceptionRaised::class)) {
|
||||
event(new \Modules\Admin\Events\ThrottledExceptionRaised(auth()->user()->account->key));
|
||||
$uri = urldecode(request()->getRequestUri());
|
||||
event(new \Modules\Admin\Events\ThrottledExceptionRaised(auth()->user()?->account?->key, $uri, request()->ip()));
|
||||
}
|
||||
|
||||
Integration::configureScope(function (Scope $scope): void {
|
||||
|
@ -106,6 +106,16 @@ class ClientFilters extends QueryFilters
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
public function group(string $group_id = ''): Builder
|
||||
{
|
||||
if (strlen($group_id) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('group_settings_id', $this->decodePrimaryKey($group_id));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
|
@ -102,8 +102,13 @@ class PaymentFilters extends QueryFilters
|
||||
if (count($payment_filters) >0) {
|
||||
$query->whereIn('status_id', $payment_filters);
|
||||
}
|
||||
|
||||
if(in_array('partially_unapplied', $status_parameters)) {
|
||||
$query->where('amount', '>', 'applied')->where('refunded', 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,7 @@ abstract class QueryFilters
|
||||
*/
|
||||
public function status(string $filter = ''): Builder
|
||||
{
|
||||
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
@ -146,17 +147,17 @@ abstract class QueryFilters
|
||||
|
||||
return $this->builder->where(function ($query) use ($filters) {
|
||||
if (in_array(self::STATUS_ACTIVE, $filters)) {
|
||||
$query->orWhereNull('deleted_at');
|
||||
$query = $query->orWhereNull('deleted_at');
|
||||
}
|
||||
|
||||
if (in_array(self::STATUS_ARCHIVED, $filters)) {
|
||||
$query->orWhere(function ($query) {
|
||||
$query->whereNotNull('deleted_at')->where('is_deleted', 0);
|
||||
$query = $query->orWhere(function ($q) {
|
||||
$q->whereNotNull('deleted_at')->where('is_deleted', 0);
|
||||
});
|
||||
}
|
||||
|
||||
if (in_array(self::STATUS_DELETED, $filters)) {
|
||||
$query->orWhere('is_deleted', 1);
|
||||
$query = $query->orWhere('is_deleted', 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -60,33 +60,33 @@ class InvoiceItemSum
|
||||
];
|
||||
|
||||
private array $tax_jurisdictions = [
|
||||
// 'AT', // Austria
|
||||
// 'BE', // Belgium
|
||||
// 'BG', // Bulgaria
|
||||
// 'CY', // Cyprus
|
||||
// 'CZ', // Czech Republic
|
||||
'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
|
||||
'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
|
||||
|
||||
@ -170,7 +170,7 @@ class InvoiceItemSum
|
||||
private function shouldCalculateTax(): self
|
||||
{
|
||||
|
||||
if (!$this->invoice->company->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {
|
||||
$this->calc_tax = false;
|
||||
return $this;
|
||||
}
|
||||
|
@ -11,12 +11,13 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
|
@ -365,21 +365,22 @@ class LoginController extends BaseController
|
||||
|
||||
private function hydrateCompanyUser(): Builder
|
||||
{
|
||||
$cu = CompanyUser::query()->where('user_id', auth()->user()->id);
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$cu = CompanyUser::query()->where('user_id', $user->id);
|
||||
|
||||
if ($cu->count() == 0) {
|
||||
return $cu;
|
||||
}
|
||||
|
||||
if (CompanyUser::query()->where('user_id', auth()->user()->id)->where('company_id', auth()->user()->account->default_company_id)->exists()) {
|
||||
$set_company = auth()->user()->account->default_company;
|
||||
if (CompanyUser::query()->where('user_id', $user->id)->where('company_id', $user->account->default_company_id)->exists()) {
|
||||
$set_company = $user->account->default_company;
|
||||
} else {
|
||||
$set_company = $cu->first()->company;
|
||||
$set_company = CompanyUser::query()->where('user_id', $user->id)->first()->company;
|
||||
}
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$user->setCompany($set_company);
|
||||
|
||||
$this->setLoginCache($user);
|
||||
@ -389,15 +390,15 @@ class LoginController extends BaseController
|
||||
$truth->setUser($user);
|
||||
$truth->setCompany($set_company);
|
||||
|
||||
$cu->first()->account->companies->each(function ($company) use ($cu) {
|
||||
$user->account->companies->each(function ($company) use ($user) {
|
||||
if ($company->tokens()->where('is_system', true)->count() == 0) {
|
||||
(new CreateCompanyToken($company, $cu->first()->user, request()->server('HTTP_USER_AGENT')))->handle();
|
||||
(new CreateCompanyToken($company, $user, request()->server('HTTP_USER_AGENT')))->handle();
|
||||
}
|
||||
});
|
||||
|
||||
$truth->setCompanyToken(CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $set_company->id)->first());
|
||||
$truth->setCompanyToken(CompanyToken::where('user_id', $user->id)->where('company_id', $set_company->id)->first());
|
||||
|
||||
return $cu;
|
||||
return CompanyUser::query()->where('user_id', $user->id);
|
||||
}
|
||||
|
||||
private function handleMicrosoftOauth()
|
||||
@ -639,8 +640,8 @@ class LoginController extends BaseController
|
||||
$parameters = ['response_type' => 'code', 'redirect_uri' => config('ninja.app_url') . "/auth/microsoft"];
|
||||
}
|
||||
|
||||
if(request()->hasHeader('X-REACT'))
|
||||
Cache::put("react_redir:".auth()->user()->account->key, 'true', 300);
|
||||
if(request()->hasHeader('X-REACT') || request()->query('react'))
|
||||
Cache::put("react_redir:".auth()->user()?->account->key, 'true', 300);
|
||||
|
||||
if (request()->has('code')) {
|
||||
return $this->handleProviderCallback($provider);
|
||||
@ -696,7 +697,7 @@ class LoginController extends BaseController
|
||||
|
||||
$redirect_url = '/#/';
|
||||
|
||||
$request_from_react = Cache::pull("react_redir:".auth()->user()->account->key);
|
||||
$request_from_react = Cache::pull("react_redir:".auth()->user()?->account?->key);
|
||||
|
||||
if($request_from_react)
|
||||
$redirect_url = config('ninja.react_url')."/#/settings/user_details/connect";
|
||||
|
28
app/Http/Controllers/Auth/PasswordTimeoutController.php
Normal file
28
app/Http/Controllers/Auth/PasswordTimeoutController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?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\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class PasswordTimeoutController extends Controller
|
||||
{
|
||||
|
||||
public function __invoke()
|
||||
{
|
||||
$cached = Cache::get(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in');
|
||||
|
||||
return $cached ? response()->json(['message' => 'Password is valid'], 200) : response()->json(['message' => 'Invalid Password'], 412);
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class ResetPasswordController extends Controller
|
||||
$account = Account::first();
|
||||
}
|
||||
|
||||
return $this->render('auth.passwords.reset', ['root' => 'themes', 'token' => $token, 'account' => $account]);
|
||||
return $this->render('auth.passwords.reset', ['root' => 'themes', 'token' => $token, 'account' => $account, 'email' => $request->email]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,4 +111,28 @@ class ResetPasswordController extends Controller
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetResponse(Request $request, $response)
|
||||
{
|
||||
if ($request->wantsJson()) {
|
||||
return new JsonResponse(['message' => trans($response)], 200);
|
||||
}
|
||||
|
||||
if(Ninja::isHosted() && $request->hasHeader('X-React')){
|
||||
return redirect('https://app.invoicing.co/#/login');
|
||||
}
|
||||
elseif($request->hasHeader('X-React'))
|
||||
return redirect('/#/login');
|
||||
|
||||
return redirect($this->redirectPath())
|
||||
->with('status', trans($response));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -422,8 +422,12 @@ class CompanyController extends BaseController
|
||||
if($request->has('e_invoice_certificate') && !is_null($request->file("e_invoice_certificate"))){
|
||||
|
||||
$company->e_invoice_certificate = base64_encode($request->file("e_invoice_certificate")->get());
|
||||
$company->save();
|
||||
|
||||
$settings = $company->settings;
|
||||
$settings->enable_e_invoice = true;
|
||||
|
||||
$company->save();
|
||||
|
||||
}
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $company, $company);
|
||||
|
@ -748,33 +748,12 @@ class InvoiceController extends BaseController
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
//check query parameter for email_type and set the template else use calculateTemplate
|
||||
|
||||
// if (request()->has('email_type') && in_array(request()->input('email_type'), ['reminder1', 'reminder2', 'reminder3', 'reminder_endless', 'custom1', 'custom2', 'custom3'])) {
|
||||
if (request()->has('email_type') && property_exists($invoice->company->settings, request()->input('email_type'))) {
|
||||
$this->reminder_template = $invoice->client->getSetting(request()->input('email_type'));
|
||||
} else {
|
||||
$this->reminder_template = $invoice->calculateTemplate('invoice');
|
||||
}
|
||||
|
||||
BulkInvoiceJob::dispatch($invoice, $this->reminder_template);
|
||||
|
||||
if (! $bulk) {
|
||||
return response()->json(['message' => 'email sent'], 200);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'send_email':
|
||||
//check query parameter for email_type and set the template else use calculateTemplate
|
||||
|
||||
$template = request()->has('email_type') ? request()->input('email_type') : $invoice->calculateTemplate('invoice');
|
||||
|
||||
if (request()->has('email_type') && property_exists($invoice->company->settings, request()->input('email_type'))) {
|
||||
$this->reminder_template = $invoice->client->getSetting(request()->input('email_type'));
|
||||
} else {
|
||||
$this->reminder_template = $invoice->calculateTemplate('invoice');
|
||||
}
|
||||
|
||||
BulkInvoiceJob::dispatch($invoice, $this->reminder_template);
|
||||
BulkInvoiceJob::dispatch($invoice, $template);
|
||||
|
||||
if (! $bulk) {
|
||||
return response()->json(['message' => 'email sent'], 200);
|
||||
|
@ -436,6 +436,14 @@ class MigrationController extends BaseController
|
||||
StartMigration::dispatch($migration_file, $user, $fresh_company);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'_id' => Str::uuid(),
|
||||
'method' => config('queue.default'),
|
||||
'started_at' => now(),
|
||||
], 200);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,9 @@ class PreviewController extends BaseController
|
||||
if (Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) {
|
||||
return response()->json(['message' => 'This server cannot handle this request.'], 400);
|
||||
}
|
||||
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
@ -322,6 +324,8 @@ class PreviewController extends BaseController
|
||||
|
||||
$response = Response::make($file_path, 200);
|
||||
$response->header('Content-Type', 'application/pdf');
|
||||
$response->header('Server-Timing', microtime(true)-$start);
|
||||
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@ -15,44 +15,18 @@ use App\Libraries\MultiDB;
|
||||
|
||||
class SubdomainController extends BaseController
|
||||
{
|
||||
private $protected = [
|
||||
'www',
|
||||
'app',
|
||||
'ninja',
|
||||
'sentry',
|
||||
'sentry2',
|
||||
'staging',
|
||||
'pdf',
|
||||
'demo',
|
||||
'docs',
|
||||
'client_domain',
|
||||
'custom_domain',
|
||||
'preview',
|
||||
'invoiceninja',
|
||||
'cname',
|
||||
'sandbox',
|
||||
'stage',
|
||||
'html',
|
||||
'lb',
|
||||
'shopify',
|
||||
'beta',
|
||||
'prometh',
|
||||
'license',
|
||||
'socket',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
* Return if a subdomain is available.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (in_array(request()->input('subdomain'), $this->protected) || MultiDB::findAndSetDbByDomain(['subdomain' => request()->input('subdomain')])) {
|
||||
if (!MultiDB::checkDomainAvailable(request()->input('subdomain'))) {
|
||||
return response()->json(['message' => 'Domain not available'], 401);
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ trait VerifiesUserEmail
|
||||
return $this->render('auth.confirmed', [
|
||||
'root' => 'themes',
|
||||
'message' => ctrans('texts.security_confirmation'),
|
||||
'redirect_url' => request()->hasHeader('X-React') ? 'https://app.invoicing.co/#/' : url('/'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\TwoFactor\EnableTwoFactorRequest;
|
||||
use App\Models\User;
|
||||
use App\Transformers\UserTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use PragmaRX\Google2FA\Google2FA;
|
||||
use App\Transformers\UserTransformer;
|
||||
use App\Http\Requests\TwoFactor\EnableTwoFactorRequest;
|
||||
|
||||
class TwoFactorController extends BaseController
|
||||
{
|
||||
@ -24,11 +25,15 @@ class TwoFactorController extends BaseController
|
||||
|
||||
public function setupTwoFactor()
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->google_2fa_secret) {
|
||||
return response()->json(['message' => '2FA already enabled'], 400);
|
||||
} elseif (! $user->phone) {
|
||||
} elseif(Ninja::isSelfHost()){
|
||||
|
||||
}
|
||||
elseif (! $user->phone) {
|
||||
return response()->json(['message' => ctrans('texts.set_phone_for_two_factor')], 400);
|
||||
} elseif (! $user->isVerified()) {
|
||||
return response()->json(['message' => 'Please confirm your account first'], 400);
|
||||
|
@ -231,8 +231,11 @@ class UserController extends BaseController
|
||||
|
||||
$return_user_collection = collect();
|
||||
|
||||
$users->each(function ($user, $key) use ($action, $return_user_collection) {
|
||||
if (auth()->user()->can('edit', $user)) {
|
||||
/** @var \App\Models\User $logged_in_user */
|
||||
$logged_in_user = auth()->user();
|
||||
|
||||
$users->each(function ($user, $key) use ($logged_in_user, $action, $return_user_collection) {
|
||||
if ($logged_in_user->can('edit', $user)) {
|
||||
$this->user_repo->{$action}($user);
|
||||
|
||||
$return_user_collection->push($user->id);
|
||||
@ -251,12 +254,11 @@ class UserController extends BaseController
|
||||
*/
|
||||
public function detach(DetachCompanyUserRequest $request, User $user)
|
||||
{
|
||||
// if ($request->entityIsDeleted($user)) {
|
||||
// return $request->disallowUpdate();
|
||||
// }
|
||||
/** @var \App\Models\User $logged_in_user */
|
||||
$logged_in_user = auth()->user();
|
||||
|
||||
$company_user = CompanyUser::whereUserId($user->id)
|
||||
->whereCompanyId(auth()->user()->companyId())
|
||||
->whereCompanyId($logged_in_user->companyId())
|
||||
->withTrashed()
|
||||
->first();
|
||||
|
||||
|
@ -146,25 +146,30 @@ class PurchaseOrderController extends Controller
|
||||
$purchase_orders = PurchaseOrder::query()
|
||||
->whereIn('id', $this->transformKeys($data['purchase_orders']))
|
||||
->where('company_id', auth()->guard('vendor')->user()->vendor->company_id)
|
||||
->whereIn('status_id', [PurchaseOrder::STATUS_DRAFT, PurchaseOrder::STATUS_SENT])
|
||||
->where('is_deleted', 0)
|
||||
->withTrashed()
|
||||
->cursor()->each(function ($purchase_order) {
|
||||
$purchase_order->service()
|
||||
->markSent()
|
||||
->applyNumber()
|
||||
->setStatus(PurchaseOrder::STATUS_ACCEPTED)
|
||||
->save();
|
||||
->withTrashed();
|
||||
|
||||
if (request()->has('signature') && ! is_null(request()->signature) && ! empty(request()->signature)) {
|
||||
InjectSignature::dispatch($purchase_order, request()->signature);
|
||||
}
|
||||
$purchase_count_query = clone $purchase_orders;
|
||||
|
||||
event(new PurchaseOrderWasAccepted($purchase_order, auth()->guard('vendor')->user(), $purchase_order->company, Ninja::eventVars()));
|
||||
});
|
||||
$purchase_orders->whereIn('status_id', [PurchaseOrder::STATUS_DRAFT, PurchaseOrder::STATUS_SENT])
|
||||
->cursor()->each(function ($purchase_order) {
|
||||
|
||||
$purchase_order->service()
|
||||
->markSent()
|
||||
->applyNumber()
|
||||
->setStatus(PurchaseOrder::STATUS_ACCEPTED)
|
||||
->save();
|
||||
|
||||
if (count($data['purchase_orders']) == 1) {
|
||||
$purchase_order = PurchaseOrder::withTrashed()->where('is_deleted', 0)->whereIn('id', $this->transformKeys($data['purchase_orders']))->first();
|
||||
if (request()->has('signature') && ! is_null(request()->signature) && ! empty(request()->signature)) {
|
||||
(new InjectSignature($purchase_order, request()->signature))->handle();
|
||||
// InjectSignature::dispatch($purchase_order, request()->signature);
|
||||
}
|
||||
|
||||
event(new PurchaseOrderWasAccepted($purchase_order, auth()->guard('vendor')->user(), $purchase_order->company, Ninja::eventVars()));
|
||||
});
|
||||
|
||||
if ($purchase_count_query->count() == 1) {
|
||||
$purchase_order = $purchase_count_query->first();
|
||||
|
||||
return redirect()->route('vendor.purchase_order.show', ['purchase_order' => $purchase_order->hashed_id]);
|
||||
} else {
|
||||
|
@ -15,7 +15,7 @@ class Cors
|
||||
// ALLOW OPTIONS METHOD
|
||||
$headers = [
|
||||
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
|
||||
'Access-Control-Allow-Headers'=> 'X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-CLIENT-VERSION,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Disposition,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE',
|
||||
'Access-Control-Allow-Headers'=> 'X-React,X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-CLIENT-VERSION,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Disposition,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE',
|
||||
];
|
||||
|
||||
return Response::make('OK', 200, $headers);
|
||||
@ -25,7 +25,7 @@ class Cors
|
||||
|
||||
$response->headers->set('Access-Control-Allow-Origin', '*');
|
||||
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
$response->headers->set('Access-Control-Allow-Headers', 'X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Disposition,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE');
|
||||
$response->headers->set('Access-Control-Allow-Headers', 'X-React,X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Disposition,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE');
|
||||
$response->headers->set('Access-Control-Expose-Headers', 'X-APP-VERSION,X-MINIMUM-CLIENT-VERSION,Content-Disposition');
|
||||
$response->headers->set('X-APP-VERSION', config('ninja.app_version'));
|
||||
$response->headers->set('X-MINIMUM-CLIENT-VERSION', config('ninja.minimum_client_version'));
|
||||
|
@ -37,6 +37,7 @@ class PasswordProtection
|
||||
'errors' => new stdClass,
|
||||
];
|
||||
|
||||
/** @var \App\Models\User auth()->user() */
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
|
||||
if ($timeout == 0) {
|
||||
|
@ -23,6 +23,7 @@ use Turbo124\Beacon\Facades\LightLogs;
|
||||
*/
|
||||
class QueryLogging
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
@ -33,26 +34,30 @@ class QueryLogging
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
|
||||
// Enable query logging for development
|
||||
if (! Ninja::isHosted() || ! config('beacon.enabled')) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$timeStart = microtime(true);
|
||||
|
||||
DB::enableQueryLog();
|
||||
return $next($request);
|
||||
|
||||
}
|
||||
|
||||
public function terminate($request, $response)
|
||||
{
|
||||
if (! Ninja::isHosted() || ! config('beacon.enabled'))
|
||||
return;
|
||||
|
||||
$response = $next($request);
|
||||
// hide requests made by debugbar
|
||||
if (strstr($request->url(), '_debugbar') === false) {
|
||||
|
||||
$queries = DB::getQueryLog();
|
||||
$count = count($queries);
|
||||
$timeEnd = microtime(true);
|
||||
$time = $timeEnd - $timeStart;
|
||||
$time = $timeEnd - LARAVEL_START;
|
||||
|
||||
// nlog("Query count = {$count}");
|
||||
// nlog($queries);
|
||||
// nlog($request->url());
|
||||
|
||||
if ($count > 175) {
|
||||
nlog("Query count = {$count}");
|
||||
nlog($queries);
|
||||
@ -60,18 +65,17 @@ class QueryLogging
|
||||
|
||||
$ip = '';
|
||||
|
||||
if (request()->hasHeader('Cf-Connecting-Ip')) {
|
||||
$ip = request()->header('Cf-Connecting-Ip');
|
||||
} elseif (request()->hasHeader('X-Forwarded-For')) {
|
||||
$ip = request()->header('Cf-Connecting-Ip');
|
||||
if ($request->hasHeader('Cf-Connecting-Ip')) {
|
||||
$ip = $request->header('Cf-Connecting-Ip');
|
||||
} elseif ($request->hasHeader('X-Forwarded-For')) {
|
||||
$ip = $request->header('Cf-Connecting-Ip');
|
||||
} else {
|
||||
$ip = request()->ip();
|
||||
$ip = $request->ip();
|
||||
}
|
||||
|
||||
LightLogs::create(new DbQuery($request->method(), substr(urldecode($request->url()), 0, 180), $count, $time, $ip))
|
||||
->batch();
|
||||
->batch();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ class UpdateCompanyRequest extends Request
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->company);
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
return $user->can('edit', $this->company);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
@ -59,14 +61,11 @@ class UpdateCompanyRequest extends Request
|
||||
|
||||
if (isset($input['portal_mode']) && ($input['portal_mode'] == 'domain' || $input['portal_mode'] == 'iframe')) {
|
||||
$rules['portal_domain'] = 'sometimes|url';
|
||||
} else {
|
||||
if (Ninja::isHosted()) {
|
||||
$rules['subdomain'] = ['nullable', 'regex:/^[a-zA-Z0-9.-]+[a-zA-Z0-9]$/', new ValidSubdomain($this->all())];
|
||||
} else {
|
||||
$rules['subdomain'] = 'nullable|regex:/^[a-zA-Z0-9.-]+[a-zA-Z0-9]$/';
|
||||
}
|
||||
}
|
||||
|
||||
if (Ninja::isHosted())
|
||||
$rules['subdomain'] = ['nullable', 'regex:/^[a-zA-Z0-9.-]+[a-zA-Z0-9]$/', new ValidSubdomain()];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
@ -83,6 +82,10 @@ class UpdateCompanyRequest extends Request
|
||||
$input['settings'] = (array)$this->filterSaveableSettings($input['settings']);
|
||||
}
|
||||
|
||||
if(array_key_exists('subdomain', $input) && $this->subdomain == $input['subdomain']) {
|
||||
unset($input['subdomain']);
|
||||
}
|
||||
|
||||
if(array_key_exists('e_invoice_certificate_passphrase', $input) && empty($input['e_invoice_certificate_passphrase'])) {
|
||||
unset($input['e_invoice_certificate_passphrase']);
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ class BulkInvoiceRequest extends Request
|
||||
{
|
||||
return [
|
||||
'action' => 'required|string',
|
||||
'ids' => 'required'
|
||||
'ids' => 'required',
|
||||
'email_type' => 'sometimes|in:reminder1,reminder2,reminder3,reminder_endless,custom1,custom2,custom3,invoice,quote,credit,payment,payment_partial,statement,purchase_order'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ class UpdateInvoiceRequest extends Request
|
||||
$rules['tax_name2'] = 'bail|sometimes|string|nullable';
|
||||
$rules['tax_name3'] = 'bail|sometimes|string|nullable';
|
||||
|
||||
// not needed.
|
||||
// $rules['partial_due_date'] = 'bail|sometimes|required_unless:partial,0,null';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,11 @@ class StoreSchedulerRequest extends Request
|
||||
if (array_key_exists('next_run', $input) && is_string($input['next_run'])) {
|
||||
$this->merge(['next_run_client' => $input['next_run']]);
|
||||
}
|
||||
|
||||
|
||||
if($input['template'] == 'email_record'){
|
||||
$input['frequency_id'] = 0;
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -57,5 +57,12 @@ class UpdateSchedulerRequest extends Request
|
||||
$this->merge(['next_run_client' => $input['next_run']]);
|
||||
}
|
||||
|
||||
if($input['template'] == 'email_record') {
|
||||
$input['frequency_id'] = 0;
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,25 +19,18 @@ use Illuminate\Contracts\Validation\Rule;
|
||||
*/
|
||||
class ValidSubdomain implements Rule
|
||||
{
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
private $input;
|
||||
|
||||
public function __construct($input)
|
||||
public function __construct()
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if (empty($input['subdomain'])) {
|
||||
if (empty($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return MultiDB::checkDomainAvailable($input['subdomain']);
|
||||
return MultiDB::checkDomainAvailable($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Jobs\Client;
|
||||
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
@ -51,9 +52,9 @@ class UpdateTaxData implements ShouldQueue
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
if(!config('services.tax.zip_tax.key'))
|
||||
if($this->company->account->isFreeHostedClient())
|
||||
return;
|
||||
|
||||
|
||||
$tax_provider = new \App\Services\Tax\Providers\TaxProvider($this->company, $this->client);
|
||||
|
||||
try {
|
||||
@ -63,8 +64,7 @@ class UpdateTaxData implements ShouldQueue
|
||||
if (!$this->client->state && $this->client->postal_code) {
|
||||
|
||||
$this->client->state = USStates::getState($this->client->postal_code);
|
||||
|
||||
$this->client->save();
|
||||
$this->client->saveQuietly();
|
||||
|
||||
}
|
||||
|
||||
@ -73,11 +73,80 @@ class UpdateTaxData implements ShouldQueue
|
||||
nlog("problem getting tax data => ".$e->getMessage());
|
||||
}
|
||||
|
||||
/** Set static tax information */
|
||||
if(!$tax_provider->updatedTaxStatus() && $this->client->country_id == 840){
|
||||
|
||||
$calculated_state = false;
|
||||
|
||||
/** State must be calculated else default to the company state for taxes */
|
||||
if(array_key_exists($this->client->shipping_state, USStates::get())) {
|
||||
$calculated_state = $this->client->shipping_state;
|
||||
$calculated_postal_code = $this->client->shipping_postal_code;
|
||||
$calculated_city = $this->client->shipping_city;
|
||||
}
|
||||
elseif(array_key_exists($this->client->state, USStates::get())){
|
||||
$calculated_state = $this->client->state;
|
||||
$calculated_postal_code = $this->client->postal_code;
|
||||
$calculated_city = $this->client->city;
|
||||
}
|
||||
else {
|
||||
|
||||
try{
|
||||
$calculated_state = USStates::getState($this->client->shipping_postal_code);
|
||||
$calculated_postal_code = $this->client->shipping_postal_code;
|
||||
$calculated_city = $this->client->shipping_city;
|
||||
}
|
||||
catch(\Exception $e){
|
||||
nlog("could not calculate state from postal code => {$this->client->shipping_postal_code} or from state {$this->client->shipping_state}");
|
||||
}
|
||||
|
||||
if(!$calculated_state) {
|
||||
try {
|
||||
$calculated_state = USStates::getState($this->client->postal_code);
|
||||
$calculated_postal_code = $this->client->postal_code;
|
||||
$calculated_city = $this->client->city;
|
||||
} catch(\Exception $e) {
|
||||
nlog("could not calculate state from postal code => {$this->client->postal_code} or from state {$this->client->state}");
|
||||
}
|
||||
}
|
||||
|
||||
if($this->company->tax_data?->seller_subregion)
|
||||
$calculated_state = $this->company->tax_data?->seller_subregion;
|
||||
|
||||
nlog("i am trying");
|
||||
|
||||
if(!$calculated_state) {
|
||||
nlog("could not determine state");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$data = [
|
||||
'seller_subregion' => $this->company->tax_data?->seller_subregion ?: '',
|
||||
'geoPostalCode' => $this->client->postal_code ?? '',
|
||||
'geoCity' => $this->client->city ?? '',
|
||||
'geoState' => $calculated_state,
|
||||
'taxSales' => $this->company->tax_data->regions->US->subregions?->{$calculated_state}?->taxSales ?? 0,
|
||||
];
|
||||
|
||||
$tax_data = new Response($data);
|
||||
|
||||
$this->client->tax_data = $tax_data;
|
||||
$this->client->saveQuietly();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
return [new WithoutOverlapping($this->company->id)];
|
||||
return [new WithoutOverlapping($this->client->id.$this->company->id)];
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
{
|
||||
nlog("UpdateTaxData failed => ".$exception->getMessage());
|
||||
}
|
||||
|
||||
}
|
@ -11,12 +11,12 @@
|
||||
|
||||
namespace App\Jobs\Company;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Jobs\Client\UpdateTaxData;
|
||||
use App\DataProviders\USStates;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Services\Tax\Providers\TaxProvider;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -40,33 +40,52 @@ class CompanyTaxRate implements ShouldQueue
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if(!config('services.tax.zip_tax.key')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MultiDB::setDB($this->company->db);
|
||||
|
||||
$tp = new TaxProvider($this->company);
|
||||
|
||||
$tp->updateCompanyTaxData();
|
||||
|
||||
$tp = null;
|
||||
|
||||
Client::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', false)
|
||||
->where('country_id', 840)
|
||||
->whereNotNull('postal_code')
|
||||
->whereNull('tax_data')
|
||||
->where('is_tax_exempt', false)
|
||||
->cursor()
|
||||
->each(function ($client) {
|
||||
|
||||
(new UpdateTaxData($client, $this->company))->handle();
|
||||
|
||||
});
|
||||
|
||||
if(!$tp->updatedTaxStatus() && $this->company->settings->country_id == '840') {
|
||||
|
||||
$calculated_state = false;
|
||||
|
||||
/** State must be calculated else default to the company state for taxes */
|
||||
if(array_key_exists($this->company->settings->state, USStates::get())) {
|
||||
$calculated_state = $this->company->setting->state;
|
||||
}
|
||||
else {
|
||||
|
||||
try{
|
||||
$calculated_state = USStates::getState($this->company->settings->postal_code);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
nlog("could not calculate state from postal code => {$this->company->settings->postal_code} or from state {$this->company->settings->state}");
|
||||
}
|
||||
|
||||
if(!$calculated_state && $this->company->tax_data?->seller_subregion)
|
||||
$calculated_state = $this->company->tax_data?->seller_subregion;
|
||||
|
||||
if(!$calculated_state)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
$data = [
|
||||
'seller_subregion' => $this->company->origin_tax_data?->seller_subregion ?: '',
|
||||
'geoPostalCode' => $this->company->settings->postal_code ?? '',
|
||||
'geoCity' => $this->company->settings->city ?? '',
|
||||
'geoState' => $calculated_state,
|
||||
'taxSales' => $this->company->tax_data->regions->US->subregions?->{$calculated_state}?->taxSales ?? 0,
|
||||
];
|
||||
|
||||
$tax_data = new Response($data);
|
||||
|
||||
$this->company->origin_tax_data = $tax_data;
|
||||
$this->company->saveQuietly();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
@ -74,4 +93,7 @@ class CompanyTaxRate implements ShouldQueue
|
||||
return [new WithoutOverlapping($this->company->id)];
|
||||
}
|
||||
|
||||
public function failed($e){
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
}
|
@ -152,12 +152,14 @@ class CreateCompany
|
||||
|
||||
$company->save();
|
||||
|
||||
$user = $this->account->users()->orderBy('id','asc')->first();
|
||||
//user does not exist yet.
|
||||
// MultiDB::setDb($company->db);
|
||||
// $user = \App\Models\User::where('account_id', $company->account_id)->first();
|
||||
|
||||
$tax_rate = TaxRateFactory::create($company->id, $user->id);
|
||||
$tax_rate->name = $company->tax_data->regions->EU->subregions->ES->tax_name;
|
||||
$tax_rate->rate = $company->tax_data->regions->EU->subregions->ES->tax_rate;
|
||||
$tax_rate->save();
|
||||
// $tax_rate = TaxRateFactory::create($company->id, $user->id);
|
||||
// $tax_rate->name = $company->tax_data->regions->EU->subregions->ES->tax_name;
|
||||
// $tax_rate->rate = $company->tax_data->regions->EU->subregions->ES->tax_rate;
|
||||
// $tax_rate->save();
|
||||
|
||||
return $company;
|
||||
|
||||
@ -191,18 +193,23 @@ class CreateCompany
|
||||
|
||||
$company->save();
|
||||
|
||||
$user = $company->account->users()->first();
|
||||
//$user = $company->account->users()->first();
|
||||
//user does not exist yet.
|
||||
// MultiDB::setDb($company->db);
|
||||
// $user = \App\Models\User::where('account_id', $company->account_id)->first();
|
||||
|
||||
$tax_rate = TaxRateFactory::create($company->id, $user->id);
|
||||
$tax_rate->name = $company->tax_data->regions->AU->subregions->AU->tax_name;
|
||||
$tax_rate->rate = $company->tax_data->regions->AU->subregions->AU->tax_rate;
|
||||
$tax_rate->save();
|
||||
|
||||
// $tax_rate = TaxRateFactory::create($company->id, $user->id);
|
||||
// $tax_rate->name = $company->tax_data->regions->AU->subregions->AU->tax_name;
|
||||
// $tax_rate->rate = $company->tax_data->regions->AU->subregions->AU->tax_rate;
|
||||
// $tax_rate->save();
|
||||
|
||||
return $company;
|
||||
|
||||
}
|
||||
catch(\Exception $e){
|
||||
nlog("SETUP: could not complete setup for Spanish Locale");
|
||||
nlog($e->getMessage());
|
||||
nlog("SETUP: could not complete setup for Australian Locale");
|
||||
}
|
||||
|
||||
$company->save();
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Jobs\Cron;
|
||||
|
||||
use App\Models\Payment;
|
||||
use App\Models\Project;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
@ -65,7 +66,6 @@ class UpdateCalculatedFields
|
||||
$project->save();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ class CreateEntityPdf implements ShouldQueue
|
||||
(new CreateEInvoice($this->entity, true))->handle();
|
||||
}
|
||||
$this->invitation = null;
|
||||
$this->entity = null;
|
||||
// $this->entity = null;
|
||||
$this->company = null;
|
||||
$this->client = null;
|
||||
$this->contact = null;
|
||||
|
@ -144,12 +144,12 @@ class AdjustProductInventory implements ShouldQueue
|
||||
private function notifyStocklevels(Product $product, string $notification_level)
|
||||
{
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new InventoryNotificationObject($product, $notification_level))->build());
|
||||
$nmo->company = $this->company;
|
||||
$nmo->settings = $this->company->settings;
|
||||
|
||||
$this->company->company_users->each(function ($cu) use ($product, $nmo) {
|
||||
$this->company->company_users->each(function ($cu) use ($product, $nmo, $notification_level) {
|
||||
if ($this->checkNotificationExists($cu, $product, ['inventory_all', 'inventory_user', 'inventory_threshold_all', 'inventory_threshold_user'])) {
|
||||
$nmo->mailable = new NinjaMailer((new InventoryNotificationObject($product, $notification_level, $cu->portalType()))->build());
|
||||
$nmo->to_user = $cu->user;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ class CheckGatewayFee implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
nlog("Checking Gateway Fees for Invoice Id = {$this->invoice_id}");
|
||||
|
||||
MultiDB::setDb($this->db);
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
namespace App\Jobs\Invoice;
|
||||
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Jobs\Vendor\CreatePurchaseOrderPdf;
|
||||
use App\Models\PurchaseOrder;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
@ -52,6 +54,11 @@ class InjectSignature implements ShouldQueue
|
||||
$invitation->signature_base64 = $this->signature;
|
||||
$invitation->save();
|
||||
|
||||
CreateEntityPdf::dispatch($invitation);
|
||||
$this->entity->refresh()->service()->touchPdf(true);
|
||||
|
||||
// if($this->entity instanceof PurchaseOrder)
|
||||
// (new CreatePurchaseOrderPdf($invitation))->handle();
|
||||
// else
|
||||
// (new CreateEntityPdf($invitation))->handle();
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
unset($methods[$key]);
|
||||
|
||||
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $amount, $this->payment_hash))->build();
|
||||
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $amount, $this->payment_hash, $company_user->portalType()))->build();
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer($mail_obj);
|
||||
|
@ -95,7 +95,6 @@ class QuoteCheckExpired implements ShouldQueue
|
||||
private function queueExpiredQuoteNotification(Quote $quote)
|
||||
{
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new QuoteExpiredObject($quote, $quote->company))->build());
|
||||
$nmo->company = $quote->company;
|
||||
$nmo->settings = $quote->company->settings;
|
||||
|
||||
@ -107,6 +106,8 @@ class QuoteCheckExpired implements ShouldQueue
|
||||
if (! $user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nmo->mailable = new NinjaMailer((new QuoteExpiredObject($quote, $quote->company, $company_user->portalType()))->build());
|
||||
|
||||
/* Returns an array of notification methods */
|
||||
$methods = $this->findUserNotificationTypes($quote->invitations()->first(), $company_user, 'quote', ['all_notifications', 'quote_expired', 'quote_expired_all', 'quote_expired_user']);
|
||||
|
@ -100,10 +100,7 @@ class Import implements ShouldQueue
|
||||
use Uploadable;
|
||||
use SavesDocuments;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $file_path; //the file path - using a different JSON parser here.
|
||||
private string $file_path; //the file path - using a different JSON parser here.
|
||||
|
||||
/**
|
||||
* @var Company
|
||||
@ -202,7 +199,11 @@ class Import implements ShouldQueue
|
||||
nlog($this->company->id);
|
||||
|
||||
auth()->login($this->user, false);
|
||||
auth()->user()->setCompany($this->company);
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$user->setCompany($this->company);
|
||||
|
||||
$array = json_decode(file_get_contents($this->file_path), 1);
|
||||
$data = $array['data'];
|
||||
|
@ -11,26 +11,27 @@
|
||||
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Exceptions\ClientHostedMigrationException;
|
||||
use App\Exceptions\MigrationValidatorFailed;
|
||||
use App\Exceptions\NonExistingMigrationFile;
|
||||
use App\Exceptions\ProcessingMigrationArchiveFailed;
|
||||
use App\Exceptions\ResourceDependencyMissing;
|
||||
use App\Exceptions\ResourceNotAvailableForMigration;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\MigrationFailed;
|
||||
use App\Models\Company;
|
||||
use ZipArchive;
|
||||
use App\Models\User;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\MigrationFailed;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use ZipArchive;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Exceptions\MigrationValidatorFailed;
|
||||
use App\Exceptions\NonExistingMigrationFile;
|
||||
use App\Exceptions\ResourceDependencyMissing;
|
||||
use App\Exceptions\ClientHostedMigrationException;
|
||||
use App\Exceptions\ProcessingMigrationArchiveFailed;
|
||||
use App\Exceptions\ResourceNotAvailableForMigration;
|
||||
|
||||
class StartMigration implements ShouldQueue
|
||||
{
|
||||
@ -79,6 +80,8 @@ class StartMigration implements ShouldQueue
|
||||
{
|
||||
nlog('Inside Migration Job');
|
||||
|
||||
Cache::put("migration-{$this->company->company_key}", "started", 86400);
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
@ -124,6 +127,8 @@ class StartMigration implements ShouldQueue
|
||||
$this->company->update_products = $update_product_flag;
|
||||
$this->company->save();
|
||||
|
||||
Cache::put("migration-{$this->company->company_key}", "completed", 86400);
|
||||
|
||||
App::forgetInstance('translator');
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
@ -131,6 +136,8 @@ class StartMigration implements ShouldQueue
|
||||
$this->company->update_products = $update_product_flag;
|
||||
$this->company->save();
|
||||
|
||||
Cache::put("migration-{$this->company->company_key}", "failed", 86400);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
@ -147,6 +154,9 @@ class StartMigration implements ShouldQueue
|
||||
if (app()->environment() !== 'production') {
|
||||
info($e->getMessage());
|
||||
}
|
||||
|
||||
Storage::deleteDirectory(public_path("storage/migrations/{$filename}"));
|
||||
|
||||
}
|
||||
|
||||
//always make sure we unset the migration as running
|
||||
|
@ -45,6 +45,32 @@ class MultiDB
|
||||
|
||||
public static $dbs = ['db-ninja-01', 'db-ninja-02'];
|
||||
|
||||
private static $protected_domains = [
|
||||
'www',
|
||||
'app',
|
||||
'ninja',
|
||||
'sentry',
|
||||
'sentry2',
|
||||
'staging',
|
||||
'pdf',
|
||||
'demo',
|
||||
'docs',
|
||||
'client_domain',
|
||||
'custom_domain',
|
||||
'preview',
|
||||
'invoiceninja',
|
||||
'cname',
|
||||
'sandbox',
|
||||
'stage',
|
||||
'html',
|
||||
'lb',
|
||||
'shopify',
|
||||
'beta',
|
||||
'prometh',
|
||||
'license',
|
||||
'socket',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@ -55,10 +81,15 @@ class MultiDB
|
||||
|
||||
public static function checkDomainAvailable($subdomain) : bool
|
||||
{
|
||||
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
return Company::whereSubdomain($subdomain)->count() == 0;
|
||||
}
|
||||
|
||||
if (in_array($subdomain, self::$protected_domains)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$current_db = config('database.default');
|
||||
|
||||
foreach (self::$dbs as $db) {
|
||||
|
@ -71,21 +71,21 @@ class OAuth
|
||||
public static function providerToString(int $social_provider): string
|
||||
{
|
||||
switch ($social_provider) {
|
||||
case SOCIAL_GOOGLE:
|
||||
case self::SOCIAL_GOOGLE:
|
||||
return 'google';
|
||||
case SOCIAL_FACEBOOK:
|
||||
case self::SOCIAL_FACEBOOK:
|
||||
return 'facebook';
|
||||
case SOCIAL_GITHUB:
|
||||
case self::SOCIAL_GITHUB:
|
||||
return 'github';
|
||||
case SOCIAL_LINKEDIN:
|
||||
case self::SOCIAL_LINKEDIN:
|
||||
return 'linkedin';
|
||||
case SOCIAL_TWITTER:
|
||||
case self::SOCIAL_TWITTER:
|
||||
return 'twitter';
|
||||
case SOCIAL_BITBUCKET:
|
||||
case self::SOCIAL_BITBUCKET:
|
||||
return 'bitbucket';
|
||||
case SOCIAL_MICROSOFT:
|
||||
case self::SOCIAL_MICROSOFT:
|
||||
return 'microsoft';
|
||||
case SOCIAL_APPLE:
|
||||
case self::SOCIAL_APPLE:
|
||||
return 'apple';
|
||||
}
|
||||
}
|
||||
@ -94,21 +94,21 @@ class OAuth
|
||||
{
|
||||
switch ($social_provider) {
|
||||
case 'google':
|
||||
return SOCIAL_GOOGLE;
|
||||
return self::SOCIAL_GOOGLE;
|
||||
case 'facebook':
|
||||
return SOCIAL_FACEBOOK;
|
||||
return self::SOCIAL_FACEBOOK;
|
||||
case 'github':
|
||||
return SOCIAL_GITHUB;
|
||||
return self::SOCIAL_GITHUB;
|
||||
case 'linkedin':
|
||||
return SOCIAL_LINKEDIN;
|
||||
return self::SOCIAL_LINKEDIN;
|
||||
case 'twitter':
|
||||
return SOCIAL_TWITTER;
|
||||
return self::SOCIAL_TWITTER;
|
||||
case 'bitbucket':
|
||||
return SOCIAL_BITBUCKET;
|
||||
return self::SOCIAL_BITBUCKET;
|
||||
case 'microsoft':
|
||||
return SOCIAL_MICROSOFT;
|
||||
return self::SOCIAL_MICROSOFT;
|
||||
case 'apple':
|
||||
return SOCIAL_APPLE;
|
||||
return self::SOCIAL_APPLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,6 @@ class CreditCreatedNotification implements ShouldQueue
|
||||
{
|
||||
MultiDB::setDb($event->company->db);
|
||||
|
||||
// $first_notification_sent = true;
|
||||
|
||||
$credit = $event->credit;
|
||||
|
||||
/* We loop through each user and determine whether they need to be notified */
|
||||
@ -60,7 +58,7 @@ class CreditCreatedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($credit, 'credit'))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($credit, 'credit', $company_user->portalType()))->build());
|
||||
$nmo->company = $credit->company;
|
||||
$nmo->settings = $credit->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -56,7 +56,7 @@ class CreditEmailedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'credit', $event->template))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'credit', $event->template, $company_user->portalType()))->build());
|
||||
$nmo->company = $credit->company;
|
||||
$nmo->settings = $credit->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -24,7 +24,7 @@ class InvoiceCreatedNotification implements ShouldQueue
|
||||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 7;
|
||||
public $delay = 3;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@ -48,11 +48,11 @@ class InvoiceCreatedNotification implements ShouldQueue
|
||||
foreach ($event->company->company_users as $company_user) {
|
||||
/* The User */
|
||||
$user = $company_user->user;
|
||||
|
||||
|
||||
if (! $user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* This is only here to handle the alternate message channels - ie Slack */
|
||||
// $notification = new EntitySentNotification($event->invitation, 'invoice');
|
||||
|
||||
@ -64,7 +64,7 @@ class InvoiceCreatedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($invoice, 'invoice'))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($invoice, 'invoice', $company_user->portalType()))->build());
|
||||
$nmo->company = $invoice->company;
|
||||
$nmo->settings = $invoice->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -64,7 +64,7 @@ class InvoiceEmailedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'invoice', $event->template))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'invoice', $event->template, $company_user->portalType()))->build());
|
||||
$nmo->company = $invoice->company;
|
||||
$nmo->settings = $invoice->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -49,7 +49,7 @@ class InvoiceFailedEmailNotification
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityFailedSendObject($event->invitation->withoutRelations(), 'invoice', $event->template, $event->message))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityFailedSendObject($event->invitation->withoutRelations(), 'invoice', $event->template, $event->message, $company_user->portalType()))->build());
|
||||
$nmo->company = $invoice->company->withoutRelations();
|
||||
$nmo->settings = $invoice->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -70,7 +70,7 @@ class InvitationViewedListener implements ShouldQueue
|
||||
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityViewedObject($invitation, $entity_name))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityViewedObject($invitation, $entity_name, $company_user->portalType()))->build());
|
||||
$nmo->company = $invitation->company;
|
||||
$nmo->settings = $invitation->company->settings;
|
||||
|
||||
|
@ -76,7 +76,7 @@ class PaymentNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityPaidObject($payment))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityPaidObject($payment, $company_user->portalType()))->build());
|
||||
$nmo->company = $event->company;
|
||||
$nmo->settings = $event->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
@ -108,7 +108,7 @@ class PaymentNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityPaidObject($payment))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityPaidObject($payment, $company_user->portalType()))->build());
|
||||
$nmo->company = $event->company;
|
||||
$nmo->settings = $event->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
@ -161,11 +161,12 @@ class PaymentNotification implements ShouldQueue
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param string $url
|
||||
*/
|
||||
private function sendAnalytics($data)
|
||||
{
|
||||
$data = utf8_encode($data);
|
||||
private function sendAnalytics($url)
|
||||
{
|
||||
$data = mb_convert_encoding($url, 'UTF-8');
|
||||
// $data = utf8_encode($data);
|
||||
$curl = curl_init();
|
||||
|
||||
$opts = [
|
||||
|
@ -59,7 +59,7 @@ class PurchaseOrderAcceptedListener implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new PurchaseOrderAcceptedObject($purchase_order, $event->company))->build());
|
||||
$nmo->mailable = new NinjaMailer((new PurchaseOrderAcceptedObject($purchase_order, $event->company, $company_user->portalType()))->build());
|
||||
$nmo->company = $event->company;
|
||||
$nmo->settings = $event->company->settings;
|
||||
|
||||
|
@ -45,7 +45,6 @@ class PurchaseOrderCreatedListener implements ShouldQueue
|
||||
|
||||
$purchase_order = $event->purchase_order;
|
||||
|
||||
|
||||
/* We loop through each user and determine whether they need to be notified */
|
||||
foreach ($event->company->company_users as $company_user) {
|
||||
/* The User */
|
||||
@ -66,7 +65,7 @@ class PurchaseOrderCreatedListener implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($purchase_order, 'purchase_order'))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($purchase_order, 'purchase_order', $company_user->portalType()))->build());
|
||||
$nmo->company = $purchase_order->company;
|
||||
$nmo->settings = $purchase_order->company->settings;
|
||||
|
||||
|
@ -62,7 +62,7 @@ class PurchaseOrderEmailedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'purchase_order', 'purchase_order'))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'purchase_order', 'purchase_order', $company_user->portalType()))->build());
|
||||
$nmo->company = $purchase_order->company;
|
||||
$nmo->settings = $purchase_order->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -61,7 +61,7 @@ class QuoteApprovedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new QuoteApprovedObject($quote, $event->company))->build());
|
||||
$nmo->mailable = new NinjaMailer((new QuoteApprovedObject($quote, $event->company, $company_user->portalType()))->build());
|
||||
$nmo->company = $quote->company;
|
||||
$nmo->settings = $quote->company->settings;
|
||||
|
||||
|
@ -54,6 +54,12 @@ class QuoteCreatedNotification implements ShouldQueue
|
||||
continue;
|
||||
}
|
||||
|
||||
$use_react_link = false;
|
||||
|
||||
if(isset($company_user->react_settings->react_notification_link) && $company_user->react_settings->react_notification_link) {
|
||||
$use_react_link = true;
|
||||
}
|
||||
|
||||
/* This is only here to handle the alternate message channels - ie Slack */
|
||||
// $notification = new EntitySentNotification($event->invitation, 'quote');
|
||||
|
||||
@ -65,7 +71,7 @@ class QuoteCreatedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($quote, 'quote'))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntityCreatedObject($quote, 'quote', $company_user->portalType()))->build());
|
||||
$nmo->company = $quote->company;
|
||||
$nmo->settings = $quote->company->settings;
|
||||
|
||||
|
@ -54,7 +54,7 @@ class QuoteEmailedNotification implements ShouldQueue
|
||||
unset($methods[$key]);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'quote', $event->template))->build());
|
||||
$nmo->mailable = new NinjaMailer((new EntitySentObject($event->invitation, 'quote', $event->template, $company_user->portalType()))->build());
|
||||
$nmo->company = $quote->company;
|
||||
$nmo->settings = $quote->company->settings;
|
||||
$nmo->to_user = $user;
|
||||
|
@ -11,19 +11,16 @@
|
||||
|
||||
namespace App\Mail\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
||||
class AccountCreatedObject
|
||||
{
|
||||
public $user;
|
||||
|
||||
public $company;
|
||||
|
||||
public function __construct($user, $company)
|
||||
|
||||
public function __construct(public User $user, public Company $company)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
public function build()
|
||||
|
@ -17,7 +17,7 @@ use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use stdClass;
|
||||
|
||||
//@deprecated
|
||||
class AutoBillingFailureObject
|
||||
{
|
||||
use MakesHash;
|
||||
|
@ -33,10 +33,13 @@ class EntityCreatedObject
|
||||
|
||||
private $template_body;
|
||||
|
||||
public function __construct($entity, $entity_type)
|
||||
protected bool $use_react_link;
|
||||
|
||||
public function __construct($entity, $entity_type, $use_react_link = false)
|
||||
{
|
||||
$this->entity_type = $entity_type;
|
||||
$this->entity = $entity;
|
||||
$this->use_react_link = $use_react_link;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,7 +84,7 @@ class EntityCreatedObject
|
||||
'purchase_order' => $this->entity->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->entity->invitations()->first()->getAdminLink(),
|
||||
'url' => $this->entity->invitations()->first()->getAdminLink($this->use_react_link),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $this->company->settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
@ -165,7 +168,7 @@ class EntityCreatedObject
|
||||
return [
|
||||
'title' => $this->getSubject(),
|
||||
'message' => $this->getMessage(),
|
||||
'url' => $this->entity->invitations()->first()->getAdminLink(),
|
||||
'url' => $this->entity->invitations()->first()->getAdminLink($this->use_react_link),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -39,7 +39,9 @@ class EntityFailedSendObject
|
||||
|
||||
private $message;
|
||||
|
||||
public function __construct($invitation, $entity_type, $template, $message)
|
||||
protected $use_react_url;
|
||||
|
||||
public function __construct($invitation, $entity_type, $template, $message, $use_react_url)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
$this->entity_type = $entity_type;
|
||||
@ -48,6 +50,7 @@ class EntityFailedSendObject
|
||||
$this->company = $invitation->company;
|
||||
$this->template = $template;
|
||||
$this->message = $message;
|
||||
$this->use_react_url = $use_react_url;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -149,7 +152,7 @@ class EntityFailedSendObject
|
||||
'contact' => $this->contact->present()->name(),
|
||||
]
|
||||
),
|
||||
'url' => $this->invitation->getAdminLink(),
|
||||
'url' => $this->invitation->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -30,7 +30,7 @@ class EntityPaidObject
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct(public Payment $payment)
|
||||
public function __construct(public Payment $payment, protected bool $use_react_url)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
$this->company = $payment->company;
|
||||
@ -98,7 +98,7 @@ class EntityPaidObject
|
||||
'invoice' => $invoice_texts,
|
||||
]
|
||||
),
|
||||
'url' => config('ninja.app_url'),
|
||||
'url' => $this->payment->portalUrl($this->use_react_url),
|
||||
'button' => ctrans('texts.view_payment'),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
@ -117,4 +117,5 @@ class EntityPaidObject
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,9 @@ class EntitySentObject
|
||||
|
||||
private $template_body;
|
||||
|
||||
public function __construct($invitation, $entity_type, $template)
|
||||
protected $use_react_url;
|
||||
|
||||
public function __construct($invitation, $entity_type, $template, $use_react_url)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
$this->entity_type = $entity_type;
|
||||
@ -44,6 +46,7 @@ class EntitySentObject
|
||||
$this->contact = $invitation->contact;
|
||||
$this->company = $invitation->company;
|
||||
$this->template = $template;
|
||||
$this->use_react_url = $use_react_url;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -78,7 +81,7 @@ class EntitySentObject
|
||||
'purchase_order' => $this->entity->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->invitation->getAdminLink(),
|
||||
'url' => $this->invitation->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $this->company->settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
@ -185,7 +188,7 @@ class EntitySentObject
|
||||
return [
|
||||
'title' => $this->getSubject(),
|
||||
'message' => $this->getMessage(),
|
||||
'url' => $this->invitation->getAdminLink(),
|
||||
'url' => $this->invitation->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -30,13 +30,16 @@ class EntityViewedObject
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct($invitation, $entity_type)
|
||||
protected $use_react_url;
|
||||
|
||||
public function __construct($invitation, $entity_type, $use_react_url)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
$this->entity_type = $entity_type;
|
||||
$this->entity = $invitation->{$entity_type};
|
||||
$this->contact = $invitation->contact;
|
||||
$this->company = $invitation->company;
|
||||
$this->use_react_url = $use_react_url;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -104,7 +107,7 @@ class EntityViewedObject
|
||||
'invoice' => $this->entity->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->invitation->getAdminLink(),
|
||||
'url' => $this->invitation->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
namespace App\Mail\Admin;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Product;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Support\Facades\App;
|
||||
@ -20,19 +19,9 @@ use stdClass;
|
||||
|
||||
class InventoryNotificationObject
|
||||
{
|
||||
public Product $product;
|
||||
|
||||
public Company $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public string $notification_level;
|
||||
|
||||
public function __construct(Product $product, string $notification_level)
|
||||
|
||||
public function __construct(protected Product $product, public string $notification_level, protected bool $use_react_url)
|
||||
{
|
||||
$this->product = $product;
|
||||
$this->company = $product->company;
|
||||
$this->settings = $this->company->settings;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -41,16 +30,16 @@ class InventoryNotificationObject
|
||||
/* Init a new copy of the translator*/
|
||||
$t = app('translator');
|
||||
/* Set the locale*/
|
||||
App::setLocale($this->company->getLocale());
|
||||
App::setLocale($this->product->company->getLocale());
|
||||
/* Set customized translations _NOW_ */
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
$t->replace(Ninja::transformTranslations($this->product->company->settings));
|
||||
|
||||
$mail_obj = new stdClass;
|
||||
$mail_obj->amount = $this->getAmount();
|
||||
$mail_obj->subject = $this->getSubject();
|
||||
$mail_obj->data = $this->getData();
|
||||
$mail_obj->markdown = 'email.admin.generic';
|
||||
$mail_obj->tag = $this->company->company_key;
|
||||
$mail_obj->tag = $this->product->company->company_key;
|
||||
|
||||
return $mail_obj;
|
||||
}
|
||||
@ -79,12 +68,12 @@ class InventoryNotificationObject
|
||||
'product' => $this->product->product_key.': '.$this->product->notes,
|
||||
]
|
||||
),
|
||||
'url' => config('ninja.app_url'),
|
||||
'button' => ctrans('texts.login'),
|
||||
'signature' => $this->settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
'settings' => $this->settings,
|
||||
'whitelabel' => $this->company->account->isPaid() ? true : false,
|
||||
'url' => $this->product->portalUrl($this->use_react_url),
|
||||
'button' => $this->use_react_url ? ctrans('texts.product_library') : ctrans('ninja.app_url'),
|
||||
'signature' => $this->product->company->settings->email_signature,
|
||||
'logo' => $this->product->company->present()->logo(),
|
||||
'settings' => $this->product->company->settings,
|
||||
'whitelabel' => $this->product->company->account->isPaid() ? true : false,
|
||||
];
|
||||
|
||||
return $data;
|
||||
|
@ -24,17 +24,6 @@ class PaymentFailureObject
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public Client $client;
|
||||
|
||||
public string $error;
|
||||
|
||||
public Company $company;
|
||||
|
||||
public $amount;
|
||||
|
||||
public ?PaymentHash $payment_hash;
|
||||
// private $invoices;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
@ -43,19 +32,8 @@ class PaymentFailureObject
|
||||
* @param $company
|
||||
* @param $amount
|
||||
*/
|
||||
public function __construct(Client $client, string $error, Company $company, $amount, ?PaymentHash $payment_hash)
|
||||
public function __construct(public Client $client, public string $error, public Company $company, public float $amount, public ?PaymentHash $payment_hash, protected bool $use_react_url)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
$this->error = $error;
|
||||
|
||||
$this->company = $company;
|
||||
|
||||
$this->amount = $amount;
|
||||
|
||||
$this->company = $company;
|
||||
|
||||
$this->payment_hash = $payment_hash;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -115,8 +93,8 @@ class PaymentFailureObject
|
||||
'logo' => $this->company->present()->logo(),
|
||||
'settings' => $this->client->getMergedSettings(),
|
||||
'whitelabel' => $this->company->account->isPaid() ? true : false,
|
||||
'url' => config('ninja.app_url'),
|
||||
'button' => ctrans('texts.login'),
|
||||
'url' => $this->client->portalUrl($this->use_react_url),
|
||||
'button' => $this->use_react_url ? ctrans('texts.view_client') : ctrans('texts.login'),
|
||||
'additional_info' => $this->error,
|
||||
];
|
||||
|
||||
|
@ -21,16 +21,9 @@ use stdClass;
|
||||
|
||||
class PurchaseOrderAcceptedObject
|
||||
{
|
||||
public $purchase_order;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct(PurchaseOrder $purchase_order, Company $company)
|
||||
public function __construct(public PurchaseOrder $purchase_order, public Company $company, protected bool $use_react_url)
|
||||
{
|
||||
$this->purchase_order = $purchase_order;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -90,7 +83,7 @@ class PurchaseOrderAcceptedObject
|
||||
'purchase_order' => $this->purchase_order->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->purchase_order->invitations->first()->getAdminLink(),
|
||||
'url' => $this->purchase_order->invitations->first()->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans('texts.view_purchase_order'),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -21,16 +21,9 @@ use stdClass;
|
||||
|
||||
class QuoteApprovedObject
|
||||
{
|
||||
public $quote;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct(Quote $quote, Company $company)
|
||||
public function __construct(public Quote $quote, public Company $company, public bool $use_react_url)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -90,7 +83,7 @@ class QuoteApprovedObject
|
||||
'invoice' => $this->quote->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->quote->invitations->first()->getAdminLink(),
|
||||
'url' => $this->quote->invitations->first()->getAdminLink($this->use_react_url),
|
||||
'button' => ctrans('texts.view_quote'),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
|
@ -21,16 +21,9 @@ use stdClass;
|
||||
|
||||
class QuoteExpiredObject
|
||||
{
|
||||
public $quote;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct(Quote $quote, Company $company)
|
||||
public function __construct(public Quote $quote, public Company $company, public bool $use_react_url)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -90,8 +83,8 @@ class QuoteExpiredObject
|
||||
'invoice' => $this->quote->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->quote->invitations->first()->getAdminLink(),
|
||||
'button' => ctrans('texts.view_quote'),
|
||||
'url' => $this->quote->invitations->first()->getAdminLink($this->use_react_url),
|
||||
'button' => $this->use_react_url ? ctrans('texts.view_quote') : ctrans('texts.login'),
|
||||
'signature' => $settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
'settings' => $settings,
|
||||
|
@ -11,15 +11,16 @@
|
||||
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use App\Models\Account;
|
||||
use App\Utils\Helpers;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Helpers;
|
||||
use App\Models\Account;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
|
||||
class PaymentEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -105,6 +106,18 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->client->getSetting('enable_e_invoice'))
|
||||
{
|
||||
|
||||
$e_invoice_filepath = $invoice->service()->getEInvoice($this->contact);
|
||||
|
||||
if(Storage::disk(config('filesystems.default'))->exists($e_invoice_filepath)) {
|
||||
$this->setAttachments([['path' => Storage::disk(config('filesystems.default'))->path($e_invoice_filepath), 'name' => $invoice->getFileName("xml"), 'mime' => null]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user