diff --git a/VERSION.txt b/VERSION.txt index 17799edf2630..f8f87624c1bd 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.3.76 \ No newline at end of file +5.3.77 \ No newline at end of file diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php index 5b6f29958042..4a31ff867cad 100644 --- a/app/DataMapper/EmailTemplateDefaults.php +++ b/app/DataMapper/EmailTemplateDefaults.php @@ -180,7 +180,7 @@ class EmailTemplateDefaults public static function emailReminder1Subject() { - return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']); + return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); } public static function emailReminder1Template() @@ -190,7 +190,7 @@ class EmailTemplateDefaults public static function emailReminder2Subject() { - return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']); + return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); } public static function emailReminder2Template() @@ -200,7 +200,7 @@ class EmailTemplateDefaults public static function emailReminder3Subject() { - return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']); + return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); } public static function emailReminder3Template() @@ -210,7 +210,7 @@ class EmailTemplateDefaults public static function emailReminderEndlessSubject() { - return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']); + return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); } public static function emailReminderEndlessTemplate() diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 0e0b70570af3..3e81d97c8ab1 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -124,7 +124,7 @@ class Handler extends ExceptionHandler } }); - if ($this->validException($exception)) { + if ($this->validException($exception) && auth()->guard('contact')->user()->company->account->report_errors) { app('sentry')->captureException($exception); } } diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 6d5196d536c3..67973e1bf0d0 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -623,8 +623,8 @@ class BaseController extends Controller $query->with($includes); // 10-01-2022 need to ensure we snake case properly here to ensure permissions work as expected - // if (auth()->user() && ! auth()->user()->hasPermission('view_'.lcfirst(class_basename($this->entity_type)))) { - if (auth()->user() && ! auth()->user()->hasPermission('view_'.lcfirst(class_basename(Str::snake($this->entity_type))))) { + // 28-03-2022 this is definitely correct here, do not append _ to the view, it resolved correctly when snake cased + if (auth()->user() && ! auth()->user()->hasPermission('view'.lcfirst(class_basename(Str::snake($this->entity_type))))) { $query->where('user_id', '=', auth()->user()->id); } diff --git a/app/Http/Controllers/ClientPortal/NinjaPlanController.php b/app/Http/Controllers/ClientPortal/NinjaPlanController.php index cfaf0bdb2dd7..2c452328b891 100644 --- a/app/Http/Controllers/ClientPortal/NinjaPlanController.php +++ b/app/Http/Controllers/ClientPortal/NinjaPlanController.php @@ -198,7 +198,7 @@ class NinjaPlanController extends Controller if($account) { //offer the option to have a free trial - if(!$account->trial_started) + if(!$account->trial_started && !$account->plan) return $this->trial(); if(Carbon::parse($account->plan_expires)->lt(now())){ diff --git a/app/Http/Controllers/SelfUpdateController.php b/app/Http/Controllers/SelfUpdateController.php index b8b7bdc89eba..ead8e65e861c 100644 --- a/app/Http/Controllers/SelfUpdateController.php +++ b/app/Http/Controllers/SelfUpdateController.php @@ -100,9 +100,10 @@ class SelfUpdateController extends BaseController $this->testWritable(); - $contents = file_get_contents($this->getDownloadUrl()); + copy($this->getDownloadUrl(), storage_path('app/invoiceninja.zip')); - Storage::disk('local')->put('invoiceninja.zip', $contents); + // $contents = file_get_contents($this->getDownloadUrl()); + // Storage::disk('local')->put('invoiceninja.zip', $contents); $file = Storage::disk('local')->path('invoiceninja.zip'); diff --git a/app/Http/Middleware/QueryLogging.php b/app/Http/Middleware/QueryLogging.php index 105df50ec9ba..94ba71086a22 100644 --- a/app/Http/Middleware/QueryLogging.php +++ b/app/Http/Middleware/QueryLogging.php @@ -42,6 +42,7 @@ class QueryLogging $timeStart = microtime(true); DB::enableQueryLog(); + $response = $next($request); // hide requests made by debugbar if (strstr($request->url(), '_debugbar') === false) { @@ -71,7 +72,6 @@ class QueryLogging ->queue(); } - - return $next($request); + return $response; } } diff --git a/app/Http/Requests/ClientPortal/PaymentMethod/CreatePaymentMethodRequest.php b/app/Http/Requests/ClientPortal/PaymentMethod/CreatePaymentMethodRequest.php index dbf905f5f868..b3da2929399f 100644 --- a/app/Http/Requests/ClientPortal/PaymentMethod/CreatePaymentMethodRequest.php +++ b/app/Http/Requests/ClientPortal/PaymentMethod/CreatePaymentMethodRequest.php @@ -18,7 +18,7 @@ class CreatePaymentMethodRequest extends FormRequest public function authorize(): bool { /** @var Client $client */ - $client = auth()->('guard')->user()->client; + $client = auth()->guard('contact')->user()->client; $available_methods = []; diff --git a/app/Models/RecurringInvoice.php b/app/Models/RecurringInvoice.php index be15ce093b97..b600c8c65b4f 100644 --- a/app/Models/RecurringInvoice.php +++ b/app/Models/RecurringInvoice.php @@ -383,8 +383,11 @@ class RecurringInvoice extends BaseModel case self::FREQUENCY_TWO_YEARS: return ctrans('texts.freq_two_years'); break; + case self::FREQUENCY_THREE_YEARS: + return ctrans('texts.freq_three_years'); + break; default: - // code... + return ''; break; } } diff --git a/app/Observers/QuoteObserver.php b/app/Observers/QuoteObserver.php index 6e32b7f4e234..49fbaf8dc689 100644 --- a/app/Observers/QuoteObserver.php +++ b/app/Observers/QuoteObserver.php @@ -33,7 +33,7 @@ class QuoteObserver if ($subscriptions) { $quote->load('client'); - WebhookHandler::dispatch(Webhook::EVENT_CREATE_QUOTE, $quote, $quote->company); + WebhookHandler::dispatch(Webhook::EVENT_CREATE_QUOTE, $quote, $quote->company, 'client'); } } @@ -53,7 +53,7 @@ class QuoteObserver if ($subscriptions) { $quote->load('client'); - WebhookHandler::dispatch(Webhook::EVENT_UPDATE_QUOTE, $quote, $quote->company); + WebhookHandler::dispatch(Webhook::EVENT_UPDATE_QUOTE, $quote, $quote->company, 'client'); } } @@ -72,7 +72,7 @@ class QuoteObserver if ($subscriptions) { $quote->load('client'); - WebhookHandler::dispatch(Webhook::EVENT_DELETE_QUOTE, $quote, $quote->company); + WebhookHandler::dispatch(Webhook::EVENT_DELETE_QUOTE, $quote, $quote->company, 'client'); } } diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 70b4308027c7..36f730224711 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -322,8 +322,6 @@ class BaseDriver extends AbstractPaymentDriver if (collect($invoice->line_items)->contains('type_id', '3')) { $invoice->service()->toggleFeesPaid()->save(); - // $invoice->client->service()->updateBalance($fee_total)->save(); - // $invoice->ledger()->updateInvoiceBalance($fee_total, "Gateway fee adjustment for invoice {$invoice->number}"); } $transaction = [ diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php index b6440543eeb6..2f2152429f4f 100644 --- a/app/Services/Client/ClientService.php +++ b/app/Services/Client/ClientService.php @@ -28,21 +28,21 @@ class ClientService public function updateBalance(float $amount) { - $this->client->increment('balance', $amount); + $this->client->balance += $amount; return $this; } public function updatePaidToDate(float $amount) { - $this->client->increment('paid_to_date', $amount); + $this->client->paid_to_date += $amount; return $this; } public function adjustCreditBalance(float $amount) { - $this->client->increment('credit_balance', $amount); + $this->client->credit_balance += $amount; return $this; } diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 600684c4b403..ea7cec68ee58 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -167,25 +167,22 @@ class CreditService public function adjustBalance($adjustment) { - // $this->credit->balance += $adjustment; - $this->credit->increment('balance', $adjustment); - + $this->credit->balance += $adjustment; + return $this; } public function updatePaidToDate($adjustment) { - // $this->credit->paid_to_date += $adjustment; - $this->credit->increment('paid_to_date', $adjustment); - + $this->credit->paid_to_date += $adjustment; + return $this; } public function updateBalance($adjustment) { - // $this->credit->balance -= $adjustment; - $this->credit->decrement('balance', $adjustment); - + $this->credit->balance -= $adjustment; + return $this; } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 59366cb5d86a..555432e87d49 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -403,8 +403,7 @@ class InvoiceService /*Update the partial amount of a invoice*/ public function updatePartial($amount) { - // $this->invoice->partial += $amount; - $this->invoice->increment('partial', $amount); + $this->invoice->partial += $amount; return $this; } @@ -535,7 +534,7 @@ class InvoiceService /* Throws: Payment amount xxx does not match invoice totals. */ if ($this->invoice->trashed()) - return; + return $this; $this->invoice->delete(); diff --git a/app/Services/Payment/UpdateInvoicePayment.php b/app/Services/Payment/UpdateInvoicePayment.php index 5054c9b87a3e..64c2b2b5233d 100644 --- a/app/Services/Payment/UpdateInvoicePayment.php +++ b/app/Services/Payment/UpdateInvoicePayment.php @@ -40,19 +40,20 @@ class UpdateInvoicePayment $paid_invoices = $this->payment_hash->invoices(); $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($paid_invoices, 'invoice_id')))->withTrashed()->get(); + + $client = $this->payment->client; - collect($paid_invoices)->each(function ($paid_invoice) use ($invoices) { + if($client->trashed()) + $client->restore(); - $client = $this->payment->client; + collect($paid_invoices)->each(function ($paid_invoice) use ($invoices, $client) { - if($client->trashed()) - $client->restore(); + $client = $client->fresh(); $invoice = $invoices->first(function ($inv) use ($paid_invoice) { return $paid_invoice->invoice_id == $inv->hashed_id; }); - if($invoice->trashed()) $invoice->restore(); @@ -62,23 +63,23 @@ class UpdateInvoicePayment $paid_amount = $paid_invoice->amount; } - $client - ->service() - ->updatePaidToDate($paid_amount) - ->save(); + $client->paid_to_date += $paid_amount; + $client->balance -= $paid_amount; + $client->save(); /* Need to determine here is we have an OVER payment - if YES only apply the max invoice amount */ if($paid_amount > $invoice->partial && $paid_amount > $invoice->balance) $paid_amount = $invoice->balance; /*Improve performance here - 26-01-2022 - also change the order of events for invoice first*/ - $invoice->service() //caution what if we amount paid was less than partial - we wipe it! - ->clearPartial() - ->updateBalance($paid_amount * -1) - ->updatePaidToDate($paid_amount) - ->updateStatus() - ->touchPdf() - ->save(); + //caution what if we amount paid was less than partial - we wipe it! + $invoice = $invoice->service() + ->clearPartial() + ->updateBalance($paid_amount * -1) + ->updatePaidToDate($paid_amount) + ->updateStatus() + ->touchPdf() + ->save(); $invoice->service() ->workFlow() @@ -89,11 +90,6 @@ class UpdateInvoicePayment ->ledger() ->updatePaymentBalance($paid_amount * -1); - $client - ->service() - ->updateBalance($paid_amount * -1) - ->save(); - $pivot_invoice = $this->payment->invoices->first(function ($inv) use ($paid_invoice) { return $inv->hashed_id == $paid_invoice->invoice_id; }); diff --git a/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php b/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php index 0d075f26eaa7..79d9c77bd275 100644 --- a/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php +++ b/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php @@ -29,6 +29,10 @@ trait CompanyGatewayFeesAndLimitsSaver foreach ($casts as $key => $value) { + if($value == 'float' && property_exists($fee_and_limit, $key)){ + $fee_and_limit->{$key} = floatval($fee_and_limit->{$key}); + } + /* Handles unset settings or blank strings */ if (! property_exists($fee_and_limit, $key) || is_null($fee_and_limit->{$key}) || ! isset($fee_and_limit->{$key}) || $fee_and_limit->{$key} == '') { continue; diff --git a/app/Utils/Traits/SettingsSaver.php b/app/Utils/Traits/SettingsSaver.php index 5237afbf32e1..fbcc7d44e1ad 100644 --- a/app/Utils/Traits/SettingsSaver.php +++ b/app/Utils/Traits/SettingsSaver.php @@ -35,6 +35,12 @@ trait SettingsSaver ksort($casts); foreach ($casts as $key => $value) { + + //try casting floats here + if($value == 'float' && property_exists($settings, $key)){ + $settings->{$key} = floatval($settings->{$key}); + } + if (in_array($key, CompanySettings::$string_casts)) { $value = 'string'; if (! property_exists($settings, $key)) { diff --git a/config/ninja.php b/config/ninja.php index 4fcab1bfcbef..7ef7b53d3b8a 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.3.76', - 'app_tag' => '5.3.76', + 'app_version' => '5.3.77', + 'app_tag' => '5.3.77', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''),