mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Minor refactors for emails (#3333)
This commit is contained in:
parent
a79c7bf60d
commit
1e0111d519
@ -3,6 +3,9 @@
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceInvitationFactory;
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
@ -54,6 +57,8 @@ class SendTestEmails extends Command
|
||||
|
||||
private function sendTemplateEmails($template)
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
|
||||
$message = [
|
||||
'title' => 'Invoice XJ-3838',
|
||||
'body' => '<div>"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</div>',
|
||||
@ -62,19 +67,26 @@ class SendTestEmails extends Command
|
||||
];
|
||||
|
||||
$user = User::whereEmail('user@example.com')->first();
|
||||
|
||||
$account = factory(\App\Models\Account::class)->create();
|
||||
|
||||
$company = factory(\App\Models\Company::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$client = Client::all()->first();
|
||||
|
||||
if (!$user) {
|
||||
$user = factory(\App\Models\User::class)->create([
|
||||
'confirmation_code' => '123',
|
||||
'email' => 'admin@business.com',
|
||||
'email' => $faker->safeEmail,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$client) {
|
||||
$client = ClientFactory::create($user->company()->id, $user->id);
|
||||
$client = ClientFactory::create($company->id, $user->id);
|
||||
$client->save();
|
||||
|
||||
factory(\App\Models\ClientContact::class, 1)->create([
|
||||
@ -83,7 +95,7 @@ class SendTestEmails extends Command
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1,
|
||||
'send_invoice' => true,
|
||||
'email' => 'exy@example.com',
|
||||
'email' => $faker->safeEmail,
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class, 1)->create([
|
||||
@ -91,17 +103,33 @@ class SendTestEmails extends Command
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $company->id,
|
||||
'send_invoice' => true,
|
||||
'email' => 'exy2@example.com',
|
||||
'email' => $faker->safeEmail,
|
||||
]);
|
||||
}
|
||||
|
||||
$invoice = InvoiceFactory::create($company->id, $user->id);
|
||||
$invoice->client_id = $client->id;
|
||||
$invoice->setRelation('client', $client);
|
||||
$invoice->save();
|
||||
|
||||
$ii = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
|
||||
$ii->invoice_id = $invoice->id;
|
||||
$ii->client_contact_id = $client->primary_contact()->first()->id;
|
||||
$ii->save();
|
||||
|
||||
$invoice->setRelation('invitations', $ii);
|
||||
|
||||
$invoice->save();
|
||||
|
||||
$cc_emails = [config('ninja.testvars.test_email')];
|
||||
$bcc_emails = [config('ninja.testvars.test_email')];
|
||||
|
||||
$email_builder = (new InvoiceEmail())->build($invoice, null, $client->primary_contact()->first());
|
||||
|
||||
Mail::to(config('ninja.testvars.test_email'), 'Mr Test')
|
||||
->cc($cc_emails)
|
||||
->bcc($bcc_emails)
|
||||
//->replyTo(also_available_if_needed)
|
||||
->send(new TemplateEmail($message, $template, $user, $client));
|
||||
->send(new TemplateEmail($email_builder, $user, $client));
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,14 @@ use App\Models\Invoice;
|
||||
|
||||
class InvoiceEmail extends EmailBuilder
|
||||
{
|
||||
|
||||
public function build(Invoice $invoice, $reminder_template, $contact = null)
|
||||
{
|
||||
$client = $invoice->client;
|
||||
|
||||
if(!$reminder_template)
|
||||
$reminder_template = $invoice->calculateTemplate();
|
||||
|
||||
$body_template = $client->getSetting('email_template_' . $reminder_template);
|
||||
|
||||
/* Use default translations if a custom message has not been set*/
|
||||
@ -32,7 +36,7 @@ class InvoiceEmail extends EmailBuilder
|
||||
if ($reminder_template == 'quote') {
|
||||
$subject_template = trans('texts.invoice_subject',
|
||||
[
|
||||
'number' => $this->invoice->present()->invoice_number(),
|
||||
'number' => $invoice->present()->invoice_number(),
|
||||
'company' => $invoice->company->present()->name()
|
||||
],
|
||||
null, $invoice->client->locale());
|
||||
|
@ -36,6 +36,7 @@ class EmailInvoice implements ShouldQueue
|
||||
public function __construct(InvoiceEmail $email_builder, InvoiceInvitation $invoice_invitation)
|
||||
{
|
||||
$this->invoice_invitation = $invoice_invitation;
|
||||
|
||||
$this->email_builder = $email_builder;
|
||||
}
|
||||
|
||||
@ -49,18 +50,17 @@ class EmailInvoice implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$email_builder = $this->email_builder;
|
||||
|
||||
Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name())
|
||||
->send(new TemplateEmail($email_builder,
|
||||
->send(new TemplateEmail($this->email_builder,
|
||||
$this->invoice_invitation->contact->user,
|
||||
$this->invoice_invitation->contact->client
|
||||
)
|
||||
);
|
||||
|
||||
if (count(Mail::failures()) > 0) {
|
||||
return $this->logMailError($errors);
|
||||
return $this->logMailError(Mail::failures());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function logMailError($errors)
|
||||
|
@ -52,16 +52,15 @@ class EmailPayment implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$email_builder = $this->email_builder;
|
||||
|
||||
if ($this->contact->email) {
|
||||
Mail::to($this->contact->email, $this->contact->present()->name())
|
||||
->send(new TemplateEmail($email_builder, $this->contact->user, $this->contact->customer));
|
||||
->send(new TemplateEmail($this->email_builder, $this->contact->user, $this->contact->customer));
|
||||
|
||||
if (count(Mail::failures()) > 0) {
|
||||
event(new PaymentWasEmailedAndFailed($this->payment, Mail::failures()));
|
||||
|
||||
return $this->logMailError($errors);
|
||||
return $this->logMailError(Mail::failures());
|
||||
}
|
||||
|
||||
//fire any events
|
||||
|
@ -47,17 +47,16 @@ class EmailQuote implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$email_builder = $this->email_builder;
|
||||
|
||||
Mail::to($this->quote_invitation->contact->email, $this->quote_invitation->contact->present()->name())
|
||||
->send(new TemplateEmail($email_builder,
|
||||
->send(new TemplateEmail($this->email_builder,
|
||||
$this->quote_invitation->contact->user,
|
||||
$this->quote_invitation->contact->client
|
||||
)
|
||||
);
|
||||
|
||||
if (count(Mail::failures()) > 0) {
|
||||
return $this->logMailError($errors);
|
||||
return $this->logMailError(Mail::failures());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
@ -9,16 +11,24 @@ use Illuminate\Queue\SerializesModels;
|
||||
class TemplateEmail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
private $build_email; //the message array // ['body', 'footer', 'title', 'files']
|
||||
|
||||
private $build_email;
|
||||
|
||||
private $user; //the user the email will be sent from
|
||||
private $customer;
|
||||
|
||||
private $client;
|
||||
|
||||
private $footer;
|
||||
|
||||
public function __construct($build_email, $user, $customer)
|
||||
public function __construct($build_email, User $user, Client $client)
|
||||
{
|
||||
|
||||
$this->build_email = $build_email;
|
||||
|
||||
$this->user = $user; //this is inappropriate here, need to refactor 'user' in this context the 'user' could also be the 'system'
|
||||
$this->customer = $customer;
|
||||
|
||||
$this->client = $client;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,17 +39,20 @@ class TemplateEmail extends Mailable
|
||||
public function build()
|
||||
{
|
||||
/*Alter Run Time Mailer configuration (driver etc etc) to regenerate the Mailer Singleton*/
|
||||
|
||||
//if using a system level template
|
||||
$template_name = 'email.template.' . $this->build_email->getTemplate();
|
||||
|
||||
$settings = $this->customer->getMergedSettings();
|
||||
\Log::error(print_r($settings, 1));
|
||||
$company = $this->customer->account;
|
||||
$settings = $this->client->getMergedSettings();
|
||||
|
||||
$message = $this->from($this->user->email,
|
||||
$this->user->present()->name())//todo this needs to be fixed to handle the hosted version
|
||||
->subject($this->build_email->getSubject())
|
||||
->text('email.template.plain', ['body' => $this->build_email->getBody(), 'footer' => $this->build_email->getFooter()])
|
||||
$company = $this->client->company;
|
||||
|
||||
$message = $this->from($this->user->email,$this->user->present()->name())//todo this needs to be fixed to handle the hosted version
|
||||
->subject($this->build_email->getSubject())
|
||||
->text('email.template.plain', [
|
||||
'body' => $this->build_email->getBody(),
|
||||
'footer' => $this->build_email->getFooter()
|
||||
])
|
||||
->view($template_name, [
|
||||
'body' => $this->build_email->getBody(),
|
||||
'footer' => $this->build_email->getFooter(),
|
||||
|
@ -42,7 +42,7 @@ class SendEmail
|
||||
|
||||
$this->invoice->invitations->each(function ($invitation) use ($email_builder) {
|
||||
if ($invitation->contact->send_invoice && $invitation->contact->email) {
|
||||
EmailInvoice::dispatchNow($email_builder, $invitation);
|
||||
EmailInvoice::dispatch($email_builder, $invitation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -98,42 +98,42 @@ trait InvoiceEmailBuilder
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function calculateTemplate() :string
|
||||
{
|
||||
//if invoice is currently a draft, or being marked as sent, this will be the initial email
|
||||
$client = $this->client;
|
||||
// private function calculateTemplate() :string
|
||||
// {
|
||||
// //if invoice is currently a draft, or being marked as sent, this will be the initial email
|
||||
// $client = $this->client;
|
||||
|
||||
//if the invoice
|
||||
if ($this->status_id == Invoice::STATUS_DRAFT || Carbon::parse($this->due_date) > now()) {
|
||||
return 'invoice';
|
||||
} elseif ($client->getSetting('enable_reminder1') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder1'), $client->getSetting('num_days_reminder1'))) {
|
||||
return 'template1';
|
||||
} elseif ($client->getSetting('enable_reminder2') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder2'), $client->getSetting('num_days_reminder2'))) {
|
||||
return 'template2';
|
||||
} elseif ($client->getSetting('enable_reminder3') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder3'), $client->getSetting('num_days_reminder3'))) {
|
||||
return 'template3';
|
||||
} else {
|
||||
return 'invoice';
|
||||
}
|
||||
// //if the invoice
|
||||
// if ($this->status_id == Invoice::STATUS_DRAFT || Carbon::parse($this->due_date) > now()) {
|
||||
// return 'invoice';
|
||||
// } elseif ($client->getSetting('enable_reminder1') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder1'), $client->getSetting('num_days_reminder1'))) {
|
||||
// return 'template1';
|
||||
// } elseif ($client->getSetting('enable_reminder2') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder2'), $client->getSetting('num_days_reminder2'))) {
|
||||
// return 'template2';
|
||||
// } elseif ($client->getSetting('enable_reminder3') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder3'), $client->getSetting('num_days_reminder3'))) {
|
||||
// return 'template3';
|
||||
// } else {
|
||||
// return 'invoice';
|
||||
// }
|
||||
|
||||
//also implement endless reminders here
|
||||
}
|
||||
// //also implement endless reminders here
|
||||
// }
|
||||
|
||||
private function inReminderWindow($schedule_reminder, $num_days_reminder)
|
||||
{
|
||||
switch ($schedule_reminder) {
|
||||
case 'after_invoice_date':
|
||||
return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
break;
|
||||
case 'before_due_date':
|
||||
return Carbon::parse($this->due_date)->subDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
break;
|
||||
case 'after_due_date':
|
||||
return Carbon::parse($this->due_date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
break;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
// private function inReminderWindow($schedule_reminder, $num_days_reminder)
|
||||
// {
|
||||
// switch ($schedule_reminder) {
|
||||
// case 'after_invoice_date':
|
||||
// return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
// break;
|
||||
// case 'before_due_date':
|
||||
// return Carbon::parse($this->due_date)->subDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
// break;
|
||||
// case 'after_due_date':
|
||||
// return Carbon::parse($this->due_date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||
// break;
|
||||
// default:
|
||||
// # code...
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -186,17 +186,17 @@ trait MakesReminders
|
||||
public function calculateTemplate(): string
|
||||
{
|
||||
//if invoice is currently a draft, or being marked as sent, this will be the initial email
|
||||
$customer = $this->client;
|
||||
$client = $this->client;
|
||||
|
||||
//if the invoice
|
||||
if ($customer->getSetting('enable_reminder1') !== false && $this->inReminderWindow($customer->getSetting('schedule_reminder1'),
|
||||
$customer->getSetting('num_days_reminder1'))) {
|
||||
if ($client->getSetting('enable_reminder1') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder1'),
|
||||
$client->getSetting('num_days_reminder1'))) {
|
||||
return 'template1';
|
||||
} elseif ($customer->getSetting('enable_reminder2') !== false && $this->inReminderWindow($customer->getSetting('schedule_reminder2'),
|
||||
$customer->getSetting('num_days_reminder2'))) {
|
||||
} elseif ($client->getSetting('enable_reminder2') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder2'),
|
||||
$client->getSetting('num_days_reminder2'))) {
|
||||
return 'template2';
|
||||
} elseif ($customer->getSetting('enable_reminder3') !== false && $this->inReminderWindow($customer->getSetting('schedule_reminder3'),
|
||||
$customer->getSetting('num_days_reminder3'))) {
|
||||
} elseif ($client->getSetting('enable_reminder3') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder3'),
|
||||
$client->getSetting('num_days_reminder3'))) {
|
||||
return 'template3';
|
||||
} else {
|
||||
return 'invoice';
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Feature;
|
||||
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Jobs\Invoice\EmailInvoice;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Invoice;
|
||||
@ -42,63 +44,29 @@ class InvoiceEmailTest extends TestCase
|
||||
public function test_initial_email_sends()
|
||||
{
|
||||
|
||||
// \Log::error($this->invoice->makeValues());
|
||||
|
||||
$this->invoice->date = now();
|
||||
$this->invoice->due_date = now()->addDays(7);
|
||||
$this->invoice->number = $this->getNextInvoiceNumber($this->client);
|
||||
|
||||
$this->invoice->client = $this->client;
|
||||
|
||||
$message_array = $this->invoice->getEmailData();
|
||||
$message_array['title'] = &$message_array['subject'];
|
||||
$message_array['footer'] = 'The Footer';
|
||||
|
||||
|
||||
// $template_style = $this->client->getSetting('email_style');
|
||||
|
||||
$template_style = 'light';
|
||||
//iterate through the senders list and send from here
|
||||
$this->invoice->client_id = $this->client->id;
|
||||
$this->invoice->setRelation('client', $this->client);
|
||||
$this->invoice->save();
|
||||
|
||||
$invitations = InvoiceInvitation::whereInvoiceId($this->invoice->id)->get();
|
||||
|
||||
$invitations->each(function($invitation) use($message_array, $template_style) {
|
||||
$email_builder = (new InvoiceEmail())->build($this->invoice, null, null);
|
||||
|
||||
$contact = $invitation->contact;
|
||||
$invitations->each(function ($invitation) use ($email_builder) {
|
||||
|
||||
if($contact->send_invoice && $contact->email)
|
||||
{
|
||||
//there may be template variables left over for the specific contact? need to reparse here
|
||||
|
||||
//change the runtime config of the mail provider here:
|
||||
|
||||
//send message
|
||||
Mail::to($contact->email)
|
||||
->send(new TemplateEmail($message_array, $template_style, $this->user, $contact->client));
|
||||
if ($invitation->contact->send_invoice && $invitation->contact->email) {
|
||||
|
||||
//fire any events
|
||||
|
||||
EmailInvoice::dispatch($email_builder, $invitation);
|
||||
|
||||
$this->expectsJobs(EmailInvoice::class);
|
||||
|
||||
//sleep(5);//here to cope with mailtrap time delays
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -212,6 +212,13 @@ trait MockAccountData
|
||||
|
||||
});
|
||||
|
||||
$invitations = InvoiceInvitation::whereCompanyId($this->invoice->company_id)
|
||||
->whereInvoiceId($this->invoice->id);
|
||||
|
||||
$this->invoice->setRelation('invitations', $invitations);
|
||||
|
||||
$this->invoice->save();
|
||||
|
||||
UpdateCompanyLedgerWithInvoice::dispatchNow($this->invoice, $this->invoice->amount, $this->invoice->company);
|
||||
|
||||
$recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
|
||||
|
Loading…
x
Reference in New Issue
Block a user