format('Y-m-d h:i:s')); if (! config('ninja.db.multi_db_enabled')) { $this->sendReminderEmails(); } else { //multiDB environment, need to foreach (MultiDB::$dbs as $db) { MultiDB::setDB($db); $this->sendReminderEmails(); } } } private function sendReminderEmails() { $invoices = Invoice::where('is_deleted', 0) ->where('balance', '>', 0) ->whereDate('next_send_date', '<=', now()->startOfDay()) ->whereNotNull('next_send_date') ->with('client') ->cursor(); //we only need invoices that are payable $invoices->filter(function ($invoice){ return $invoice->isPayable(); })->each(function ($invoice){ $reminder_template = $invoice->calculateTemplate('invoice'); if(in_array($reminder_template, ['reminder1', 'reminder2', 'reminder3', 'endless_reminder'])) $this->sendReminder($invoice, $reminder_template); }); } private function checkSendSetting($invoice, $template) { switch ($template) { case 'reminder1': return $invoice->client->getSetting('enable_reminder1'); break; case 'reminder2': return $invoice->client->getSetting('enable_reminder2'); break; case 'reminder3': return $invoice->client->getSetting('enable_reminder3'); break; case 'endless_reminder': return $invoice->client->getSetting('enable_reminder_endless'); break; default: return false; break; } } private function calculateNextSendDate($invoice) { $dates = collect(); $settings = $invoice->client->getMergedSettings(); if((int)$settings->schedule_reminder1 > 0) $dates->push($this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder1, (int)$settings->num_days_reminder1)); if((int)$settings->num_days_reminder2 > 0) $dates->push($this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder2, (int)$settings->num_days_reminder2)); if((int)$settings->num_days_reminder3 > 0) $dates->push($this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder3, (int)$settings->num_days_reminder3)); if((int)$settings->endless_reminder_frequency_id > 0) $dates->push(); //calculate every potential date, then pluck the next one //reminder1,2,3, and endless could potentially be the NEXT_SEND_DATE // //we check num_days to determine if the setting is ACTIVE } private function calculateScheduledDate($invoice, $schedule_reminder, $num_days_reminder) { switch ($schedule_reminder) { case 'after_invoice_date': return Carbon::parse($invoice->date)->addDays($num_days_reminder)->startOfDay(); break; case 'before_due_date': return Carbon::parse($invoice->due_date)->subDays($num_days_reminder)->startOfDay(); break; case 'after_due_date': return Carbon::parse($invoice->due_date)->addDays($num_days_reminder)->startOfDay(); break; default: return null; break; } } private function sendReminder($invoice, $template) { $invoice = $this->calcLateFee($invoice, $template); $invoice->invitations->each(function ($invitation) use($template, $invoice){ //only send if enable_reminder setting is toggled to yes if($this->checkSendSetting($invoice, $template)) EmailEntity::dispatch($invitation, $invitation->company, $template); }); if ($invoice->invitations->count() > 0) event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars())); $invoice->last_sent_date = now(); $invoice->reminder_last_send = now(); $invoice->next_send_date = $this->calculateNextSendDate($invoice); if(in_array($template, ['reminder1', 'reminder2', 'reminder3'])) $invoice->{$template."_send"} = now(); //calculate next_send_date $invoice->save(); } private function calcLateFee($invoice, $template) :Invoice { $late_fee_amount = 0; $late_fee_percent = 0; switch ($template) { case 'reminder1': $late_fee_amount = $invoice->client->getSetting('late_fee_amount1'); $late_fee_percent = $invoice->client->getSetting('late_fee_percent1'); break; case 'reminder2': $late_fee_amount = $invoice->client->getSetting('late_fee_amount2'); $late_fee_percent = $invoice->client->getSetting('late_fee_percent2'); break; case 'reminder3': $late_fee_amount = $invoice->client->getSetting('late_fee_amount3'); $late_fee_percent = $invoice->client->getSetting('late_fee_percent3'); break; case 'endless_reminder': $late_fee_amount = $invoice->client->getSetting('late_fee_endless_amount'); $late_fee_percent = $invoice->client->getSetting('late_fee_endless_percent'); break; default: $late_fee_amount = 0; $late_fee_percent = 0; break; } return $this->setLateFee($invoice, $late_fee_amount, $late_fee_percent); } private function setLateFee($invoice, $amount, $percent) :Invoice { if ($amount <= 0 && $percent <= 0) { return $invoice; } $fee = $amount; if ($invoice->partial > 0) $fee += round($invoice->partial * $percent / 100, 2); else $fee += round($invoice->balance * $percent / 100, 2); $invoice_item = new InvoiceItem; $invoice_item->type_id = '5'; $invoice_item->product_key = trans('texts.fee'); $invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->formatDate(now()->startOfDay(), $invoice->client->date_format())]); $invoice_item->quantity = 1; $invoice_item->cost = $fee; $invoice_items = $invoice->line_items; $invoice_items[] = $invoice_item; $invoice->line_items = $invoice_items; /**Refresh Invoice values*/ $invoice = $invoice->calc()->getInvoice(); return $invoice; } }