1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 13:12:50 +01:00

Reduce notification emails to one per entity

This commit is contained in:
David Bomba 2020-12-09 20:52:08 +11:00
parent b74d80e091
commit 7ba78cc342
9 changed files with 154 additions and 35 deletions

View File

@ -13,6 +13,7 @@ namespace App\Events\Quote;
use App\Models\Company;
use App\Models\Quote;
use App\Models\QuoteInvitation;
use Illuminate\Queue\SerializesModels;
/**
@ -22,7 +23,7 @@ class QuoteWasEmailed
{
use SerializesModels;
public $quote;
public $invitation;
public $company;
@ -38,9 +39,9 @@ class QuoteWasEmailed
* @param Company $company
* @param array $event_vars
*/
public function __construct(Quote $quote, string $notes, Company $company, array $event_vars)
public function __construct(QuoteInvitation $invitation, string $notes, Company $company, array $event_vars)
{
$this->quote = $quote;
$this->invitation = $invitation;
$this->notes = $notes;
$this->company = $company;
$this->event_vars = $event_vars;

View File

@ -11,6 +11,7 @@
namespace App\Http\Controllers;
use App\Events\Quote\QuoteWasEmailed;
use App\Http\Requests\Email\SendEmailRequest;
use App\Jobs\Entity\EmailEntity;
use App\Jobs\Mail\EntitySentMailer;
@ -22,6 +23,7 @@ use App\Transformers\CreditTransformer;
use App\Transformers\InvoiceTransformer;
use App\Transformers\QuoteTransformer;
use App\Transformers\RecurringInvoiceTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Response;
@ -117,6 +119,7 @@ class EmailController extends BaseController
$template = $request->input('template');
$template = str_replace("email_template_", "", $template);
$entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj, $template) {
if ($invitation->contact->send_email && $invitation->contact->email) {
$data = [
@ -138,11 +141,19 @@ class EmailController extends BaseController
if ($entity_obj instanceof Invoice) {
$this->entity_type = Invoice::class;
$this->entity_transformer = InvoiceTransformer::class;
if($entity_obj->invitations->count() >= 1)
$entity_obj->entityEmailEvent($entity_obj->invitations->first(), 'invoice');
}
if ($entity_obj instanceof Quote) {
$this->entity_type = Quote::class;
$this->entity_transformer = QuoteTransformer::class;
if($entity_obj->invitations->count() >= 1)
event(new QuoteWasEmailed($entity_obj->invitations->first(), '', $entity_obj->company, Ninja::eventVars()));
}
if ($entity_obj instanceof Credit) {
@ -155,7 +166,6 @@ class EmailController extends BaseController
$this->entity_transformer = RecurringInvoiceTransformer::class;
}
$entity_obj->service()->markSent()->save();
return $this->itemResponse($entity_obj);

View File

@ -12,7 +12,9 @@
namespace App\Http\Controllers;
use App\Events\Invoice\InvoiceReminderWasEmailed;
use App\Events\Invoice\InvoiceWasCreated;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Invoice\InvoiceWasUpdated;
use App\Factory\CloneInvoiceFactory;
use App\Factory\CloneInvoiceToQuoteFactory;
@ -29,6 +31,7 @@ use App\Jobs\Entity\EmailEntity;
use App\Jobs\Invoice\StoreInvoice;
use App\Jobs\Invoice\ZipInvoices;
use App\Jobs\Util\UnlinkFile;
use App\Models\Activity;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\Quote;
@ -721,14 +724,15 @@ class InvoiceController extends BaseController
}
//touch reminder1,2,3_sent + last_sent here if the email is a reminder.
$invoice->service()->touchReminder($this->reminder_template)->save();
$invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($invoice) {
info("firing email");
EmailEntity::dispatch($invitation, $invoice->company, $this->reminder_template);
});
if($invoice->invitations->count() >= 1)
$invoice->entityEmailEvent($invoice->invitations->first(), $this->reminder_template);
if (! $bulk) {
return response()->json(['message' => 'email sent'], 200);
}

View File

@ -56,6 +56,7 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
public $email_entity_builder;
public $template_data;
/**
* EmailEntity constructor.
* @param Invitation $invitation
@ -100,7 +101,7 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
$this->setMailDriver();
try {
/** @noinspection PhpMethodParametersCountMismatchInspection */
Mail::to($this->invitation->contact->email, $this->invitation->contact->present()->name())
->send(
new TemplateEmail(
@ -115,9 +116,9 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
$this->logMailError($e->getMessage(), $this->entity->client);
}
if (count(Mail::failures()) == 0) {
$this->entityEmailSucceeded();
}
// if (count(Mail::failures()) == 0) {
// $this->entityEmailSucceeded();
// }
/* Mark entity sent */
$this->entity->service()->markSent()->save();
@ -149,29 +150,29 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
}
}
private function entityEmailSucceeded()
{
switch ($this->reminder_template) {
case 'invoice':
event(new InvoiceWasEmailed($this->invitation, $this->company, Ninja::eventVars()));
break;
case 'reminder1':
event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER1_SENT));
break;
case 'reminder2':
event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER2_SENT));
break;
case 'reminder3':
event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER3_SENT));
break;
case 'reminder_endless':
event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER_ENDLESS_SENT));
break;
default:
# code...
break;
}
}
// private function entityEmailSucceeded()
// {
// switch ($this->reminder_template) {
// case 'invoice':
// event(new InvoiceWasEmailed($this->invitation, $this->company, Ninja::eventVars()));
// break;
// case 'reminder1':
// event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER1_SENT));
// break;
// case 'reminder2':
// event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER2_SENT));
// break;
// case 'reminder3':
// event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER3_SENT));
// break;
// case 'reminder_endless':
// event(new InvoiceReminderWasEmailed($this->invitation, $this->company, Ninja::eventVars(), Activity::INVOICE_REMINDER_ENDLESS_SENT));
// break;
// default:
// # code...
// break;
// }
// }
private function resolveEmailBuilder()
{

View File

@ -0,0 +1,63 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Quote;
use App\Jobs\Mail\EntitySentMailer;
use App\Libraries\MultiDB;
use App\Notifications\Admin\EntitySentNotification;
use App\Utils\Traits\Notifications\UserNotifies;
use Illuminate\Contracts\Queue\ShouldQueue;
class QuoteEmailedNotification implements ShouldQueue
{
use UserNotifies;
public function __construct()
{
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$first_notification_sent = true;
$quote = $event->invitation->quote;
$quote->last_sent_date = now();
$quote->save();
foreach ($event->invitation->company->company_users as $company_user) {
$user = $company_user->user;
$notification = new EntitySentNotification($event->invitation, 'quote');
$methods = $this->findUserNotificationTypes($event->invitation, $company_user, 'quote', ['all_notifications', 'quote_sent']);
if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
unset($methods[$key]);
EntitySentMailer::dispatch($event->invitation, 'quote', $user, $event->invitation->company);
$first_notification_sent = false;
}
$notification->method = $methods;
$user->notify($notification);
}
}
}

