diff --git a/app/DataMapper/InvoiceItem.php b/app/DataMapper/InvoiceItem.php index ccfe5138240e..6349e057ba31 100644 --- a/app/DataMapper/InvoiceItem.php +++ b/app/DataMapper/InvoiceItem.php @@ -51,7 +51,7 @@ class InvoiceItem public $custom_value4 = ''; - public $type_id = 1; //1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee + public $type_id = 1; //1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee public static $casts = [ 'type_id' => 'string', diff --git a/app/Jobs/Ninja/SendReminders.php b/app/Jobs/Ninja/SendReminders.php index a10e45075cb4..530795612cd9 100644 --- a/app/Jobs/Ninja/SendReminders.php +++ b/app/Jobs/Ninja/SendReminders.php @@ -11,8 +11,13 @@ namespace App\Jobs\Ninja; +use App\DataMapper\InvoiceItem; +use App\Events\Invoice\InvoiceWasEmailed; +use App\Jobs\Entity\EmailEntity; use App\Libraries\MultiDB; use App\Models\Invoice; +use App\Utils\Ninja; +use App\Utils\Traits\MakesDates; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -21,7 +26,7 @@ use Illuminate\Queue\SerializesModels; class SendReminders implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesDates; /** * Create a new job instance. @@ -73,6 +78,7 @@ class SendReminders implements ShouldQueue $invoices = Invoice::where('is_deleted', 0) ->where('balance', '>', 0) ->whereDate('next_send_date', '<=', now()->startOfDay()) + ->whereNotNull('next_send_date') ->cursor(); //we only need invoices that are payable @@ -84,29 +90,129 @@ class SendReminders implements ShouldQueue $reminder_template = $invoice->calculateTemplate('invoice'); - if($reminder_template == 'reminder1'){ - - } - elseif($reminder_template == 'reminder2'){ - - } - elseif($reminder_template == 'reminder3'){ - - } - elseif($reminder_template == 'endless_reminder'){ - - } - - //@todo + if(in_array($reminder_template, ['reminder1', 'reminder2', 'reminder3', 'endless_reminder'])) + $this->sendReminder($invoice, $reminder_template); }); - //iterate through all the reminder emails due today - // - //determine which reminder - // - //determine late fees - // - //send + + } + + 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, $template) + { + + } + + 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, $template); + + 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; + } } \ No newline at end of file diff --git a/app/Utils/Traits/MakesReminders.php b/app/Utils/Traits/MakesReminders.php index 9754573b401a..1c039de1fa98 100644 --- a/app/Utils/Traits/MakesReminders.php +++ b/app/Utils/Traits/MakesReminders.php @@ -190,22 +190,22 @@ trait MakesReminders return $entity_string; //if the invoice - if ($client->getSetting('enable_reminder1') !== false && $this->inReminderWindow( + if ($this->inReminderWindow( $client->getSetting('schedule_reminder1'), $client->getSetting('num_days_reminder1') )) { return 'reminder1'; - } elseif ($client->getSetting('enable_reminder2') !== false && $this->inReminderWindow( + } elseif ($this->inReminderWindow( $client->getSetting('schedule_reminder2'), $client->getSetting('num_days_reminder2') )) { return 'reminder2'; - } elseif ($client->getSetting('enable_reminder3') !== false && $this->inReminderWindow( + } elseif ($this->inReminderWindow( $client->getSetting('schedule_reminder3'), $client->getSetting('num_days_reminder3') )) { return 'reminder3'; - } elseif($client->getSetting('enable_reminder_endless') !== false && $this->checkEndlessReminder( + } elseif($this->checkEndlessReminder( $this->last_sent_date, $client->getSetting('endless_reminder_frequency_id') )){