diff --git a/app/Helpers/Email/EmailBuilder.php b/app/Helpers/Email/EmailBuilder.php new file mode 100644 index 000000000000..b449e9f24905 --- /dev/null +++ b/app/Helpers/Email/EmailBuilder.php @@ -0,0 +1,154 @@ +variables)) { + $data = str_replace(array_keys($this->variables), array_values($this->variables), $data); + } + + //process markdown + if ($is_markdown) { + //$data = Parsedown::instance()->line($data); + + $converter = new CommonMarkConverter([ + 'html_input' => 'allow', + 'allow_unsafe_links' => true, + ]); + + $data = $converter->convertToHtml($data); + } + + return $data; + } + + /** + * @param $footer + * @return $this + */ + public function setFooter($footer) + { + $this->footer = $footer; + return $this; + } + + public function setVariables($variables) + { + $this->variables = $variables; + return $this; + } + + /** + * @param $contact + * @return $this + */ + public function setContact($contact) + { + $this->contact = $contact; + return $this; + } + + /** + * @param $subject + * @return $this + */ + public function setSubject($subject) + { + $this->subject = $this->parseTemplate($subject, false, $this->contact); + return $this; + } + + /** + * @param $body + * @return $this + */ + public function setBody($body) + { + $this->parseTemplate($body, true); + return $this; + } + + /** + * @param $template_style + * @return $this + */ + public function setTemplate($template_style) + { + $this->template_style = $template_style; + return $this; + } + + public function setAttachments($attachments) + { + $this->attachments[] = $attachments; + } + + + /** + * @return mixed + */ + public function getSubject() + { + return $this->subject; + } + + /** + * @return mixed + */ + public function getBody() + { + return $this->body; + } + + /** + * @return mixed + */ + public function getRecipients() + { + return $this->recipients; + } + + /** + * @return mixed + */ + public function getAttachments() + { + return $this->attachments; + } + + /** + * @return mixed + */ + public function getFooter() + { + return $this->footer; + } + + /** + * @return mixed + */ + public function getTemplate() + { + return $this->template_style; + } +} diff --git a/app/Helpers/Email/InvoiceEmail.php b/app/Helpers/Email/InvoiceEmail.php new file mode 100644 index 000000000000..835e24d28346 --- /dev/null +++ b/app/Helpers/Email/InvoiceEmail.php @@ -0,0 +1,61 @@ +client; + + $body_template = $client->getSetting('email_template_' . $reminder_template); + + /* Use default translations if a custom message has not been set*/ + if (iconv_strlen($body_template) == 0) { + $body_template = trans('texts.invoice_message', + ['amount' => $invoice->present()->amount(), 'company' => $invoice->company->present()->name()], null, + $invoice->client->locale()); + } + + $subject_template = $client->getSetting('email_subject_' . $reminder_template); + + if (iconv_strlen($subject_template) == 0) { + if ($reminder_template == 'quote') { + $subject_template = trans('texts.invoice_subject', + [ + 'number' => $this->invoice->present()->invoice_number(), + 'company' => $invoice->company->present()->name() + ], + null, $invoice->client->locale()); + } else { + $subject_template = trans('texts.reminder_subject', + [ + 'number' => $invoice->present()->invoice_number(), + 'company' => $invoice->company->present()->name() + ], + null, $invoice->client->locale()); + } + } + + $this->setTemplate($invoice->client->getSetting('email_style')) + ->setContact($contact) + ->setVariables($invoice->makeValues($contact)) + ->setSubject($subject_template) + ->setBody($body_template) + ->setFooter("Invoice Link"); + + if ($client->getSetting('pdf_email_attachment') !== false) { + $this->setAttachments($invoice->pdf_file_path()); + } + return $this; + } +} diff --git a/app/Helpers/Email/PaymentEmail.php b/app/Helpers/Email/PaymentEmail.php new file mode 100644 index 000000000000..5535a9811e13 --- /dev/null +++ b/app/Helpers/Email/PaymentEmail.php @@ -0,0 +1,43 @@ +client; + + $body_template = $client->getSetting('email_template_payment'); + + /* Use default translations if a custom message has not been set*/ + if (iconv_strlen($body_template) == 0) { + + $body_template = trans('texts.payment_message', + ['amount' => $payment->amount, 'company' => $payment->company->present()->name()], null, + $this->client->locale()); + } + + $subject_template = $client->getSetting('email_subject_payment'); + + if (iconv_strlen($subject_template) == 0) { + $subject_template = trans('texts.payment_subject', + ['number' => $payment->number, 'company' => $payment->company->present()->name()], null, + $payment->client->locale()); + } + + $this->setTemplate($payment->client->getSetting('email_style')) + ->setSubject($subject_template) + ->setBody($body_template); + + return $this; + } +} diff --git a/app/Helpers/Email/QuoteEmail.php b/app/Helpers/Email/QuoteEmail.php new file mode 100644 index 000000000000..a586199acaca --- /dev/null +++ b/app/Helpers/Email/QuoteEmail.php @@ -0,0 +1,58 @@ +client; + $this->template_style = $quote->client->getSetting('email_style'); + + $body_template = $client->getSetting('email_template_' . $reminder_template); + + /* Use default translations if a custom message has not been set*/ + if (iconv_strlen($body_template) == 0) { + $body_template = trans('texts.quote_message', + ['amount' => $quote->amount, 'company' => $quote->company->present()->name()], null, + $quote->client->locale()); + } + + $subject_template = $client->getSetting('email_subject_' . $reminder_template); + + if (iconv_strlen($subject_template) == 0) { + if ($reminder_template == 'quote') { + $subject_template = trans('texts.quote_subject', + ['number' => $quote->number, 'company' => $quote->company->present()->name()], + null, $quote->client->locale()); + } else { + $subject_template = trans('texts.reminder_subject', + ['number' => $quote->number, 'company' => $quote->company->present()->name()], + null, $quote->client->locale()); + } + } + + $this->setTemplate($quote->client->getSetting('email_style')) + ->setContact($contact) + ->setFooter("Invoice Link") + ->setVariables($quote->makeValues($contact)) + ->setSubject($subject_template) + ->setBody($body_template); + + if ($client->getSetting('pdf_email_attachment') !== false) { + $this->attachments = $quote->pdf_file_path(); + } + + return $this; + } +} diff --git a/app/Jobs/Invoice/EmailInvoice.php b/app/Jobs/Invoice/EmailInvoice.php index 791ed7dccdd9..c63450b5dd1f 100644 --- a/app/Jobs/Invoice/EmailInvoice.php +++ b/app/Jobs/Invoice/EmailInvoice.php @@ -1,50 +1,40 @@ invoice = $invoice; - - $this->company = $company; + $this->invoice_invitation = $invoice_invitation; + $this->email_builder = $email_builder; } /** @@ -53,46 +43,22 @@ class EmailInvoice implements ShouldQueue * * @return void */ + public function handle() { - /*Jobs are not multi-db aware, need to set! */ - MultiDB::setDB($this->company->db); + + $email_builder = $this->email_builder; - //todo - change runtime config of mail driver if necessary + Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name()) + ->send(new TemplateEmail($email_builder, + $this->invoice_invitation->contact->user, + $this->invoice_invitation->contact->client + ) + ); - $template_style = $this->invoice->client->getSetting('email_style'); - - $this->invoice->invitations->each(function ($invitation) use ($template_style) { - if ($invitation->contact->send_invoice && $invitation->contact->email) { - - $message_array = $this->invoice->getEmailData('', $invitation->contact); - - $message_array['title'] = &$message_array['subject']; - - //$message_array['footer'] = "Sent to ".$invitation->contact->present()->name(); - $message_array['footer'] = "Invoice Link"; - - //change the runtime config of the mail provider here: - - //send message - Mail::to($invitation->contact->email, $invitation->contact->present()->name()) - ->send(new TemplateEmail($message_array, - $template_style, - $invitation->contact->user, - $invitation->contact->client)); - - if (count(Mail::failures()) > 0) { - event(new InvoiceWasEmailedAndFailed($this->invoice, Mail::failures())); - - return $this->logMailError($errors); - } - - //fire any events - event(new InvoiceWasEmailed($this->invoice)); - - //sleep(5); - } - }); + if (count(Mail::failures()) > 0) { + return $this->logMailError($errors); + } } private function logMailError($errors) diff --git a/app/Jobs/Payment/EmailPayment.php b/app/Jobs/Payment/EmailPayment.php index dccb94d2bb0f..f8d58a3cead3 100644 --- a/app/Jobs/Payment/EmailPayment.php +++ b/app/Jobs/Payment/EmailPayment.php @@ -1,9 +1,13 @@ payment = $payment; + $this->email_builder = $email_builder; + $this->contact = $contact; + } - $this->company = $company; - } /** * Execute the job. @@ -46,37 +52,24 @@ class EmailPayment implements ShouldQueue */ public function handle() { - /*Jobs are not multi-db aware, need to set! */ - MultiDB::setDB($this->company->db); + $email_builder = $this->email_builder; - //todo - change runtime config of mail driver if necessary + if ($this->contact->email) { + Mail::to($this->contact->email, $this->contact->present()->name()) + ->send(new TemplateEmail($email_builder, $this->contact->user, $this->contact->customer)); - $template_style = $this->payment->client->getSetting('email_style'); + if (count(Mail::failures()) > 0) { + event(new PaymentWasEmailedAndFailed($this->payment, Mail::failures())); - $this->payment->client->contacts->each(function ($contact) use ($template_style) { - if ($contact->email) { - $message_array = $this->payment->getEmailData('', $contact); - $message_array['title'] = &$message_array['subject']; - $message_array['footer'] = "Sent to ".$contact->present()->name(); - - //change the runtime config of the mail provider here: - - //send message - Mail::to($contact->email, $contact->present()->name()) - ->send(new TemplateEmail($message_array, $template_style, $contact->user, $contact->client)); - - if (count(Mail::failures()) > 0) { - event(new PaymentWasEmailedAndFailed($this->payment, Mail::failures())); - - return $this->logMailError($errors); - } - - //fire any events - event(new PaymentWasEmailed($this->payment)); - - //sleep(5); + return $this->logMailError($errors); } - }); + + //fire any events + event(new PaymentWasEmailed($this->payment)); + + //sleep(5); + } + } private function logMailError($errors) diff --git a/app/Jobs/Quote/EmailQuote.php b/app/Jobs/Quote/EmailQuote.php index fd7834e59240..845c839d08cf 100644 --- a/app/Jobs/Quote/EmailQuote.php +++ b/app/Jobs/Quote/EmailQuote.php @@ -1,13 +1,17 @@ quote = $quote; - - $this->company = $company; + $this->quote_invitation = $quote_invitation; + $this->email_builder = $email_builder; } /** @@ -46,37 +47,19 @@ class EmailQuote implements ShouldQueue */ public function handle() { - /*Jobs are not multi-db aware, need to set! */ - MultiDB::setDB($this->company->db); + $email_builder = $this->email_builder; - //todo - change runtime config of mail driver if necessary + Mail::to($this->quote_invitation->contact->email, $this->quote_invitation->contact->present()->name()) + ->send(new TemplateEmail($email_builder, + $this->quote_invitation->contact->user, + $this->quote_invitation->contact->client + ) + ); - $template_style = $this->quote->client->getSetting('email_style'); + if (count(Mail::failures()) > 0) { + return $this->logMailError($errors); + } - $this->quote->invitations->each(function ($invitation) use ($template_style) { - if ($invitation->contact->email) { - $message_array = $this->quote->getEmailData('', $invitation->contact); - $message_array['title'] = &$message_array['subject']; - $message_array['footer'] = "Quote Link"; - - //change the runtime config of the mail provider here: - - //send message - Mail::to($invitation->contact->email, $invitation->contact->present()->name()) - ->send(new TemplateEmail($message_array, $template_style, $invitation->contact->user, $invitation->contact->client)); - - if (count(Mail::failures()) > 0) { - event(new QuoteWasEmailedAndFailed($this->quote, Mail::failures())); - - return $this->logMailError($errors); - } - - //fire any events - event(new QuoteWasEmailed($this->quote)); - - //sleep(5); - } - }); } private function logMailError($errors) diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index 47872e14113b..e1b06a5ac22c 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -1,8 +1,6 @@ message = $message; - $this->template = $template; + $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->client = $client; + $this->customer = $customer; } /** @@ -37,33 +29,32 @@ 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->template; + $template_name = 'email.template.' . $this->build_email->getTemplate(); - $settings = $this->client->getMergedSettings(); + $settings = $this->customer->getMergedSettings(); + \Log::error(print_r($settings, 1)); + $company = $this->customer->account; - $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->message['subject']) - ->text('email.template.plain', ['body' => $this->message['body'], 'footer' => $this->message['footer']]) + $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->message['body'], - 'footer' => $this->message['footer'], - 'title' => $this->message['title'], + 'body' => $this->build_email->getBody(), + 'footer' => $this->build_email->getFooter(), + 'title' => $this->build_email->getSubject(), 'settings' => $settings, 'company' => $company ]); + //conditionally attach files + if($settings->pdf_email_attachment !== false && !empty($this->build_email->getAttachments())){ - //conditionally attach files - if ($settings->pdf_email_attachment !== false && array_key_exists('files', $this->message)) { - foreach ($this->message['files'] as $file) { - $message->attach($file); - } - } + foreach($this->build_email->getAttachments() as $file) + $message->attach($file); + } - return $message; + return $message; } } diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 715f736c0fee..f5bec3c94189 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -146,7 +146,7 @@ class Invoice extends BaseModel public function payments() { - return $this->morphToMany(Payment::class, 'paymentable')->withPivot('amount','refunded')->withTimestamps();; + return $this->morphToMany(Payment::class, 'paymentable')->withPivot('amount', 'refunded')->withTimestamps();; } public function company_ledger() @@ -156,13 +156,14 @@ class Invoice extends BaseModel public function credits() { - return $this->belongsToMany(Credit::class)->using(Paymentable::class)->withPivot('amount','refunded')->withTimestamps();; + return $this->belongsToMany(Credit::class)->using(Paymentable::class)->withPivot('amount', + 'refunded')->withTimestamps();; } /** * Service entry points */ - public function service() :InvoiceService + public function service(): InvoiceService { return new InvoiceService($this); } @@ -192,12 +193,12 @@ class Invoice extends BaseModel * * @return boolean isLocked */ - public function isLocked() : bool + public function isLocked(): bool { return $this->client->getSetting('lock_sent_invoices'); } - public function isPayable() : bool + public function isPayable(): bool { if ($this->status_id == Invoice::STATUS_SENT && $this->is_deleted == false) { return true; @@ -212,23 +213,25 @@ class Invoice extends BaseModel } } - public function isRefundable() : bool + public function isRefundable(): bool { - if($this->is_deleted) + if ($this->is_deleted) { return false; + } - if(($this->amount - $this->balance) == 0) + if (($this->amount - $this->balance) == 0) { return false; + } return true; - + } /** * @return bool */ - public function isPartial() : bool + public function isPartial(): bool { return $this->status_id >= self::STATUS_PARTIAL; } @@ -236,7 +239,7 @@ class Invoice extends BaseModel /** * @return bool */ - public function hasPartial() : bool + public function hasPartial(): bool { return ($this->partial && $this->partial > 0) === true; } @@ -245,28 +248,28 @@ class Invoice extends BaseModel { switch ($status) { case Invoice::STATUS_DRAFT: - return '