diff --git a/app/Console/Commands/SendRemindersCron.php b/app/Console/Commands/SendRemindersCron.php index 098f1b032b57..7ce0ba0bdcdf 100644 --- a/app/Console/Commands/SendRemindersCron.php +++ b/app/Console/Commands/SendRemindersCron.php @@ -62,10 +62,10 @@ class SendRemindersCron extends Command public function handle() { Invoice::where('next_send_date', '<=', now()->toDateTimeString()) - ->whereNull('deleted_at') - ->where('is_deleted', 0) - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('balance', '>', 0) + ->whereNull('invoices.deleted_at') + ->where('invoices.is_deleted', 0) + ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('invoices.balance', '>', 0) ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -73,6 +73,7 @@ class SendRemindersCron extends Command ->whereHas('company', function ($query) { $query->where('is_disabled', 0); }) + ->with('invitations')->cursor()->each(function ($invoice) { if ($invoice->isPayable()) { $reminder_template = $invoice->calculateTemplate('invoice'); diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php index a9fa3c165dda..6d76a1352de4 100644 --- a/app/Filters/InvoiceFilters.php +++ b/app/Filters/InvoiceFilters.php @@ -320,7 +320,7 @@ class InvoiceFilters extends QueryFilters { $sort_col = explode('|', $sort); - if (!is_array($sort_col) || count($sort_col) != 2) { + if (!is_array($sort_col) || count($sort_col) != 2 || in_array($sort_col[0], ['documents'])) { return $this->builder; } diff --git a/app/Helpers/Invoice/InvoiceSumInclusive.php b/app/Helpers/Invoice/InvoiceSumInclusive.php index fe50d9cb1fb0..6df714231f04 100644 --- a/app/Helpers/Invoice/InvoiceSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceSumInclusive.php @@ -107,16 +107,16 @@ class InvoiceSumInclusive private function calculateCustomValues() { - $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1); + // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1); $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge1); - $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2); + // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2); $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge2); - $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3); + // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3); $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge3); - $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4); + // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4); $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4); $this->total += $this->total_custom_values; @@ -137,21 +137,21 @@ class InvoiceSumInclusive } //Handles cases where the surcharge is not taxed - // if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && !$this->invoice->custom_surcharge_tax1) { - // $amount += $this->invoice->custom_surcharge1; - // } + if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && $this->invoice->custom_surcharge_tax1) { + $amount += $this->invoice->custom_surcharge1; + } - // if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && !$this->invoice->custom_surcharge_tax2) { - // $amount += $this->invoice->custom_surcharge2; - // } + if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && $this->invoice->custom_surcharge_tax2) { + $amount += $this->invoice->custom_surcharge2; + } - // if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && !$this->invoice->custom_surcharge_tax3) { - // $amount += $this->invoice->custom_surcharge3; - // } + if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && $this->invoice->custom_surcharge_tax3) { + $amount += $this->invoice->custom_surcharge3; + } - // if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && !$this->invoice->custom_surcharge_tax4) { - // $amount += $this->invoice->custom_surcharge4; - // } + if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && $this->invoice->custom_surcharge_tax4) { + $amount += $this->invoice->custom_surcharge4; + } if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) { $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 50b0c46cf58e..5cf35adef3c2 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -81,14 +81,20 @@ class SearchController extends Controller $invoices = Invoice::query() ->company() ->with('client') - ->where('is_deleted', 0) - ->whereHas('client', function ($q) { - $q->where('is_deleted', 0); - }) + ->where('invoices.is_deleted', 0) + // ->whereHas('client', function ($q) { + // $q->where('is_deleted', 0); + // }) + + ->leftJoin('clients', function ($join) { + $join->on('invoices.client_id', '=', 'clients.id') + ->where('clients.is_deleted', 0); + }) + ->when(!$user->hasPermission('view_all') || !$user->hasPermission('view_invoice'), function ($query) use ($user) { - $query->where('user_id', $user->id); + $query->where('invoices.user_id', $user->id); }) - ->orderBy('id', 'desc') + ->orderBy('invoices.id', 'desc') ->take(3000) ->get(); diff --git a/app/Http/Requests/Invoice/StoreInvoiceRequest.php b/app/Http/Requests/Invoice/StoreInvoiceRequest.php index 1b8d8693729e..767ac8db722d 100644 --- a/app/Http/Requests/Invoice/StoreInvoiceRequest.php +++ b/app/Http/Requests/Invoice/StoreInvoiceRequest.php @@ -78,7 +78,9 @@ class StoreInvoiceRequest extends Request $rules['tax_name3'] = 'bail|sometimes|string|nullable'; $rules['exchange_rate'] = 'bail|sometimes|numeric'; $rules['partial'] = 'bail|sometimes|nullable|numeric|gte:0'; - $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date']; + $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; + $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date ?? '') > 1), 'date']; + $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; // $rules['amount'] = ['sometimes', 'bail', 'max:99999999999999']; diff --git a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php index 0c71d72ac8ed..9d960ef379c9 100644 --- a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php +++ b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php @@ -82,8 +82,8 @@ class UpdateInvoiceRequest extends Request $rules['date'] = 'bail|sometimes|date:Y-m-d'; - // $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date']; - // $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; + $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; + $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', 'after_or_equal:date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; return $rules; } diff --git a/app/Http/Requests/Quote/StoreQuoteRequest.php b/app/Http/Requests/Quote/StoreQuoteRequest.php index e3d0bd4cfb52..4b2624ee7a6e 100644 --- a/app/Http/Requests/Quote/StoreQuoteRequest.php +++ b/app/Http/Requests/Quote/StoreQuoteRequest.php @@ -66,8 +66,8 @@ class StoreQuoteRequest extends Request $rules['exchange_rate'] = 'bail|sometimes|numeric'; $rules['line_items'] = 'array'; $rules['date'] = 'bail|sometimes|date:Y-m-d'; - $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date', 'after_or_equal:date']; - $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; + $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; + $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date ?? '') > 1), 'date']; $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; return $rules; diff --git a/app/Http/Requests/Quote/UpdateQuoteRequest.php b/app/Http/Requests/Quote/UpdateQuoteRequest.php index ce8c6eeeb273..77ac6f2f4abd 100644 --- a/app/Http/Requests/Quote/UpdateQuoteRequest.php +++ b/app/Http/Requests/Quote/UpdateQuoteRequest.php @@ -65,7 +65,7 @@ class UpdateQuoteRequest extends Request $rules['date'] = 'bail|sometimes|date:Y-m-d'; - $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date']; + $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', 'after_or_equal:date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php index f295ea6e446b..b9c30656a5c8 100644 --- a/app/Jobs/Cron/RecurringInvoicesCron.php +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -48,12 +48,12 @@ class RecurringInvoicesCron Auth::logout(); if (! config('ninja.db.multi_db_enabled')) { - $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) - ->where('is_deleted', false) - ->where('remaining_cycles', '!=', '0') - ->whereNotNull('next_send_date') - ->whereNull('deleted_at') - ->where('next_send_date', '<=', now()->toDateTimeString()) + $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) + ->where('recurring_invoices.is_deleted', false) + ->where('recurring_invoices.remaining_cycles', '!=', '0') + ->whereNotNull('recurring_invoices.next_send_date') + ->whereNull('recurring_invoices.deleted_at') + ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -87,18 +87,27 @@ class RecurringInvoicesCron foreach (MultiDB::$dbs as $db) { MultiDB::setDB($db); - $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) - ->where('is_deleted', false) - ->where('remaining_cycles', '!=', '0') - ->whereNull('deleted_at') - ->whereNotNull('next_send_date') - ->where('next_send_date', '<=', now()->toDateTimeString()) - ->whereHas('client', function ($query) { - $query->where('is_deleted', 0) - ->where('deleted_at', null); + $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) + ->where('recurring_invoices.is_deleted', false) + ->where('recurring_invoices.remaining_cycles', '!=', '0') + ->whereNull('recurring_invoices.deleted_at') + ->whereNotNull('recurring_invoices.next_send_date') + ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) + // ->whereHas('client', function ($query) { + // $query->where('is_deleted', 0) + // ->where('deleted_at', null); + // }) + // ->whereHas('company', function ($query) { + // $query->where('is_disabled', 0); + // }) + ->leftJoin('clients', function ($join) { + $join->on('recurring_invoices.client_id', '=', 'clients.id') + ->where('clients.is_deleted', 0) + ->whereNull('clients.deleted_at'); }) - ->whereHas('company', function ($query) { - $query->where('is_disabled', 0); + ->leftJoin('companies', function ($join) { + $join->on('recurring_invoices.company_id', '=', 'companies.id') + ->where('companies.is_disabled', 0); }) ->with('company') ->cursor(); diff --git a/app/Jobs/Invoice/InvoiceCheckLateWebhook.php b/app/Jobs/Invoice/InvoiceCheckLateWebhook.php index 50576ac642d5..4e036657f96c 100644 --- a/app/Jobs/Invoice/InvoiceCheckLateWebhook.php +++ b/app/Jobs/Invoice/InvoiceCheckLateWebhook.php @@ -51,20 +51,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue ->pluck('company_id'); Invoice::query() - ->where('is_deleted', false) - ->whereNull('deleted_at') - ->whereNotNull('due_date') - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('balance', '>', 0) - ->whereIn('company_id', $company_ids) - ->whereHas('client', function ($query) { - $query->where('is_deleted', 0) - ->where('deleted_at', null); - }) - ->whereHas('company', function ($query) { - $query->where('is_disabled', 0); - }) - ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) + ->where('invoices.is_deleted', false) + ->whereNull('invoices.deleted_at') + ->whereNotNull('invoices.due_date') + ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('invoices.balance', '>', 0) + ->whereIn('invoices.company_id', $company_ids) + // ->whereHas('client', function ($query) { + // $query->where('is_deleted', 0) + // ->where('deleted_at', null); + // }) + // ->whereHas('company', function ($query) { + // $query->where('is_disabled', 0); + // }) + ->leftJoin('clients', function ($join) { + $join->on('invoices.client_id', '=', 'clients.id') + ->where('clients.is_deleted', 0) + ->whereNull('clients.deleted_at'); + }) + ->leftJoin('companies', function ($join) { + $join->on('invoices.company_id', '=', 'companies.id') + ->where('companies.is_disabled', 0); + }) + ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) ->cursor() ->each(function ($invoice) { (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); @@ -78,20 +87,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue ->pluck('company_id'); Invoice::query() - ->where('is_deleted', false) - ->whereNull('deleted_at') - ->whereNotNull('due_date') - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('balance', '>', 0) - ->whereIn('company_id', $company_ids) - ->whereHas('client', function ($query) { - $query->where('is_deleted', 0) - ->where('deleted_at', null); - }) - ->whereHas('company', function ($query) { - $query->where('is_disabled', 0); - }) - ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) + ->where('invoices.is_deleted', false) + ->whereNull('invoices.deleted_at') + ->whereNotNull('invoices.due_date') + ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('invoices.balance', '>', 0) + ->whereIn('invoices.company_id', $company_ids) + // ->whereHas('client', function ($query) { + // $query->where('is_deleted', 0) + // ->where('deleted_at', null); + // }) + // ->whereHas('company', function ($query) { + // $query->where('is_disabled', 0); + // }) + ->leftJoin('clients', function ($join) { + $join->on('invoices.client_id', '=', 'clients.id') + ->where('clients.is_deleted', 0) + ->whereNull('clients.deleted_at'); + }) + ->leftJoin('companies', function ($join) { + $join->on('invoices.company_id', '=', 'companies.id') + ->where('companies.is_disabled', 0); + }) + ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) ->cursor() ->each(function ($invoice) { (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); diff --git a/app/Jobs/Quote/QuoteCheckExpired.php b/app/Jobs/Quote/QuoteCheckExpired.php index 8082936b58dc..15a9ab9383de 100644 --- a/app/Jobs/Quote/QuoteCheckExpired.php +++ b/app/Jobs/Quote/QuoteCheckExpired.php @@ -49,10 +49,10 @@ class QuoteCheckExpired implements ShouldQueue { if (! config('ninja.db.multi_db_enabled')) { Quote::query() - ->where('status_id', Quote::STATUS_SENT) - ->where('is_deleted', false) - ->whereNull('deleted_at') - ->whereNotNull('due_date') + ->where('quotes.status_id', Quote::STATUS_SENT) + ->where('quotes.is_deleted', false) + ->whereNull('quotes.deleted_at') + ->whereNotNull('quotes.due_date') ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -60,8 +60,8 @@ class QuoteCheckExpired implements ShouldQueue ->whereHas('company', function ($query) { $query->where('is_disabled', 0); }) - // ->where('due_date', '<='. now()->toDateTimeString()) - ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) + + ->whereBetween('quotes.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) ->cursor() ->each(function ($quote) { $this->queueExpiredQuoteNotification($quote); @@ -71,10 +71,10 @@ class QuoteCheckExpired implements ShouldQueue MultiDB::setDB($db); Quote::query() - ->where('status_id', Quote::STATUS_SENT) - ->where('is_deleted', false) - ->whereNull('deleted_at') - ->whereNotNull('due_date') + ->where('quotes.status_id', Quote::STATUS_SENT) + ->where('quotes.is_deleted', false) + ->whereNull('quotes.deleted_at') + ->whereNotNull('quotes.due_date') ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -82,8 +82,8 @@ class QuoteCheckExpired implements ShouldQueue ->whereHas('company', function ($query) { $query->where('is_disabled', 0); }) - // ->where('due_date', '<='. now()->toDateTimeString()) - ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) + + ->whereBetween('quotes.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) ->cursor() ->each(function ($quote) { $this->queueExpiredQuoteNotification($quote); diff --git a/app/Jobs/Util/QuoteReminderJob.php b/app/Jobs/Util/QuoteReminderJob.php index ed1aa5fa722a..fdebf50198c7 100644 --- a/app/Jobs/Util/QuoteReminderJob.php +++ b/app/Jobs/Util/QuoteReminderJob.php @@ -61,10 +61,10 @@ class QuoteReminderJob implements ShouldQueue nrlog("Sending quote reminders on ".now()->format('Y-m-d h:i:s')); Quote::query() - ->where('is_deleted', 0) - ->whereIn('status_id', [Invoice::STATUS_SENT]) - ->whereNull('deleted_at') - ->where('next_send_date', '<=', now()->toDateTimeString()) + ->where('quotes.is_deleted', 0) + ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) + ->whereNull('quotes.deleted_at') + ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -88,10 +88,10 @@ class QuoteReminderJob implements ShouldQueue nrlog("Sending quote reminders on db {$db} ".now()->format('Y-m-d h:i:s')); Quote::query() - ->where('is_deleted', 0) - ->whereIn('status_id', [Invoice::STATUS_SENT]) - ->whereNull('deleted_at') - ->where('next_send_date', '<=', now()->toDateTimeString()) + ->where('quotes.is_deleted', 0) + ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) + ->whereNull('quotes.deleted_at') + ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) ->whereHas('client', function ($query) { $query->where('is_deleted', 0) ->where('deleted_at', null); @@ -99,6 +99,7 @@ class QuoteReminderJob implements ShouldQueue ->whereHas('company', function ($query) { $query->where('is_disabled', 0); }) + ->with('invitations')->chunk(50, function ($quotes) { foreach ($quotes as $quote) { diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php index 1bb055ecc733..ab83f2f80fb1 100644 --- a/app/Repositories/ExpenseRepository.php +++ b/app/Repositories/ExpenseRepository.php @@ -47,11 +47,10 @@ class ExpenseRepository extends BaseRepository $user = auth()->user(); $payment_date = &$data['payment_date']; - $vendor_id = &$data['vendor_id']; if($payment_date && $payment_date == $expense->payment_date) { //do nothing - } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && ($vendor_id || $expense->vendor_id)) { + } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && (isset($data['vendor_id']) || $expense->vendor_id)) { $this->notify_vendor = true; } diff --git a/app/Services/Report/ARDetailReport.php b/app/Services/Report/ARDetailReport.php index be8c83069936..68d2dd11be68 100644 --- a/app/Services/Report/ARDetailReport.php +++ b/app/Services/Report/ARDetailReport.php @@ -90,15 +90,15 @@ class ARDetailReport extends BaseExport $this->csv->insertOne($this->buildHeader()); $query = Invoice::query() + ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) ->withTrashed() ->whereHas('client', function ($query) { $query->where('is_deleted', 0); }) - ->where('company_id', $this->company->id) - ->where('is_deleted', 0) - ->where('balance', '>', 0) - ->orderBy('due_date', 'ASC') - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]); + ->where('invoices.company_id', $this->company->id) + ->where('invoices.is_deleted', 0) + ->where('invoices.balance', '>', 0) + ->orderBy('invoices.due_date', 'ASC'); $query = $this->addDateRange($query, 'invoices'); diff --git a/app/Utils/Traits/Pdf/PdfMaker.php b/app/Utils/Traits/Pdf/PdfMaker.php index 7d5259192b86..112570272f4a 100644 --- a/app/Utils/Traits/Pdf/PdfMaker.php +++ b/app/Utils/Traits/Pdf/PdfMaker.php @@ -39,7 +39,7 @@ trait PdfMaker $pdf->addChromiumArguments(config('ninja.snappdf_chromium_arguments')); } - $html = str_replace(['file:/', 'iframe', '<object', 'setHtml($html) diff --git a/resources/views/portal/ninja2020/recurring_invoices/show.blade.php b/resources/views/portal/ninja2020/recurring_invoices/show.blade.php index df9a8c59bf9d..aed229b7fbe5 100644 --- a/resources/views/portal/ninja2020/recurring_invoices/show.blade.php +++ b/resources/views/portal/ninja2020/recurring_invoices/show.blade.php @@ -101,18 +101,7 @@ - - - - - - - - - - @if($invoice->subscription && $invoice->subscription?->allow_cancellation) - {{-- INV2-591 --}} - {{-- @if(false) --}} + @if($invoice->subscription && $invoice->subscription?->allow_cancellation && $invoice->status_id == 2)
diff --git a/resources/views/portal/ninja2020/subscriptions/show.blade.php b/resources/views/portal/ninja2020/subscriptions/show.blade.php index a2e226cd928c..c3540d56b788 100644 --- a/resources/views/portal/ninja2020/subscriptions/show.blade.php +++ b/resources/views/portal/ninja2020/subscriptions/show.blade.php @@ -73,7 +73,7 @@
@endif - @if($invoice->subscription && $invoice->subscription?->allow_cancellation) + @if($invoice->subscription && $invoice->subscription?->allow_cancellation && $invoice->status_id == 2)
@@ -92,7 +92,7 @@
@endif - @if($invoice->subscription && $invoice->subscription->allow_plan_changes) + @if($invoice->subscription && $invoice->subscription->allow_plan_changes && count($invoice->subscription->service()->getPlans()) > 0)

{{ ctrans('texts.change_plan') }}

{{ ctrans('texts.change_plan_description') }}

diff --git a/tests/Feature/ExpenseApiTest.php b/tests/Feature/ExpenseApiTest.php index 8ffb2ab43d98..5cf695cb90d1 100644 --- a/tests/Feature/ExpenseApiTest.php +++ b/tests/Feature/ExpenseApiTest.php @@ -47,6 +47,44 @@ class ExpenseApiTest extends TestCase Model::reguard(); } + public function testExpensePutWithVendorStatus() + { + + + $data = + [ + 'vendor_id' => $this->vendor->hashed_id, + 'amount' => 10, + 'date' => '2021-10-01', + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/expenses', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + + $this->assertEquals($this->vendor->hashed_id, $arr['data']['vendor_id']); + + $data = [ + 'payment_date' => now()->format('Y-m-d') + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->putJson('/api/v1/expenses/'.$arr['data']['id'], $data); + + $arr = $response->json(); + $response->assertStatus(200); + + $this->assertEquals($this->vendor->hashed_id, $arr['data']['vendor_id']); + + } + public function testTransactionIdClearedOnDelete() { $bi = BankIntegration::factory()->create([