From cfbf6e8f4eafcd61c4814caf5bee8649a944033a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 19 Jan 2021 20:16:29 +1100 Subject: [PATCH] Working on email failure notifications --- app/Jobs/Mail/EntityFailedSendMailer.php | 99 +++++++++++++ .../InvoiceFailedEmailNotification.php | 63 ++++++++ app/Mail/Admin/EntityFailedSendObject.php | 140 ++++++++++++++++++ app/Mail/Admin/EntitySentObject.php | 3 +- resources/lang/en/texts.php | 2 + 5 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 app/Jobs/Mail/EntityFailedSendMailer.php create mode 100644 app/Listeners/Invoice/InvoiceFailedEmailNotification.php create mode 100644 app/Mail/Admin/EntityFailedSendObject.php diff --git a/app/Jobs/Mail/EntityFailedSendMailer.php b/app/Jobs/Mail/EntityFailedSendMailer.php new file mode 100644 index 000000000000..4f4b5f7a2354 --- /dev/null +++ b/app/Jobs/Mail/EntityFailedSendMailer.php @@ -0,0 +1,99 @@ +company = $company; + + $this->user = $user; + + $this->invitation = $invitation; + + $this->entity = $invitation->{$entity_type}; + + $this->entity_type = $entity_type; + + $this->settings = $invitation->contact->client->getMergedSettings(); + + $this->template = $template; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + nlog("entity sent mailer"); + + /*If we are migrating data we don't want to fire these notification*/ + if ($this->company->is_disabled) { + return true; + } + + //Set DB + MultiDB::setDb($this->company->db); + + //if we need to set an email driver do it now + $this->setMailDriver(); + + $mail_obj = (new EntitySentObject($this->invitation, $this->entity_type, $this->template))->build(); + $mail_obj->from = [config('mail.from.address'), config('mail.from.name')]; + + try { + Mail::to($this->user->email) + ->send(new EntityNotificationMailer($mail_obj)); + } catch (\Exception $e) { + $this->failed($e); + $this->logMailError($e->getMessage(), $this->entity->client); + } + } +} diff --git a/app/Listeners/Invoice/InvoiceFailedEmailNotification.php b/app/Listeners/Invoice/InvoiceFailedEmailNotification.php new file mode 100644 index 000000000000..8c55ce5520b8 --- /dev/null +++ b/app/Listeners/Invoice/InvoiceFailedEmailNotification.php @@ -0,0 +1,63 @@ +company->db); + + $first_notification_sent = true; + + $invoice = $event->invitation->invoice; + $invoice->last_sent_date = now(); + $invoice->save(); + + foreach ($event->invitation->company->company_users as $company_user) { + $user = $company_user->user; + + $notification = new EntitySentNotification($event->invitation, 'invoice'); + + $methods = $this->findUserNotificationTypes($event->invitation, $company_user, 'invoice', ['all_notifications', 'invoice_sent']); + + if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) { + unset($methods[$key]); + + EntitySentMailer::dispatch($event->invitation, 'invoice', $user, $event->invitation->company, $event->template); + $first_notification_sent = false; + } + + $notification->method = $methods; + + $user->notify($notification); + } + } +} diff --git a/app/Mail/Admin/EntityFailedSendObject.php b/app/Mail/Admin/EntityFailedSendObject.php new file mode 100644 index 000000000000..7ef6ee23f9b3 --- /dev/null +++ b/app/Mail/Admin/EntityFailedSendObject.php @@ -0,0 +1,140 @@ +invitation = $invitation; + $this->entity_type = $entity_type; + $this->entity = $invitation->{$entity_type}; + $this->contact = $invitation->contact; + $this->company = $invitation->company; + $this->template = $template; + } + + public function build() + { + $this->setTemplate(); + + $mail_obj = new stdClass; + $mail_obj->amount = $this->getAmount(); + $mail_obj->subject = $this->getSubject(); + $mail_obj->data = $this->getData(); + $mail_obj->markdown = 'email.admin.generic'; + $mail_obj->tag = $this->company->company_key; + + return $mail_obj; + } + + private function setTemplate() + { + // nlog($this->template); + + switch ($this->template) { + case 'invoice': + $this->template_subject = "texts.notification_invoice_bounced_subject"; + $this->template_body = "texts.notification_invoice_bounced"; + break; + case 'reminder1': + $this->template_subject = "texts.notification_invoice_reminder1_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder2': + $this->template_subject = "texts.notification_invoice_reminder2_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder3': + $this->template_subject = "texts.notification_invoice_reminder3_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder_endless': + $this->template_subject = "texts.notification_invoice_reminder_endless_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'quote': + $this->template_subject = "texts.notification_quote_bounced_subject"; + $this->template_body = "texts.notification_quote_sent"; + break; + case 'credit': + $this->template_subject = "texts.notification_credit_bounced_subject"; + $this->template_body = "texts.notification_credit_bounced"; + break; + default: + $this->template_subject = "texts.notification_invoice_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + } + } + + private function getAmount() + { + return Number::formatMoney($this->entity->amount, $this->entity->client); + } + + private function getSubject() + { + return + ctrans( + $this->template_subject, + [ + 'client' => $this->contact->present()->name(), + 'invoice' => $this->entity->number, + ] + ); + } + + private function getData() + { + $settings = $this->entity->client->getMergedSettings(); + + return [ + 'title' => $this->getSubject(), + 'message' => ctrans( + $this->template_body, + [ + 'amount' => $this->getAmount(), + 'client' => $this->contact->present()->name(), + 'invoice' => $this->entity->number, + ] + ), + 'url' => $this->invitation->getAdminLink(), + 'button' => ctrans("texts.view_{$this->entity_type}"), + 'signature' => $settings->email_signature, + 'logo' => $this->company->present()->logo(), + 'settings' => $settings, + 'whitelabel' => $this->company->account->isPaid() ? true : false, + ]; + } +} diff --git a/app/Mail/Admin/EntitySentObject.php b/app/Mail/Admin/EntitySentObject.php index 3e0f9c8f76e2..ad7da9877e60 100644 --- a/app/Mail/Admin/EntitySentObject.php +++ b/app/Mail/Admin/EntitySentObject.php @@ -14,7 +14,7 @@ namespace App\Mail\Admin; use App\Utils\Number; use stdClass; -class EntitySentObject +class EntityFailedSendObject { public $invitation; @@ -91,7 +91,6 @@ class EntitySentObject $this->template_subject = "texts.notification_credit_sent_subject"; $this->template_body = "texts.notification_credit_sent"; break; - default: $this->template_subject = "texts.notification_invoice_sent_subject"; $this->template_body = "texts.notification_invoice_sent"; diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index f89dd1350aa9..1dda79726715 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -3371,4 +3371,6 @@ return [ 'required_payment_information_more' => 'To complete a payment we need more details about you.', 'required_client_info_save_label' => 'We will save this, so you don\'t have to enter it next time.', + 'notification_credit_bounced' => 'We were unable to deliver Credit :invoice to :contact.', + 'notification_credit_bounced_subject' => 'Unable to deliver Credit :invoice', ];