From 2d54c4fdb36c2d88123f5c6216e4ccc20873eb7c Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Tue, 13 Jun 2023 15:23:54 -0400 Subject: [PATCH 1/3] Support All Time option for statements and support excluding clients with no invoices matching the selected filters --- app/DataMapper/Schedule/EmailStatement.php | 1 + .../TaskScheduler/StoreSchedulerRequest.php | 2 +- .../TaskScheduler/UpdateSchedulerRequest.php | 2 +- app/Services/Client/ClientService.php | 18 +++++- app/Services/Client/Statement.php | 58 +++++++++++++------ app/Services/PdfMaker/Design.php | 28 +++++---- .../Scheduler/EmailStatementService.php | 4 +- lang/en/texts.php | 2 + 8 files changed, 82 insertions(+), 33 deletions(-) diff --git a/app/DataMapper/Schedule/EmailStatement.php b/app/DataMapper/Schedule/EmailStatement.php index b9ece221c7ee..6f5499fdf7c3 100644 --- a/app/DataMapper/Schedule/EmailStatement.php +++ b/app/DataMapper/Schedule/EmailStatement.php @@ -41,6 +41,7 @@ class EmailStatement public const LAST_QUARTER = "last_quarter"; public const THIS_YEAR = "this_year"; public const LAST_YEAR = "last_year"; + public const ALL_TIME = "all_time"; public const CUSTOM_RANGE = "custom"; diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 47156bf84a48..1c132dbb9b06 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -40,7 +40,7 @@ class StoreSchedulerRequest extends Request 'template' => 'bail|required|string', 'parameters' => 'bail|array', 'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()], - 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,custom', + 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom', 'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'], 'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'], 'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'], diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index 775b45db5603..74d011722ca2 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -37,7 +37,7 @@ class UpdateSchedulerRequest extends Request 'template' => 'bail|required|string', 'parameters' => 'bail|array', 'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()], - 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,custom', + 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom', 'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'], 'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'], 'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'], diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php index 6492bdde5f89..a30cccd16531 100644 --- a/app/Services/Client/ClientService.php +++ b/app/Services/Client/ClientService.php @@ -18,6 +18,7 @@ use App\Services\Email\Email; use App\Services\Email\EmailObject; use App\Utils\Number; use App\Utils\Traits\MakesDates; +use Carbon\Carbon; use Illuminate\Mail\Mailables\Address; use Illuminate\Support\Facades\DB; @@ -149,7 +150,22 @@ class ClientService $pdf = $statement->run(); if ($send_email) { - return $this->emailStatement($pdf, $statement->options); + // If selected, ignore clients that don't have any invoices to put on the statement. + if (!empty($options['only_clients_with_invoices'] && $statement->getInvoices()->count() == 0)) { + return false; + } + + $options = $statement->options; + + if (empty($options['start_date'])) { + $options['start_date'] = $statement->getInvoices()->first()->date; + } + + if (empty($options['end_date'])) { + $options['end_date'] = Carbon::now(); + } + + return $this->emailStatement($pdf, $options); } return $pdf; diff --git a/app/Services/Client/Statement.php b/app/Services/Client/Statement.php index 63406638a343..8894ff7208a8 100644 --- a/app/Services/Client/Statement.php +++ b/app/Services/Client/Statement.php @@ -211,6 +211,9 @@ class Statement $this->options['show_credits_table'] = false; } + if (!\array_key_exists('only_clients_with_invoices', $this->options)) { + $this->options['only_clients_with_invoices'] = false; + } return $this; } @@ -220,18 +223,25 @@ class Statement * * @return Invoice[]|\Illuminate\Support\LazyCollection */ - protected function getInvoices(): \Illuminate\Support\LazyCollection + public function getInvoices(): \Illuminate\Support\LazyCollection { - return Invoice::withTrashed() + $query = Invoice::withTrashed() ->with('payments.type') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', $this->invoiceStatuses()) - ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) ->orderBy('due_date', 'ASC') - ->orderBy('date', 'ASC') - ->cursor(); + ->orderBy('date', 'ASC'); + + if (!empty($this->options['start_date'])) { + $query->whereDate('date', '>=', $this->options['start_date']); + } + if (!empty($this->options['end_date'])) { + $query->whereDate('date', '<=', $this->options['end_date']); + } + + return $query->cursor(); } private function invoiceStatuses() :array @@ -266,15 +276,22 @@ class Statement */ protected function getPayments(): \Illuminate\Support\LazyCollection { - return Payment::withTrashed() + $query = Payment::withTrashed() ->with('client.country', 'invoices') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED]) - ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) - ->orderBy('date', 'ASC') - ->cursor(); + ->orderBy('date', 'ASC'); + + if (!empty($this->options['start_date'])) { + $query->whereDate('date', '>=', $this->options['start_date']); + } + if (!empty($this->options['end_date'])) { + $query->whereDate('date', '<=', $this->options['end_date']); + } + + return $query->cursor(); } /** @@ -284,19 +301,26 @@ class Statement */ protected function getCredits(): \Illuminate\Support\LazyCollection { - return Credit::withTrashed() + $query = Credit::withTrashed() ->with('client.country', 'invoices') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', [Credit::STATUS_SENT, Credit::STATUS_PARTIAL, Credit::STATUS_APPLIED]) - ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) - ->where(function ($query) { - $query->whereDate('due_date', '>=', $this->options['end_date']) - ->orWhereNull('due_date'); - }) - ->orderBy('date', 'ASC') - ->cursor(); + ->orderBy('date', 'ASC'); + + if (!empty($this->options['start_date'])) { + $query->whereDate('date', '>=', $this->options['start_date']); + } + if (!empty($this->options['end_date'])) { + $query->whereDate('date', '<=', $this->options['end_date']) + ->where(function ($query) { + $query->whereDate('due_date', '>=', $this->options['end_date']) + ->orWhereNull('due_date'); + }); + } + + return $query->cursor(); } /** diff --git a/app/Services/PdfMaker/Design.php b/app/Services/PdfMaker/Design.php index 0ca138f12823..9568444c7d65 100644 --- a/app/Services/PdfMaker/Design.php +++ b/app/Services/PdfMaker/Design.php @@ -391,23 +391,27 @@ class Design extends BaseDesign { if ($this->type === 'statement') { // $s_date = $this->translateDate(now(), $this->client->date_format(), $this->client->locale()); - - $s_date = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale()) . " - " . $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale()); - return [ + + $headerParts = [ ['element' => 'tr', 'properties' => ['data-ref' => 'statement-label'], 'elements' => [ ['element' => 'th', 'properties' => [], 'content' => ""], - ['element' => 'th', 'properties' => [], 'content' => "

".ctrans('texts.statement')."

"], - ]], - ['element' => 'tr', 'properties' => [], 'elements' => [ - ['element' => 'th', 'properties' => [], 'content' => ctrans('texts.statement_date')], - ['element' => 'th', 'properties' => [], 'content' => $s_date ?? ''], - ]], - ['element' => 'tr', 'properties' => [], 'elements' => [ - ['element' => 'th', 'properties' => [], 'content' => '$balance_due_label'], - ['element' => 'th', 'properties' => [], 'content' => Number::formatMoney($this->invoices->sum('balance'), $this->client)], + ['element' => 'th', 'properties' => [], 'content' => "

" . ctrans('texts.statement') . "

"], ]], ]; + if (!empty($this->options['start_date']) || !empty($this->options['end_date'])) { + $s_date = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale()) . " - " . $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale()); + $headerParts[] = + ['element' => 'tr', 'properties' => [], 'elements' => [ + ['element' => 'th', 'properties' => [], 'content' => ctrans('texts.statement_date')], + ['element' => 'th', 'properties' => [], 'content' => $s_date ?? ''], + ]]; + } + $headerParts[] = ['element' => 'tr', 'properties' => [], 'elements' => [ + ['element' => 'th', 'properties' => [], 'content' => '$balance_due_label'], + ['element' => 'th', 'properties' => [], 'content' => Number::formatMoney($this->invoices->sum('balance'), $this->client)], + ]]; + return $headerParts; } $variables = $this->context['pdf_variables']['invoice_details']; diff --git a/app/Services/Scheduler/EmailStatementService.php b/app/Services/Scheduler/EmailStatementService.php index 770ffdc203a2..6a9a77839b0d 100644 --- a/app/Services/Scheduler/EmailStatementService.php +++ b/app/Services/Scheduler/EmailStatementService.php @@ -71,10 +71,11 @@ class EmailStatementService 'show_payments_table' => $this->scheduler->parameters['show_payments_table'] ?? true, 'show_aging_table' => $this->scheduler->parameters['show_aging_table'] ?? true, 'show_credits_table' => $this->scheduler->parameters['show_credits_table'] ?? true, + 'only_clients_with_invoices' => $this->scheduler->parameters['only_clients_with_invoices'] ?? true, 'status' => $this->scheduler->parameters['status'] ]; } - + /** * Start and end date of the statement * @@ -92,6 +93,7 @@ class EmailStatementService EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')], EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')], EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')], + EmailStatement::ALL_TIME => [null, null], EmailStatement::CUSTOM_RANGE => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']], default => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')], }; diff --git a/lang/en/texts.php b/lang/en/texts.php index c85e0263513b..860c98e3142a 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -2000,6 +2000,7 @@ $LANG = array( 'current_quarter' => 'Current Quarter', 'last_quarter' => 'Last Quarter', 'last_year' => 'Last Year', + 'all_time' => 'All Time', 'custom_range' => 'Custom Range', 'url' => 'URL', 'debug' => 'Debug', @@ -4907,6 +4908,7 @@ $LANG = array( 'all_clients' => 'All Clients', 'show_aging_table' => 'Show Aging Table', 'show_payments_table' => 'Show Payments Table', + 'only_clients_with_invoices' => 'Only Clients with Invoices', 'email_statement' => 'Email Statement', 'once' => 'Once', 'schedules' => 'Schedules', From 347c4f95d6f6b1f3fe2a0d48e408a45ddbaa8541 Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Thu, 15 Jun 2023 13:46:11 -0400 Subject: [PATCH 2/3] Switch "All Time" option for statements to pull the earliest invoice date. --- app/Services/Client/ClientService.php | 14 +---- app/Services/Client/Statement.php | 53 ++++++------------- app/Services/PdfMaker/Design.php | 28 +++++----- .../Scheduler/EmailStatementService.php | 21 +++++--- 4 files changed, 43 insertions(+), 73 deletions(-) diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php index a30cccd16531..6e22782a298f 100644 --- a/app/Services/Client/ClientService.php +++ b/app/Services/Client/ClientService.php @@ -151,21 +151,11 @@ class ClientService if ($send_email) { // If selected, ignore clients that don't have any invoices to put on the statement. - if (!empty($options['only_clients_with_invoices'] && $statement->getInvoices()->count() == 0)) { + if (!empty($options['only_clients_with_invoices']) && $statement->getInvoices()->count() == 0) { return false; } - $options = $statement->options; - - if (empty($options['start_date'])) { - $options['start_date'] = $statement->getInvoices()->first()->date; - } - - if (empty($options['end_date'])) { - $options['end_date'] = Carbon::now(); - } - - return $this->emailStatement($pdf, $options); + return $this->emailStatement($pdf, $statement->options); } return $pdf; diff --git a/app/Services/Client/Statement.php b/app/Services/Client/Statement.php index 8894ff7208a8..4fe0ccc36fbe 100644 --- a/app/Services/Client/Statement.php +++ b/app/Services/Client/Statement.php @@ -225,23 +225,16 @@ class Statement */ public function getInvoices(): \Illuminate\Support\LazyCollection { - $query = Invoice::withTrashed() + return Invoice::withTrashed() ->with('payments.type') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', $this->invoiceStatuses()) + ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) ->orderBy('due_date', 'ASC') - ->orderBy('date', 'ASC'); - - if (!empty($this->options['start_date'])) { - $query->whereDate('date', '>=', $this->options['start_date']); - } - if (!empty($this->options['end_date'])) { - $query->whereDate('date', '<=', $this->options['end_date']); - } - - return $query->cursor(); + ->orderBy('date', 'ASC') + ->cursor(); } private function invoiceStatuses() :array @@ -276,22 +269,15 @@ class Statement */ protected function getPayments(): \Illuminate\Support\LazyCollection { - $query = Payment::withTrashed() + return Payment::withTrashed() ->with('client.country', 'invoices') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED]) - ->orderBy('date', 'ASC'); - - if (!empty($this->options['start_date'])) { - $query->whereDate('date', '>=', $this->options['start_date']); - } - if (!empty($this->options['end_date'])) { - $query->whereDate('date', '<=', $this->options['end_date']); - } - - return $query->cursor(); + ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) + ->orderBy('date', 'ASC') + ->cursor(); } /** @@ -301,26 +287,19 @@ class Statement */ protected function getCredits(): \Illuminate\Support\LazyCollection { - $query = Credit::withTrashed() + return Credit::withTrashed() ->with('client.country', 'invoices') ->where('is_deleted', false) ->where('company_id', $this->client->company_id) ->where('client_id', $this->client->id) ->whereIn('status_id', [Credit::STATUS_SENT, Credit::STATUS_PARTIAL, Credit::STATUS_APPLIED]) - ->orderBy('date', 'ASC'); - - if (!empty($this->options['start_date'])) { - $query->whereDate('date', '>=', $this->options['start_date']); - } - if (!empty($this->options['end_date'])) { - $query->whereDate('date', '<=', $this->options['end_date']) - ->where(function ($query) { - $query->whereDate('due_date', '>=', $this->options['end_date']) - ->orWhereNull('due_date'); - }); - } - - return $query->cursor(); + ->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])]) + ->where(function ($query) { + $query->whereDate('due_date', '>=', $this->options['end_date']) + ->orWhereNull('due_date'); + }) + ->orderBy('date', 'ASC') + ->cursor(); } /** diff --git a/app/Services/PdfMaker/Design.php b/app/Services/PdfMaker/Design.php index 9568444c7d65..0ca138f12823 100644 --- a/app/Services/PdfMaker/Design.php +++ b/app/Services/PdfMaker/Design.php @@ -391,27 +391,23 @@ class Design extends BaseDesign { if ($this->type === 'statement') { // $s_date = $this->translateDate(now(), $this->client->date_format(), $this->client->locale()); + + $s_date = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale()) . " - " . $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale()); - - $headerParts = [ + return [ ['element' => 'tr', 'properties' => ['data-ref' => 'statement-label'], 'elements' => [ ['element' => 'th', 'properties' => [], 'content' => ""], - ['element' => 'th', 'properties' => [], 'content' => "

" . ctrans('texts.statement') . "

"], + ['element' => 'th', 'properties' => [], 'content' => "

".ctrans('texts.statement')."

"], + ]], + ['element' => 'tr', 'properties' => [], 'elements' => [ + ['element' => 'th', 'properties' => [], 'content' => ctrans('texts.statement_date')], + ['element' => 'th', 'properties' => [], 'content' => $s_date ?? ''], + ]], + ['element' => 'tr', 'properties' => [], 'elements' => [ + ['element' => 'th', 'properties' => [], 'content' => '$balance_due_label'], + ['element' => 'th', 'properties' => [], 'content' => Number::formatMoney($this->invoices->sum('balance'), $this->client)], ]], ]; - if (!empty($this->options['start_date']) || !empty($this->options['end_date'])) { - $s_date = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale()) . " - " . $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale()); - $headerParts[] = - ['element' => 'tr', 'properties' => [], 'elements' => [ - ['element' => 'th', 'properties' => [], 'content' => ctrans('texts.statement_date')], - ['element' => 'th', 'properties' => [], 'content' => $s_date ?? ''], - ]]; - } - $headerParts[] = ['element' => 'tr', 'properties' => [], 'elements' => [ - ['element' => 'th', 'properties' => [], 'content' => '$balance_due_label'], - ['element' => 'th', 'properties' => [], 'content' => Number::formatMoney($this->invoices->sum('balance'), $this->client)], - ]]; - return $headerParts; } $variables = $this->context['pdf_variables']['invoice_details']; diff --git a/app/Services/Scheduler/EmailStatementService.php b/app/Services/Scheduler/EmailStatementService.php index 6a9a77839b0d..e795f83b1b32 100644 --- a/app/Services/Scheduler/EmailStatementService.php +++ b/app/Services/Scheduler/EmailStatementService.php @@ -16,6 +16,7 @@ use App\Models\Scheduler; use App\Utils\Traits\MakesHash; use App\DataMapper\Schedule\EmailStatement; use App\Utils\Traits\MakesDates; +use Carbon\Carbon; class EmailStatementService { @@ -46,7 +47,7 @@ class EmailStatementService $this->client = $_client; //work out the date range - $statement_properties = $this->calculateStatementProperties(); + $statement_properties = $this->calculateStatementProperties($_client); $_client->service()->statement($statement_properties, true); }); @@ -61,17 +62,17 @@ class EmailStatementService * * @return array The statement options array */ - private function calculateStatementProperties(): array + private function calculateStatementProperties(Client $client): array { - $start_end = $this->calculateStartAndEndDates(); + $start_end = $this->calculateStartAndEndDates($client); return [ - 'start_date' =>$start_end[0], - 'end_date' =>$start_end[1], + 'start_date' => $start_end[0], + 'end_date' => $start_end[1], 'show_payments_table' => $this->scheduler->parameters['show_payments_table'] ?? true, 'show_aging_table' => $this->scheduler->parameters['show_aging_table'] ?? true, 'show_credits_table' => $this->scheduler->parameters['show_credits_table'] ?? true, - 'only_clients_with_invoices' => $this->scheduler->parameters['only_clients_with_invoices'] ?? true, + 'only_clients_with_invoices' => $this->scheduler->parameters['only_clients_with_invoices'] ?? false, 'status' => $this->scheduler->parameters['status'] ]; } @@ -81,7 +82,7 @@ class EmailStatementService * * @return array [$start_date, $end_date]; */ - private function calculateStartAndEndDates(): array + private function calculateStartAndEndDates(Client $client): array { return match ($this->scheduler->parameters['date_range']) { EmailStatement::LAST7 => [now()->startOfDay()->subDays(7)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')], @@ -93,7 +94,11 @@ class EmailStatementService EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')], EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')], EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')], - EmailStatement::ALL_TIME => [null, null], + EmailStatement::ALL_TIME => [ + $client->invoices()->selectRaw('MIN(invoices.date) as start_date')->pluck('start_date')->first() + ?: Carbon::now()->format('Y-m-d'), + Carbon::now()->format('Y-m-d') + ], EmailStatement::CUSTOM_RANGE => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']], default => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')], }; From e6dac5cf655ace109cdd9dd25ec8c6555196b3da Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Thu, 15 Jun 2023 21:42:40 -0400 Subject: [PATCH 3/3] Performance improvement --- app/Services/Scheduler/EmailStatementService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Services/Scheduler/EmailStatementService.php b/app/Services/Scheduler/EmailStatementService.php index e795f83b1b32..3ce5d5f7f7bf 100644 --- a/app/Services/Scheduler/EmailStatementService.php +++ b/app/Services/Scheduler/EmailStatementService.php @@ -95,7 +95,7 @@ class EmailStatementService EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')], EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')], EmailStatement::ALL_TIME => [ - $client->invoices()->selectRaw('MIN(invoices.date) as start_date')->pluck('start_date')->first() + Invoice::withTrashed()->where('client_id', $client->id)->selectRaw('MIN(invoices.date) as start_date')->pluck('start_date')->first() ?: Carbon::now()->format('Y-m-d'), Carbon::now()->format('Y-m-d') ],