View File

@ -11,10 +11,13 @@
namespace App\Models;
use App\Events\Invoice\InvoiceReminderWasEmailed;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Invoice\InvoiceWasUpdated;
use App\Helpers\Invoice\InvoiceSum;
use App\Helpers\Invoice\InvoiceSumInclusive;
use App\Jobs\Entity\CreateEntityPdf;
use App\Models\Activity;
use App\Models\Presenters\InvoicePresenter;
use App\Services\Invoice\InvoiceService;
use App\Services\Ledger\LedgerService;
@ -431,4 +434,30 @@ class Invoice extends BaseModel
{
return $this->calc()->getTotal();
}
public function entityEmailEvent($invitation, $reminder_template)
{
switch ($reminder_template) {
case 'invoice':
event(new InvoiceWasEmailed($invitation, $invitation->company, Ninja::eventVars()));
break;
case 'reminder1':
event(new InvoiceReminderWasEmailed($invitation, $invitation->company, Ninja::eventVars(), Activity::INVOICE_REMINDER1_SENT));
break;
case 'reminder2':
event(new InvoiceReminderWasEmailed($invitation, $invitation->company, Ninja::eventVars(), Activity::INVOICE_REMINDER2_SENT));
break;
case 'reminder3':
event(new InvoiceReminderWasEmailed($invitation, $invitation->company, Ninja::eventVars(), Activity::INVOICE_REMINDER3_SENT));
break;
case 'reminder_endless':
event(new InvoiceReminderWasEmailed($invitation, $invitation->company, Ninja::eventVars(), Activity::INVOICE_REMINDER_ENDLESS_SENT));
break;
default:
# code...
break;
}
}
}

View File

@ -120,8 +120,8 @@ use App\Listeners\Invoice\InvoiceArchivedActivity;
use App\Listeners\Invoice\InvoiceCancelledActivity;
use App\Listeners\Invoice\InvoiceDeletedActivity;
use App\Listeners\Invoice\InvoiceEmailActivity;
use App\Listeners\Invoice\InvoiceEmailedNotification;
use App\Listeners\Invoice\InvoiceEmailFailedActivity;
use App\Listeners\Invoice\InvoiceEmailedNotification;
use App\Listeners\Invoice\InvoicePaidActivity;
use App\Listeners\Invoice\InvoiceReminderEmailActivity;
use App\Listeners\Invoice\InvoiceRestoredActivity;
@ -129,14 +129,15 @@ use App\Listeners\Invoice\InvoiceReversedActivity;
use App\Listeners\Invoice\InvoiceViewedActivity;
use App\Listeners\Invoice\UpdateInvoiceActivity;
use App\Listeners\Misc\InvitationViewedListener;
use App\Listeners\Payment\PaymentEmailedActivity;
use App\Listeners\Payment\PaymentEmailFailureActivity;
use App\Listeners\Payment\PaymentEmailedActivity;
use App\Listeners\Payment\PaymentNotification;
use App\Listeners\Payment\PaymentRestoredActivity;
use App\Listeners\Quote\QuoteApprovedActivity;
use App\Listeners\Quote\QuoteArchivedActivity;
use App\Listeners\Quote\QuoteDeletedActivity;
use App\Listeners\Quote\QuoteEmailActivity;
use App\Listeners\Quote\QuoteEmailedNotification;
use App\Listeners\Quote\QuoteRestoredActivity;
use App\Listeners\Quote\QuoteViewedActivity;
use App\Listeners\Quote\ReachWorkflowSettings;
@ -332,6 +333,7 @@ class EventServiceProvider extends ServiceProvider
],
QuoteWasEmailed::class => [
QuoteEmailActivity::class,
QuoteEmailedNotification::class,
],
QuoteWasViewed::class => [
QuoteViewedActivity::class,

View File

@ -209,4 +209,7 @@ trait MakesReminders
return null;
}
}
}

View File

@ -3314,4 +3314,10 @@ return [
'service' => 'Service',
'pay' => 'Pay',
'notification_invoice_reminder1_sent_subject' => 'Reminder 1 for Invoice :invoice was sent to :client',
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
'notification_invoice_reminder_endless_sent_subject' => 'Endless reminder for Invoice :invoice was sent to :client',
];