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/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index f284e550424c..b69a79a2fa3d 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -554,7 +554,7 @@ class CreditController extends BaseController // EmailCredit::dispatch($credit, $credit->company); $credit->invitations->load('contact.client.country', 'credit.client.country', 'credit.company')->each(function ($invitation) use ($credit) { - EmailEntity::dispatch($invitation, $credit->company); + EmailEntity::dispatch($invitation, $credit->company, 'credit'); }); diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index efd29b7b09df..d768bf1cf33f 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -117,13 +117,22 @@ class EmailController extends BaseController $subject = $request->input('subject'); $body = $request->input('body'); $entity_string = strtolower(class_basename($entity_obj)); + $template = $request->input('template'); + $template = str_replace("email_template_", "", $template); + + $entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj, $template) { - $entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj) { if ($invitation->contact->send_email && $invitation->contact->email) { - EmailEntity::dispatchNow($invitation, $invitation->company); - //$invitation->contact->notify((new SendGenericNotification($invitation, $entity_string, $subject, $body))->delay($when)); + $data = [ + 'subject' => $subject, + 'body' => $body + ]; + + EmailEntity::dispatchNow($invitation, $invitation->company, $template, $data); + } + }); $entity_obj->last_sent_date = now(); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index fb0350e5fe3f..bfecb4de8b0d 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -725,7 +725,8 @@ class InvoiceController extends BaseController $invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($invoice) { $email_builder = (new InvoiceEmail())->build($invitation, $this->reminder_template); - EmailEntity::dispatch($invitation, $invoice->company); + EmailEntity::dispatch($invitation, $invoice->company, $this->reminder_template); + }); if (! $bulk) { diff --git a/app/Http/Controllers/WebhookController.php b/app/Http/Controllers/WebhookController.php index 8558a60349b6..d1388666b622 100644 --- a/app/Http/Controllers/WebhookController.php +++ b/app/Http/Controllers/WebhookController.php @@ -380,7 +380,7 @@ class WebhookController extends BaseController * * @throws \Exception * @OA\Delete( - * path="/api/v1/Webhooks/{id}", + * path="/api/v1/webhooks/{id}", * operationId="deleteWebhook", * tags={"Webhooks"}, * summary="Deletes a Webhook", diff --git a/app/Jobs/Entity/EmailEntity.php b/app/Jobs/Entity/EmailEntity.php index f2c27e6857ce..1696b0b53eaa 100644 --- a/app/Jobs/Entity/EmailEntity.php +++ b/app/Jobs/Entity/EmailEntity.php @@ -61,13 +61,14 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue public $email_entity_builder; + public $template_data; /** * EmailEntity constructor. * @param Invitation $invitation * @param Company $company * @param ?string $reminder_template */ - public function __construct($invitation, Company $company, ?string $reminder_template = null) + public function __construct($invitation, Company $company, ?string $reminder_template = null, $template_data = null) { $this->company = $company; @@ -83,7 +84,10 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue $this->html_engine = new HtmlEngine($invitation); + $this->template_data = $template_data; + $this->email_entity_builder = $this->resolveEmailBuilder(); + } /** @@ -186,6 +190,6 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue { $class = 'App\Mail\Engine\\' . ucfirst(Str::camel($this->entity_string)) . "EmailEngine"; - return (new $class($this->invitation, $this->reminder_template))->build(); + return (new $class($this->invitation, $this->reminder_template, $this->template_data))->build(); } } diff --git a/app/Jobs/Ninja/SendReminders.php b/app/Jobs/Ninja/SendReminders.php index a10e45075cb4..c8b89ba7019c 100644 --- a/app/Jobs/Ninja/SendReminders.php +++ b/app/Jobs/Ninja/SendReminders.php @@ -11,17 +11,24 @@ 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 App\Utils\Traits\MakesReminders; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Carbon; class SendReminders implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesDates, MakesReminders; /** * Create a new job instance. @@ -63,16 +70,13 @@ class SendReminders implements ShouldQueue } - private function chargeLateFee() - { - - } - 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 @@ -84,29 +88,228 @@ 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; + } + } + + /** + * Create a collection of all possible reminder dates + * and pass back the first one in chronology + * + * @param Invoice $invoice + * @return Carbon $date + */ + private function calculateNextSendDate($invoice) + { + $dates = collect(); + + $settings = $invoice->client->getMergedSettings(); + + $set_reminder1 = false; + $set_reminder2 = false; + $set_reminder3 = false; + + if((int)$settings->schedule_reminder1 > 0){ + + $next_reminder_date = $this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder1, (int)$settings->num_days_reminder1); + + if($next_reminder_date->gt(Carbon::parse($invoice->last_sent_date))); + $dates->push($next_reminder_date); + + if(!$invoice->reminder1_sent) + $set_reminder1 = true; + } + + if((int)$settings->num_days_reminder2 > 0){ + + $next_reminder_date = $this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder2, (int)$settings->num_days_reminder2); + + if($next_reminder_date->gt(Carbon::parse($invoice->last_sent_date))); + $dates->push($next_reminder_date); + + if(!$invoice->reminder2_sent) + $set_reminder3 = true; + } + + if((int)$settings->num_days_reminder3 > 0){ + + $next_reminder_date = $this->calculateScheduledDate($invoice, (int)$settings->schedule_reminder3, (int)$settings->num_days_reminder3); + + if($next_reminder_date->gt(Carbon::parse($invoice->last_sent_date))); + $dates->push($next_reminder_date); + + if(!$invoice->reminder3_sent) + $set_reminder3 = true; + } + + //If all the available reminders have fired, we then start to fire the endless reminders + if((int)$settings->endless_reminder_frequency_id > 0 && !$set_reminder1 && !$set_reminder2 && !$set_reminder3) { + $dates->push($this->addTimeInterval($invoice->last_sent_date, (int)$settings->endless_reminder_frequency_id)); + } + + //order the dates ascending and get first one + return $dates->sort()->first(); + } + + /** + * Helper method which switches values based on the $schedule_reminder + * @param Invoice $invoice + * @param string $schedule_reminder + * @param int $num_days_reminder + * @return Carbon $date + */ + private function calculateScheduledDate($invoice, $schedule_reminder, $num_days_reminder) :?Carbon + { + 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; + } + } + + /** + * Sends the reminder and/or late fee for the invoice. + * + * @param Invoice $invoice + * @param string $template + * @return void + */ + private function sendReminder($invoice, $template) :void + { + $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(); + + + $invoice->save(); + } + + /** + * Calculates the late if - if any - and rebuilds the invoice + * + * @param Invoice $invoice + * @param string $template + * @return Invoice + */ + 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); + + } + + /** + * Applies the late fee to the invoice line items + * + * @param Invoice $invoice + * @param float $amount The fee amount + * @param float $percent The fee percentage amount + * @return Invoice + */ + 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(); + + //@todo update the ledger!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + return $invoice; + } } \ No newline at end of file diff --git a/app/Jobs/Util/SendFailedEmails.php b/app/Jobs/Util/SendFailedEmails.php index 91f0850657e6..35973ac60ba6 100644 --- a/app/Jobs/Util/SendFailedEmails.php +++ b/app/Jobs/Util/SendFailedEmails.php @@ -69,7 +69,7 @@ class SendFailedEmails implements ShouldQueue $email_builder = (new InvoiceEmail())->build($invitation, $job_meta_array['reminder_template']); if ($invitation->contact->send_email && $invitation->contact->email) { - EmailEntity::dispatch($invitation, $invitation->company); + EmailEntity::dispatch($invitation, $invitation->company, $job_meta_array['reminder_template']); } } }); diff --git a/app/Mail/Engine/BaseEmailEngine.php b/app/Mail/Engine/BaseEmailEngine.php index a1fc0208f437..4b41dd965266 100644 --- a/app/Mail/Engine/BaseEmailEngine.php +++ b/app/Mail/Engine/BaseEmailEngine.php @@ -54,6 +54,9 @@ class BaseEmailEngine implements EngineInterface public function setSubject($subject) { + if (! empty($this->variables)) + $subject = str_replace(array_keys($this->variables), array_values($this->variables), $subject); + $this->subject = $subject; return $this; @@ -61,6 +64,9 @@ class BaseEmailEngine implements EngineInterface public function setBody($body) { + if (! empty($this->variables)) + $body = str_replace(array_keys($this->variables), array_values($this->variables), $body); + $this->body = $body; return $this; diff --git a/app/Mail/Engine/CreditEmailEngine.php b/app/Mail/Engine/CreditEmailEngine.php index 019248b658ed..7529767001eb 100644 --- a/app/Mail/Engine/CreditEmailEngine.php +++ b/app/Mail/Engine/CreditEmailEngine.php @@ -26,19 +26,25 @@ class CreditEmailEngine extends BaseEmailEngine public $reminder_template; - public function __construct($invitation, $reminder_template) + public $template_data; + + public function __construct($invitation, $reminder_template, $template_data) { $this->invitation = $invitation; $this->reminder_template = $reminder_template; $this->client = $invitation->contact->client; $this->credit = $invitation->credit; $this->contact = $invitation->contact; + $this->template_data = $template_data; } public function build() { - $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); + if(is_array($this->template_data) && array_key_exists('body', $this->template_data) && strlen($this->template_data['body']) > 0) + $body_template = $this->template_data['body']; + else + $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); /* Use default translations if a custom message has not been set*/ if (iconv_strlen($body_template) == 0) { @@ -54,7 +60,10 @@ class CreditEmailEngine extends BaseEmailEngine ); } - $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); + if(is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) + $subject_template = $this->template_data['subject']; + else + $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); if (iconv_strlen($subject_template) == 0) { diff --git a/app/Mail/Engine/InvoiceEmailEngine.php b/app/Mail/Engine/InvoiceEmailEngine.php index 90809330daa3..e91e13a1b33c 100644 --- a/app/Mail/Engine/InvoiceEmailEngine.php +++ b/app/Mail/Engine/InvoiceEmailEngine.php @@ -26,19 +26,25 @@ class InvoiceEmailEngine extends BaseEmailEngine public $reminder_template; - public function __construct($invitation, $reminder_template) + public $template_data; + + public function __construct($invitation, $reminder_template, $template_data) { $this->invitation = $invitation; $this->reminder_template = $reminder_template; $this->client = $invitation->contact->client; $this->invoice = $invitation->invoice; $this->contact = $invitation->contact; + $this->template_data = $template_data; } public function build() { - $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); + if(is_array($this->template_data) && array_key_exists('body', $this->template_data) && strlen($this->template_data['body']) > 0) + $body_template = $this->template_data['body']; + else + $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); /* Use default translations if a custom message has not been set*/ if (iconv_strlen($body_template) == 0) { @@ -54,7 +60,10 @@ class InvoiceEmailEngine extends BaseEmailEngine ); } - $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); + if(is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) + $subject_template = $this->template_data['subject']; + else + $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); if (iconv_strlen($subject_template) == 0) { @@ -80,7 +89,7 @@ class InvoiceEmailEngine extends BaseEmailEngine ->setViewText(ctrans('texts.view_invoice')); if ($this->client->getSetting('pdf_email_attachment') !== false) { - $this->setAttachments($invitation->pdf_file_path()); + $this->setAttachments($this->invoice->pdf_file_path()); } return $this; diff --git a/app/Mail/Engine/QuoteEmailEngine.php b/app/Mail/Engine/QuoteEmailEngine.php index dc8e92932e5e..9aef5001571d 100644 --- a/app/Mail/Engine/QuoteEmailEngine.php +++ b/app/Mail/Engine/QuoteEmailEngine.php @@ -26,20 +26,26 @@ class QuoteEmailEngine extends BaseEmailEngine public $reminder_template; - public function __construct($invitation, $reminder_template) + public $template_data; + + public function __construct($invitation, $reminder_template, $template_data) { $this->invitation = $invitation; $this->reminder_template = $reminder_template; $this->client = $invitation->contact->client; $this->quote = $invitation->quote; $this->contact = $invitation->contact; + $this->template_data = $template_data; } public function build() { - $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); - + if(is_array($this->template_data) && array_key_exists('body', $this->template_data) && strlen($this->template_data['body']) > 0) + $body_template = $this->template_data['body']; + else + $body_template = $this->client->getSetting('email_template_'.$this->reminder_template); + /* Use default translations if a custom message has not been set*/ if (iconv_strlen($body_template) == 0) { $body_template = trans( @@ -54,7 +60,10 @@ class QuoteEmailEngine extends BaseEmailEngine ); } - $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); + if(is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) + $subject_template = $this->template_data['subject']; + else + $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); if (iconv_strlen($subject_template) == 0) { diff --git a/app/Services/Credit/SendEmail.php b/app/Services/Credit/SendEmail.php index fec8604b1a03..39b3533f3bba 100644 --- a/app/Services/Credit/SendEmail.php +++ b/app/Services/Credit/SendEmail.php @@ -49,7 +49,7 @@ class SendEmail $email_builder = (new CreditEmail())->build($invitation, $this->reminder_template); // EmailCredit::dispatchNow($email_builder, $invitation, $invitation->company); - EmailEntity::dispatchNow($invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template); } }); diff --git a/app/Services/Invoice/SendEmail.php b/app/Services/Invoice/SendEmail.php index 28f0f62f8346..a69bf12c3511 100644 --- a/app/Services/Invoice/SendEmail.php +++ b/app/Services/Invoice/SendEmail.php @@ -49,7 +49,7 @@ class SendEmail extends AbstractService $email_builder = (new InvoiceEmail())->build($invitation, $this->reminder_template); if ($invitation->contact->send_email && $invitation->contact->email) { - EmailEntity::dispatchNow($invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template); } }); diff --git a/app/Services/Invoice/TriggeredActions.php b/app/Services/Invoice/TriggeredActions.php index ad4ba23074eb..c110c2492cff 100644 --- a/app/Services/Invoice/TriggeredActions.php +++ b/app/Services/Invoice/TriggeredActions.php @@ -70,7 +70,7 @@ class TriggeredActions extends AbstractService $this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($reminder_template) { - EmailEntity::dispatch($invitation, $this->invoice->company); + EmailEntity::dispatch($invitation, $this->invoice->company, $reminder_template); }); if ($this->invoice->invitations->count() > 0) { diff --git a/app/Services/Quote/SendEmail.php b/app/Services/Quote/SendEmail.php index f9ec5d5e2183..f2382567b92e 100644 --- a/app/Services/Quote/SendEmail.php +++ b/app/Services/Quote/SendEmail.php @@ -49,7 +49,7 @@ class SendEmail $email_builder = (new QuoteEmail())->build($invitation, $this->reminder_template); // EmailQuote::dispatchNow($email_builder, $invitation, $invitation->company); - EmailEntity::dispatchNow($invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template); } }); diff --git a/app/Utils/Traits/MakesReminders.php b/app/Utils/Traits/MakesReminders.php index 9754573b401a..ea66569dd973 100644 --- a/app/Utils/Traits/MakesReminders.php +++ b/app/Utils/Traits/MakesReminders.php @@ -32,134 +32,82 @@ trait MakesReminders return; //exit early } - $nsd = null; //abbreviation for next_send_date + $date_collection = collect(); - if ($settings->enable_reminder1 !== false && - $settings->schedule_reminder1 == 'after_invoice_date' && + if ($settings->schedule_reminder1 == 'after_invoice_date' && $settings->num_days_reminder1 > 0) { $reminder_date = Carbon::parse($this->date)->addDays($settings->num_days_reminder1); - $nsd = $reminder_date->format('Y-m-d'); + $date_collection->push($reminder_date->format('Y-m-d')); - - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder1 !== false && - $settings->schedule_reminder1 == 'before_due_date' && + if ($settings->schedule_reminder1 == 'before_due_date' && $settings->num_days_reminder1 > 0) { $reminder_date = Carbon::parse($this->due_date)->subDays($settings->num_days_reminder1); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder1 !== false && - $settings->schedule_reminder1 == 'after_due_date' && + if ($settings->schedule_reminder1 == 'after_due_date' && $settings->num_days_reminder1 > 0) { $reminder_date = Carbon::parse($this->due_date)->addDays($settings->num_days_reminder1); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder2 !== false && - $settings->schedule_reminder2 == 'after_invoice_date' && + if ($settings->schedule_reminder2 == 'after_invoice_date' && $settings->num_days_reminder2 > 0) { $reminder_date = Carbon::parse($this->date)->addDays($settings->num_days_reminder2); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder2 !== false && - $settings->schedule_reminder2 == 'before_due_date' && + if ($settings->schedule_reminder2 == 'before_due_date' && $settings->num_days_reminder2 > 0) { $reminder_date = Carbon::parse($this->due_date)->subDays($settings->num_days_reminder2); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder2 !== false && - $settings->schedule_reminder2 == 'after_due_date' && + if ($settings->schedule_reminder2 == 'after_due_date' && $settings->num_days_reminder2 > 0) { $reminder_date = Carbon::parse($this->due_date)->addDays($settings->num_days_reminder2); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder3 !== false && - $settings->schedule_reminder3 == 'after_invoice_date' && + if ($settings->schedule_reminder3 == 'after_invoice_date' && $settings->num_days_reminder3 > 0) { $reminder_date = Carbon::parse($this->date)->addDays($settings->num_days_reminder3); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder3 !== false && - $settings->schedule_reminder3 == 'before_due_date' && + if ($settings->schedule_reminder3 == 'before_due_date' && $settings->num_days_reminder3 > 0) { $reminder_date = Carbon::parse($this->due_date)->subDays($settings->num_days_reminder3); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - if ($settings->enable_reminder3 !== false && - $settings->schedule_reminder3 == 'after_due_date' && + if ($settings->schedule_reminder3 == 'after_due_date' && $settings->num_days_reminder3 > 0) { $reminder_date = Carbon::parse($this->due_date)->addDays($settings->num_days_reminder3); - if (! $nsd) { - $nsd = $reminder_date->format('Y-m-d'); - } + $date_collection->push($reminder_date->format('Y-m-d')); - if ($reminder_date->lt($nsd)) { - $nsd = $reminder_date->format('Y-m-d'); - } } - $this->next_send_date = $nsd; + $this->next_send_date = $date_collection->sort()->first(); + $this->save(); } @@ -190,22 +138,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') )){ @@ -220,41 +168,41 @@ trait MakesReminders private function checkEndlessReminder($last_sent_date, $endless_reminder_frequency_id) :bool { - if(Carbon::now()->startOfDay()->eq($this->addTimeInterval($endless_reminder_frequency_id))) + if(Carbon::now()->startOfDay()->eq($this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id))) return true; return false; } - private function addTimeInterval($endless_reminder_frequency_id) :?Carbon + private function addTimeInterval($date, $endless_reminder_frequency_id) :?Carbon { - if(!$this->next_send_date){ + if(!$date) return null; - } + switch ($endless_reminder_frequency_id) { case RecurringInvoice::FREQUENCY_WEEKLY: - return Carbon::parse($this->next_send_date)->addWeek()->startOfDay(); + return Carbon::parse($date)->addWeek()->startOfDay(); case RecurringInvoice::FREQUENCY_TWO_WEEKS: - return Carbon::parse($this->next_send_date)->addWeeks(2)->startOfDay(); + return Carbon::parse($date)->addWeeks(2)->startOfDay(); case RecurringInvoice::FREQUENCY_FOUR_WEEKS: - return Carbon::parse($this->next_send_date)->addWeeks(4)->startOfDay(); + return Carbon::parse($date)->addWeeks(4)->startOfDay(); case RecurringInvoice::FREQUENCY_MONTHLY: - return Carbon::parse($this->next_send_date)->addMonthNoOverflow()->startOfDay(); + return Carbon::parse($date)->addMonthNoOverflow()->startOfDay(); case RecurringInvoice::FREQUENCY_TWO_MONTHS: - return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(2)->startOfDay(); + return Carbon::parse($date)->addMonthsNoOverflow(2)->startOfDay(); case RecurringInvoice::FREQUENCY_THREE_MONTHS: - return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(3)->startOfDay(); + return Carbon::parse($date)->addMonthsNoOverflow(3)->startOfDay(); case RecurringInvoice::FREQUENCY_FOUR_MONTHS: - return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(4)->startOfDay(); + return Carbon::parse($date)->addMonthsNoOverflow(4)->startOfDay(); case RecurringInvoice::FREQUENCY_SIX_MONTHS: - return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(6)->startOfDay(); + return Carbon::parse($date)->addMonthsNoOverflow(6)->startOfDay(); case RecurringInvoice::FREQUENCY_ANNUALLY: - return Carbon::parse($this->next_send_date)->addYear()->startOfDay(); + return Carbon::parse($date)->addYear()->startOfDay(); case RecurringInvoice::FREQUENCY_TWO_YEARS: - return Carbon::parse($this->next_send_date)->addYears(2)->startOfDay(); + return Carbon::parse($date)->addYears(2)->startOfDay(); case RecurringInvoice::FREQUENCY_THREE_YEARS: - return Carbon::parse($this->next_send_date)->addYears(3)->startOfDay(); + return Carbon::parse($date)->addYears(3)->startOfDay(); default: return null; } diff --git a/app/Utils/Traits/QuoteEmailBuilder.php b/app/Utils/Traits/QuoteEmailBuilder.php index 230f3f817bd5..a87a1fb1cdf5 100644 --- a/app/Utils/Traits/QuoteEmailBuilder.php +++ b/app/Utils/Traits/QuoteEmailBuilder.php @@ -30,11 +30,10 @@ trait QuoteEmailBuilder */ public function getEmailData($reminder_template = null, $contact = null) :array { - //client - //$client = $this->client; - if (! $reminder_template) { - $reminder_template = $this->calculateTemplate('quote'); + $reminder_template = 'quote'; + + //$reminder_template = $this->calculateTemplate('quote'); } //Need to determine which email template we are producing diff --git a/tests/Integration/CheckRemindersTest.php b/tests/Integration/CheckRemindersTest.php index 7e74f3a1cfe2..580435ed830a 100644 --- a/tests/Integration/CheckRemindersTest.php +++ b/tests/Integration/CheckRemindersTest.php @@ -114,9 +114,6 @@ class CheckRemindersTest extends TestCase $settings->enable_reminder1 = true; $settings->schedule_reminder1 = 'after_invoice_date'; $settings->num_days_reminder1 = 50; - $settings->enable_reminder2 = false; - $settings->schedule_reminder2 = 'before_due_date'; - $settings->num_days_reminder2 = 50; $settings->enable_reminder3 = true; $settings->schedule_reminder3 = 'after_due_date'; $settings->num_days_reminder3 = 1; @@ -136,13 +133,13 @@ class CheckRemindersTest extends TestCase $settings = $this->company->settings; $settings->enable_reminder1 = false; $settings->schedule_reminder1 = 'after_invoice_date'; - $settings->num_days_reminder1 = 50; + $settings->num_days_reminder1 = 0; $settings->enable_reminder2 = false; $settings->schedule_reminder2 = 'before_due_date'; - $settings->num_days_reminder2 = 50; + $settings->num_days_reminder2 = 0; $settings->enable_reminder3 = false; $settings->schedule_reminder3 = 'after_due_date'; - $settings->num_days_reminder3 = 1; + $settings->num_days_reminder3 = 0; $this->company->settings = $settings; $this->invoice->service()->markSent();