mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-30 22:14:33 -04:00
Merge pull request #9191 from turbo124/v5-develop
Prevent reminder fees being taxes in DE region
This commit is contained in:
commit
f325370986
@ -890,6 +890,40 @@ class CheckData extends Command
|
|||||||
|
|
||||||
$this->logMessage("Fixing country for # {$client->id}");
|
$this->logMessage("Fixing country for # {$client->id}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Client::query()->whereNull("settings->currency_id")->cursor()->each(function ($client){
|
||||||
|
$settings = $client->settings;
|
||||||
|
$settings->currency_id = (string)$client->company->settings->currency_id;
|
||||||
|
$client->settings = $settings;
|
||||||
|
$client->saveQuietly();
|
||||||
|
|
||||||
|
$this->logMessage("Fixing currency_id for # {$client->id}");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Payment::withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment){
|
||||||
|
$payment->exchange_rate = 1;
|
||||||
|
$payment->saveQuietly();
|
||||||
|
|
||||||
|
$this->logMessage("Fixing exchange rate for # {$payment->id}");
|
||||||
|
});
|
||||||
|
|
||||||
|
Payment::withTrashed()
|
||||||
|
->whereHas("client", function ($query) {
|
||||||
|
$query->whereColumn("settings->currency_id", "!=", "payments.currency_id");
|
||||||
|
})
|
||||||
|
->cursor()
|
||||||
|
->each(function ($p) {
|
||||||
|
$p->currency_id = $p->client->settings->currency_id;
|
||||||
|
$p->saveQuietly();
|
||||||
|
|
||||||
|
|
||||||
|
$this->logMessage("Fixing currency for # {$p->id}");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +319,7 @@ class BaseRule implements RuleInterface
|
|||||||
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item),
|
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item),
|
||||||
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item),
|
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item),
|
||||||
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item),
|
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item),
|
||||||
|
Product::PRODUCT_TYPE_ZERO_RATED => $this->zeroRated($item),
|
||||||
default => $this->defaultForeign(),
|
default => $this->defaultForeign(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -327,6 +328,14 @@ class BaseRule implements RuleInterface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function zeroRated($item): self
|
||||||
|
{
|
||||||
|
$this->tax_rate1 = 0;
|
||||||
|
$this->tax_name1 = ctrans('texts.zero_rated');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function taxByType(mixed $type): self
|
public function taxByType(mixed $type): self
|
||||||
{
|
{
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\DataMapper\Tax\DE;
|
namespace App\DataMapper\Tax\DE;
|
||||||
|
|
||||||
|
use App\DataMapper\InvoiceItem;
|
||||||
use App\DataMapper\Tax\BaseRule;
|
use App\DataMapper\Tax\BaseRule;
|
||||||
use App\DataMapper\Tax\RuleInterface;
|
use App\DataMapper\Tax\RuleInterface;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
@ -63,7 +64,7 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
public function taxByType($item): self
|
public function taxByType($item): self
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id')) {
|
if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id') || (isset($item->type_id) && $item->type_id == '5')) {
|
||||||
return $this->taxExempt($item);
|
return $this->taxExempt($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +399,7 @@ class QuoteController extends BaseController
|
|||||||
|
|
||||||
$quote->service()
|
$quote->service()
|
||||||
->triggeredActions($request);
|
->triggeredActions($request);
|
||||||
// ->deletePdf();
|
|
||||||
|
|
||||||
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
return $this->itemResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
|
@ -51,10 +51,6 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
|
|
||||||
public $deleteWhenMissingModels = true;
|
public $deleteWhenMissingModels = true;
|
||||||
|
|
||||||
public $nmo;
|
|
||||||
|
|
||||||
public $override;
|
|
||||||
|
|
||||||
/** @var null|\App\Models\Company $company **/
|
/** @var null|\App\Models\Company $company **/
|
||||||
public ?Company $company;
|
public ?Company $company;
|
||||||
|
|
||||||
@ -67,11 +63,8 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
protected $client_mailgun_domain = false;
|
protected $client_mailgun_domain = false;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(NinjaMailerObject $nmo, bool $override = false)
|
public function __construct(public ?NinjaMailerObject $nmo, public bool $override = false)
|
||||||
{
|
{
|
||||||
$this->nmo = $nmo;
|
|
||||||
|
|
||||||
$this->override = $override;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function backoff()
|
public function backoff()
|
||||||
@ -106,7 +99,10 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name);
|
$this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name);
|
||||||
} else {
|
}elseif(isset($this->nmo->invitation->user)){
|
||||||
|
$this->nmo->mailable->replyTo($this->nmo->invitation->user->email, $this->nmo->invitation->user->present()->name());
|
||||||
|
}
|
||||||
|
else {
|
||||||
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ namespace App\Jobs\Mail;
|
|||||||
*/
|
*/
|
||||||
class NinjaMailerObject
|
class NinjaMailerObject
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* @var Illuminate\Mail\Mailable */
|
||||||
public $mailable;
|
public $mailable;
|
||||||
|
|
||||||
/* @var Company $company */
|
/* @var Company $company */
|
||||||
@ -32,7 +34,7 @@ class NinjaMailerObject
|
|||||||
/* Variable for cascading notifications */
|
/* Variable for cascading notifications */
|
||||||
public $entity_string = false;
|
public $entity_string = false;
|
||||||
|
|
||||||
/* @var bool | App\Models\InvoiceInvitation | App\Models\QuoteInvitation | App\Models\CreditInvitation | App\Models\RecurringInvoiceInvitation | App\Models\PurchaseOrderInvitation $invitation*/
|
/* @var App\Models\InvoiceInvitation | App\Models\QuoteInvitation | App\Models\CreditInvitation | App\Models\RecurringInvoiceInvitation | App\Models\PurchaseOrderInvitation | \bool $invitation*/
|
||||||
public $invitation = false;
|
public $invitation = false;
|
||||||
|
|
||||||
public $template = false;
|
public $template = false;
|
||||||
|
@ -69,8 +69,11 @@ class UpdateOrCreateProduct implements ShouldQueue
|
|||||||
* we do NOT update the product details this short block we
|
* we do NOT update the product details this short block we
|
||||||
* check for the presence of a task_id and/or expense_id
|
* check for the presence of a task_id and/or expense_id
|
||||||
*/
|
*/
|
||||||
$expense_count = count(array_column((array) $this->products, 'expense_id'));
|
// $expense_count = count(array_column((array) $this->products, 'expense_id'));
|
||||||
$task_count = count(array_column((array) $this->products, 'task_id'));
|
// $task_count = count(array_column((array) $this->products, 'task_id'));
|
||||||
|
|
||||||
|
$task_count = implode("", array_column((array) $this->products, 'task_id'));
|
||||||
|
$expense_count = implode("", array_column((array) $this->products, 'expense_id'));
|
||||||
|
|
||||||
if ($task_count >= 1 || $expense_count >= 1) {
|
if ($task_count >= 1 || $expense_count >= 1) {
|
||||||
return;
|
return;
|
||||||
|
@ -44,7 +44,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property string|null $po_number
|
* @property string|null $po_number
|
||||||
* @property string|null $date
|
* @property string|null $date
|
||||||
* @property string|null $last_sent_date
|
* @property string|null $last_sent_date
|
||||||
* @property string|null $due_date
|
* @property string|null|Carbon $due_date
|
||||||
* @property string|null $next_send_date
|
* @property string|null $next_send_date
|
||||||
* @property bool $is_deleted
|
* @property bool $is_deleted
|
||||||
* @property object|null $line_items
|
* @property object|null $line_items
|
||||||
@ -164,7 +164,7 @@ class Quote extends BaseModel
|
|||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
// 'date' => 'date:Y-m-d',
|
// 'date' => 'date:Y-m-d',
|
||||||
// 'due_date' => 'date:Y-m-d',
|
'due_date' => 'date:Y-m-d',
|
||||||
// 'partial_due_date' => 'date:Y-m-d',
|
// 'partial_due_date' => 'date:Y-m-d',
|
||||||
'line_items' => 'object',
|
'line_items' => 'object',
|
||||||
'backup' => 'object',
|
'backup' => 'object',
|
||||||
@ -197,7 +197,7 @@ class Quote extends BaseModel
|
|||||||
|
|
||||||
public function getDueDateAttribute($value)
|
public function getDueDateAttribute($value)
|
||||||
{
|
{
|
||||||
return $this->dateMutator($value);
|
return $value ? $this->dateMutator($value) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPartialDueDateAttribute($value)
|
public function getPartialDueDateAttribute($value)
|
||||||
|
@ -437,7 +437,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
|
|
||||||
if($shipping = $this->getShippingAddress()) {
|
if($shipping = $this->getShippingAddress()) {
|
||||||
$order['purchase_units'][0] = $shipping;
|
$order['purchase_units'][0]["shipping"] = $shipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
||||||
@ -465,8 +465,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
{
|
{
|
||||||
return $this->company_gateway->require_shipping_address ?
|
return $this->company_gateway->require_shipping_address ?
|
||||||
[
|
[
|
||||||
"shipping" => [
|
"address" =>
|
||||||
"address" =>
|
|
||||||
[
|
[
|
||||||
"address_line_1" => $this->client->shipping_address1,
|
"address_line_1" => $this->client->shipping_address1,
|
||||||
"address_line_2" => $this->client->shipping_address2,
|
"address_line_2" => $this->client->shipping_address2,
|
||||||
@ -475,8 +474,8 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
"postal_code" => $this->client->shipping_postal_code,
|
"postal_code" => $this->client->shipping_postal_code,
|
||||||
"country_code" => $this->client->present()->shipping_country_code(),
|
"country_code" => $this->client->present()->shipping_country_code(),
|
||||||
],
|
],
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -208,9 +208,22 @@ class EmailDefaults
|
|||||||
*/
|
*/
|
||||||
private function setReplyTo(): self
|
private function setReplyTo(): self
|
||||||
{
|
{
|
||||||
$reply_to_email = str_contains($this->email->email_object->settings->reply_to_email, "@") ? $this->email->email_object->settings->reply_to_email : $this->email->company->owner()->email;
|
$reply_to_email = $this->email->company->owner()->email;
|
||||||
|
$reply_to_name = $this->email->company->owner()->present()->name();
|
||||||
|
|
||||||
$reply_to_name = strlen($this->email->email_object->settings->reply_to_name) > 3 ? $this->email->email_object->settings->reply_to_name : $this->email->company->owner()->present()->name();
|
if(str_contains($this->email->email_object->settings->reply_to_email, "@")){
|
||||||
|
$reply_to_email = $this->email->email_object->settings->reply_to_email;
|
||||||
|
}
|
||||||
|
elseif(isset($this->email->email_object->invitation->user)) {
|
||||||
|
$reply_to_email = $this->email->email_object->invitation->user->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen($this->email->email_object->settings->reply_to_name) > 3) {
|
||||||
|
$reply_to_name =$this->email->email_object->settings->reply_to_name;
|
||||||
|
}
|
||||||
|
elseif(isset($this->email->email_object->invitation->user)) {
|
||||||
|
$reply_to_name = $this->email->email_object->invitation->user->present()->name();
|
||||||
|
}
|
||||||
|
|
||||||
$this->email->email_object->reply_to = array_merge($this->email->email_object->reply_to, [new Address($reply_to_email, $reply_to_name)]);
|
$this->email->email_object->reply_to = array_merge($this->email->email_object->reply_to, [new Address($reply_to_email, $reply_to_name)]);
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ class MarkSent
|
|||||||
->service()
|
->service()
|
||||||
->setStatus(Quote::STATUS_SENT)
|
->setStatus(Quote::STATUS_SENT)
|
||||||
->applyNumber()
|
->applyNumber()
|
||||||
// ->deletePdf()
|
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
event(new QuoteWasMarkedSent($this->quote, $this->quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new QuoteWasMarkedSent($this->quote, $this->quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
@ -28,20 +28,22 @@ return new class extends Migration
|
|||||||
|
|
||||||
$line_items = $invoice->line_items;
|
$line_items = $invoice->line_items;
|
||||||
|
|
||||||
foreach ($line_items as $key => $item)
|
if(is_array($line_items))
|
||||||
{
|
{
|
||||||
|
foreach ($line_items as $key => $item)
|
||||||
if($product = Product::where('company_id', $invoice->company_id)->where('product_key', $item->product_key)->where('cost', '>', 0)->first())
|
|
||||||
{
|
{
|
||||||
if((property_exists($item, 'product_cost') && $item->product_cost == 0) || !property_exists($item, 'product_cost'))
|
|
||||||
$line_items[$key]->product_cost = (float)$product->cost;
|
if($product = Product::where('company_id', $invoice->company_id)->where('product_key', $item->product_key)->where('cost', '>', 0)->first())
|
||||||
|
{
|
||||||
|
if((property_exists($item, 'product_cost') && $item->product_cost == 0) || !property_exists($item, 'product_cost'))
|
||||||
|
$line_items[$key]->product_cost = (float)$product->cost;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$invoice->line_items = $line_items;
|
||||||
|
$invoice->saveQuietly();
|
||||||
}
|
}
|
||||||
|
|
||||||
$invoice->line_items = $line_items;
|
|
||||||
$invoice->saveQuietly();
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user