diff --git a/.env.dusk.example b/.env.dusk.example
index 60dd0ac0e942..4ad2e62efcba 100644
--- a/.env.dusk.example
+++ b/.env.dusk.example
@@ -3,7 +3,6 @@ APP_DEBUG=true
APP_LOCALE=en
APP_URL=http://127.0.0.1:8000
APP_KEY=s7epnjtomsdond5zgfqgaqmwhhcjct02
-APP_CIPHER=AES-256-CBC
REQUIRE_HTTPS=false
NINJA_ENVIRONMENT=development
@@ -26,4 +25,3 @@ MAIL_FROM_ADDRESS=
MAIL_PASSWORD=
MAILGUN_DOMAIN=
MAILGUN_SECRET=
-AUTH_PROVIDER=users
diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php
index 7499b41d2d19..3024d424655a 100644
--- a/app/Console/Commands/CheckData.php
+++ b/app/Console/Commands/CheckData.php
@@ -355,8 +355,6 @@ class CheckData extends Command
$wrong_balances = 0;
$wrong_paid_to_dates = 0;
- //todo reversing an invoice breaks the check data at this point;
-
Client::cursor()->each(function ($client) use ($wrong_balances) {
$client->invoices->where('is_deleted', false)->each(function ($invoice) use ($wrong_balances, $client) {
$total_amount = $invoice->payments->sum('pivot.amount');
diff --git a/app/Console/Commands/CreateSingleAccount.php b/app/Console/Commands/CreateSingleAccount.php
index ba83e7ecba92..f500accc6db4 100644
--- a/app/Console/Commands/CreateSingleAccount.php
+++ b/app/Console/Commands/CreateSingleAccount.php
@@ -340,10 +340,6 @@ class CreateSingleAccount extends Command
$this->invoice_repo->markSent($invoice);
- // if (rand(0, 1)) {
- // $invoice = $invoice->service()->markPaid()->save();
- // }
- //@todo this slow things down, but gives us PDFs of the invoices for inspection whilst debugging.
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars()));
}
diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php
index 2dab5b2dd4cd..6b1172ebf1df 100644
--- a/app/Console/Commands/CreateTestData.php
+++ b/app/Console/Commands/CreateTestData.php
@@ -516,7 +516,7 @@ class CreateTestData extends Command
if (rand(0, 1)) {
$invoice = $invoice->service()->markPaid()->save();
}
- //@todo this slow things down, but gives us PDFs of the invoices for inspection whilst debugging.
+
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars()));
}
diff --git a/app/Console/Commands/DemoMode.php b/app/Console/Commands/DemoMode.php
index 8e5c3881d420..dae42b242547 100644
--- a/app/Console/Commands/DemoMode.php
+++ b/app/Console/Commands/DemoMode.php
@@ -431,7 +431,7 @@ class DemoMode extends Command
$payment->save();
});
}
- //@todo this slow things down, but gives us PDFs of the invoices for inspection whilst debugging.
+
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars()));
}
diff --git a/app/Console/Commands/SendTestEmails.php b/app/Console/Commands/SendTestEmails.php
index 0a6a2511f6c2..c775dce2f27d 100644
--- a/app/Console/Commands/SendTestEmails.php
+++ b/app/Console/Commands/SendTestEmails.php
@@ -17,7 +17,6 @@ use App\Factory\ClientFactory;
use App\Factory\CompanyUserFactory;
use App\Factory\InvoiceFactory;
use App\Factory\InvoiceInvitationFactory;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\CreateEntityPdf;
use App\Mail\TemplateEmail;
use App\Models\Account;
@@ -155,16 +154,15 @@ class SendTestEmails extends Command
$cc_emails = [config('ninja.testvars.test_email')];
$bcc_emails = [config('ninja.testvars.test_email')];
- $email_builder = (new InvoiceEmail())->build($ii, 'invoice');
$email_builder->setFooter($message['footer'])
->setSubject($message['subject'])
->setBody($message['body']);
- Mail::to(config('ninja.testvars.test_email'), 'Mr Test')
- ->cc($cc_emails)
- ->bcc($bcc_emails)
+ // Mail::to(config('ninja.testvars.test_email'), 'Mr Test')
+ // ->cc($cc_emails)
+ // ->bcc($bcc_emails)
//->replyTo(also_available_if_needed)
- ->send(new TemplateEmail($email_builder, $user, $client));
+ //->send(new TemplateEmail($email_builder, $user, $client));
}
}
diff --git a/app/DataMapper/DefaultSettings.php b/app/DataMapper/DefaultSettings.php
index bfdcf155f28f..a80242697dbf 100644
--- a/app/DataMapper/DefaultSettings.php
+++ b/app/DataMapper/DefaultSettings.php
@@ -28,7 +28,6 @@ class DefaultSettings extends BaseSettings
/**
* @return stdClass
*
- * //todo user specific settings / preferences.
*/
public static function userSettings() : stdClass
{
diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php
index 5fc3288a95db..0ab17319ade8 100644
--- a/app/DataMapper/EmailTemplateDefaults.php
+++ b/app/DataMapper/EmailTemplateDefaults.php
@@ -178,6 +178,7 @@ class EmailTemplateDefaults
public static function emailReminder1Subject()
{
+ info("reminder 1 subject");
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
}
diff --git a/app/Events/Invoice/InvoiceReminderWasEmailed.php b/app/Events/Invoice/InvoiceReminderWasEmailed.php
new file mode 100644
index 000000000000..6201582cc981
--- /dev/null
+++ b/app/Events/Invoice/InvoiceReminderWasEmailed.php
@@ -0,0 +1,50 @@
+invitation = $invitation;
+ $this->company = $company;
+ $this->event_vars = $event_vars;
+ $this->reminder = $reminder;
+ }
+}
diff --git a/app/Filters/CreditFilters.php b/app/Filters/CreditFilters.php
index b390da78a53d..1c87ddc47318 100644
--- a/app/Filters/CreditFilters.php
+++ b/app/Filters/CreditFilters.php
@@ -25,7 +25,6 @@ class CreditFilters extends QueryFilters
* Filter based on client status.
*
* Statuses we need to handle
- * //todo ?partials as a status?
* - all
* - paid
* - unpaid
diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php
index 320e889079ed..522b048631e9 100644
--- a/app/Filters/InvoiceFilters.php
+++ b/app/Filters/InvoiceFilters.php
@@ -26,7 +26,6 @@ class InvoiceFilters extends QueryFilters
* Filter based on client status.
*
* Statuses we need to handle
- * //todo ?partials as a status?
* - all
* - paid
* - unpaid
diff --git a/app/Helpers/ClientPortal.php b/app/Helpers/ClientPortal.php
index 382350ad4af7..fa885ee689ec 100644
--- a/app/Helpers/ClientPortal.php
+++ b/app/Helpers/ClientPortal.php
@@ -1,5 +1,4 @@
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)
- {
-
- if (! empty($this->variables)) {
- $subject = str_replace(array_keys($this->variables), array_values($this->variables), $subject);
- }
-
- $this->subject = $subject;
-
- return $this;
- }
-
- /**
- * @param $body
- * @return $this
- */
- public function setBody($body)
- {
- //todo move this to use HTMLEngine
- if (! empty($this->variables)) {
- $body = str_replace(array_keys($this->variables), array_values($this->variables), $body);
- }
-
- $this->body = $body;
-
- 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 $this;
- }
-
- public function setViewLink($link)
- {
- $this->view_link = $link;
-
- return $this;
- }
-
- public function setViewText($text)
- {
- $this->view_text = $text;
-
- return $this;
- }
-
- /**
- * @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;
- }
-
- public function getViewLink()
- {
- return $this->view_link;
- }
-
- public function getViewText()
- {
- return $this->view_text;
- }
-}
diff --git a/app/Helpers/Email/InvoiceEmail.php b/app/Helpers/Email/InvoiceEmail.php
deleted file mode 100644
index 9fad11927ea8..000000000000
--- a/app/Helpers/Email/InvoiceEmail.php
+++ /dev/null
@@ -1,86 +0,0 @@
-contact->client;
- $invoice = $invitation->invoice;
- $contact = $invitation->contact;
-
- if (! $reminder_template) {
- $reminder_template = $invoice->calculateTemplate('invoice');
- }
-
- $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',
- [
- 'invoice' => $invoice->number,
- 'company' => $invoice->company->present()->name(),
- 'amount' => Number::formatMoney($invoice->balance, $invoice->client),
- ],
- 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.quote_subject',
- [
- 'number' => $invoice->number,
- 'account' => $invoice->company->present()->name(),
- ],
- null,
- $invoice->client->locale()
- );
- } else {
- $subject_template = trans(
- 'texts.invoice_subject',
- [
- 'number' => $invoice->number,
- 'account' => $invoice->company->present()->name(),
- ],
- null,
- $invoice->client->locale()
- );
- }
- }
-
- $this->setTemplate($client->getSetting('email_style'))
- ->setContact($contact)
- ->setVariables((new HtmlEngine($invitation))->makeValues())
- ->setSubject($subject_template)
- ->setBody($body_template)
- ->setFooter("".ctrans('texts.view_invoice').'')
- ->setViewLink($invitation->getLink())
- ->setViewText(ctrans('texts.view_invoice'));
-
- if ($client->getSetting('pdf_email_attachment') !== false) {
- $this->setAttachments($invitation->pdf_file_path());
- }
-
- return $this;
- }
-}
diff --git a/app/Helpers/Email/PaymentEmail.php b/app/Helpers/Email/PaymentEmail.php
deleted file mode 100644
index 0e96d2dc35f7..000000000000
--- a/app/Helpers/Email/PaymentEmail.php
+++ /dev/null
@@ -1,48 +0,0 @@
-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
deleted file mode 100644
index c98f1d0532f3..000000000000
--- a/app/Helpers/Email/QuoteEmail.php
+++ /dev/null
@@ -1,70 +0,0 @@
-contact->client;
- $quote = $invitation->quote;
- $contact = $invitation->contact;
-
- $this->template_style = $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("Quote Link")
- ->setVariables((new HtmlEngine($invitation))->makeValues())
- ->setSubject($subject_template)
- ->setBody($body_template);
-
- if ($client->getSetting('pdf_email_attachment') !== false) {
- $this->attachments = $invitation->pdf_file_path();
- }
-
- return $this;
- }
-}
diff --git a/app/Helpers/Language/NinjaTranslator.php b/app/Helpers/Language/NinjaTranslator.php
index 1891628a79ef..4777116bf998 100644
--- a/app/Helpers/Language/NinjaTranslator.php
+++ b/app/Helpers/Language/NinjaTranslator.php
@@ -1,4 +1,13 @@
gmail->cc($message->getCc());
$this->gmail->bcc($message->getBcc());
- Log::error(print_r($message->getChildren(), 1));
+ info(print_r($message->getChildren(), 1));
foreach ($message->getChildren() as $child) {
$this->gmail->attach($child);
diff --git a/app/Helpers/TranslationHelper.php b/app/Helpers/TranslationHelper.php
index 76a582645894..c77da5585181 100644
--- a/app/Helpers/TranslationHelper.php
+++ b/app/Helpers/TranslationHelper.php
@@ -22,7 +22,5 @@
*/
function ctrans(string $string, $replace = [], $locale = null) : string
{
- //todo pass through the cached version of the custom strings here else return trans();
-
return trans($string, $replace, $locale);
}
diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php
index d768bf1cf33f..04f10b0cccc9 100644
--- a/app/Http/Controllers/EmailController.php
+++ b/app/Http/Controllers/EmailController.php
@@ -11,7 +11,6 @@
namespace App\Http\Controllers;
-use App\Helpers\Email\InvoiceEmail;
use App\Http\Requests\Email\SendEmailRequest;
use App\Jobs\Entity\EmailEntity;
use App\Jobs\Invoice\EmailInvoice;
@@ -139,9 +138,8 @@ class EmailController extends BaseController
$entity_obj->save();
/*Only notify the admin ONCE, not once per contact/invite*/
- $invitation = $entity_obj->invitations->first();
-
- EntitySentMailer::dispatch($invitation, $entity_string, $entity_obj->user, $invitation->company);
+ // $invitation = $entity_obj->invitations->first();
+ // EntitySentMailer::dispatch($invitation, $entity_string, $entity_obj->user, $invitation->company);
if ($entity_obj instanceof Invoice) {
$this->entity_type = Invoice::class;
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index bf6e5c97ec06..4bdb7a6bc22c 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -20,7 +20,6 @@ use App\Factory\CloneInvoiceFactory;
use App\Factory\CloneInvoiceToQuoteFactory;
use App\Factory\InvoiceFactory;
use App\Filters\InvoiceFilters;
-use App\Helpers\Email\InvoiceEmail;
use App\Http\Requests\Invoice\ActionInvoiceRequest;
use App\Http\Requests\Invoice\CreateInvoiceRequest;
use App\Http\Requests\Invoice\DestroyInvoiceRequest;
@@ -723,8 +722,6 @@ class InvoiceController extends BaseController
$invoice->service()->touchReminder($this->reminder_template)->save();
$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, $this->reminder_template);
});
diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php
index 78caf1f26929..4aa6dde3e805 100644
--- a/app/Http/Controllers/PaymentController.php
+++ b/app/Http/Controllers/PaymentController.php
@@ -510,7 +510,6 @@ class PaymentController extends BaseController
$payments->each(function ($payment, $key) use ($action) {
if (auth()->user()->can('edit', $payment)) {
$this->performAction($payment, $action, true);
- // $this->payment_repo->{$action}($payment);
}
});
diff --git a/app/Http/Requests/ClientPortal/Documents/ShowDocumentRequest.php b/app/Http/Requests/ClientPortal/Documents/ShowDocumentRequest.php
index 6db1346cbbc1..1b0eec9504a3 100644
--- a/app/Http/Requests/ClientPortal/Documents/ShowDocumentRequest.php
+++ b/app/Http/Requests/ClientPortal/Documents/ShowDocumentRequest.php
@@ -28,7 +28,7 @@ class ShowDocumentRequest extends FormRequest
*/
public function authorize()
{
- return auth()->user('contact')->client->id === $this->document->documentable->id;
+ return auth()->user('contact')->client->id == $this->document->documentable_id;
}
/**
diff --git a/app/Http/ViewComposers/PortalComposer.php b/app/Http/ViewComposers/PortalComposer.php
index 0d13a36f57cb..3ab97958eb4b 100644
--- a/app/Http/ViewComposers/PortalComposer.php
+++ b/app/Http/ViewComposers/PortalComposer.php
@@ -12,7 +12,9 @@
namespace App\Http\ViewComposers;
use App\Models\ClientContact;
+use App\Utils\Ninja;
use App\Utils\TranslationHelper;
+use Illuminate\Support\Facades\Lang;
use Illuminate\View\View;
/**
@@ -29,6 +31,9 @@ class PortalComposer
public function compose(View $view) :void
{
$view->with($this->portalData());
+
+ if(auth()->user())
+ Lang::replace(Ninja::transformTranslations(auth()->user()->client->getMergedSettings()));
}
/**
diff --git a/app/Jobs/Entity/CreateEntityPdf.php b/app/Jobs/Entity/CreateEntityPdf.php
index 6d0a8f98806e..fca7262c0ad0 100644
--- a/app/Jobs/Entity/CreateEntityPdf.php
+++ b/app/Jobs/Entity/CreateEntityPdf.php
@@ -31,6 +31,7 @@ use App\Services\PdfMaker\Design as PdfDesignModel;
use App\Services\PdfMaker\Design as PdfMakerDesign;
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
use App\Utils\HtmlEngine;
+use App\Utils\Ninja;
use App\Utils\PhantomJS\Phantom;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
@@ -42,6 +43,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Storage;
use Spatie\Browsershot\Browsershot;
@@ -102,6 +104,7 @@ class CreateEntityPdf implements ShouldQueue
}
App::setLocale($this->contact->preferredLocale());
+ App::forgetInstance('translator');
$entity_design_id = '';
@@ -118,6 +121,8 @@ class CreateEntityPdf implements ShouldQueue
$entity_design_id = 'credit_design_id';
}
+ Lang::replace(Ninja::transformTranslations($this->entity->client->getMergedSettings()));
+
$file_path = $path.$this->entity->number.'.pdf';
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
diff --git a/app/Jobs/Entity/EmailEntity.php b/app/Jobs/Entity/EmailEntity.php
index fcb449c201b2..a80f148ccdfc 100644
--- a/app/Jobs/Entity/EmailEntity.php
+++ b/app/Jobs/Entity/EmailEntity.php
@@ -12,13 +12,14 @@
namespace App\Jobs\Entity;
use App\DataMapper\Analytics\EmailInvoiceFailure;
+use App\Events\Invoice\InvoiceReminderWasEmailed;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Mail\BaseMailerJob;
use App\Jobs\Utils\SystemLogger;
use App\Libraries\MultiDB;
use App\Mail\TemplateEmail;
+use App\Models\Activity;
use App\Models\Company;
use App\Models\CreditInvitation;
use App\Models\Invoice;
@@ -170,11 +171,22 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
private function entityEmailSucceeded()
{
- switch ($this->entity_string) {
+ 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;
diff --git a/app/Jobs/Mail/BaseMailerJob.php b/app/Jobs/Mail/BaseMailerJob.php
index bc1a1e8ab5aa..0a03436ace6f 100644
--- a/app/Jobs/Mail/BaseMailerJob.php
+++ b/app/Jobs/Mail/BaseMailerJob.php
@@ -16,12 +16,15 @@ use App\Libraries\Google\Google;
use App\Libraries\MultiDB;
use App\Models\User;
use App\Providers\MailServiceProvider;
+use App\Utils\Ninja;
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\Facades\App;
use Illuminate\Support\Facades\Config;
+use Illuminate\Support\Facades\Lang;
use Turbo124\Beacon\Facades\LightLogs;
/*Multi Mailer implemented*/
@@ -32,6 +35,9 @@ class BaseMailerJob implements ShouldQueue
public function setMailDriver()
{
+ App::forgetInstance('translator');
+ Lang::replace(Ninja::transformTranslations($this->settings));
+
switch ($this->settings->email_sending_method) {
case 'default':
break;
@@ -69,7 +75,7 @@ class BaseMailerJob implements ShouldQueue
}
public function logMailError($errors, $recipient_object)
- {
+ {info(print_r($errors,1));
SystemLogger::dispatch(
$errors,
SystemLog::CATEGORY_MAIL,
diff --git a/app/Jobs/Mail/EntityPaidMailer.php b/app/Jobs/Mail/EntityPaidMailer.php
index b0defdc0cab9..62e0d462f8b3 100644
--- a/app/Jobs/Mail/EntityPaidMailer.php
+++ b/app/Jobs/Mail/EntityPaidMailer.php
@@ -53,11 +53,11 @@ class EntityPaidMailer extends BaseMailerJob implements ShouldQueue
* @param $user
* @param $company
*/
- public function __construct($payment, $company)
+ public function __construct($payment, $company, $user)
{
$this->company = $company;
- $this->user = $payment->user;
+ $this->user = $user;
$this->payment = $payment;
@@ -84,7 +84,7 @@ class EntityPaidMailer extends BaseMailerJob implements ShouldQueue
try {
$mail_obj = (new EntityPaidObject($this->payment))->build();
- $mail_obj->from = [$this->payment->user->email, $this->payment->user->present()->name()];
+ $mail_obj->from = [$this->user->email, $this->user->present()->name()];
//send email
Mail::to($this->user->email)
@@ -96,7 +96,7 @@ class EntityPaidMailer extends BaseMailerJob implements ShouldQueue
}
if (count(Mail::failures()) > 0) {
- $this->logMailError(Mail::failures(), $this->entity->client);
+ $this->logMailError(Mail::failures(), $this->payment->client);
} else {
// $this->entityEmailSucceeded();
}
diff --git a/app/Jobs/Ninja/AdjustEmailQuota.php b/app/Jobs/Ninja/AdjustEmailQuota.php
index 1fecd1bbdd01..68f92ee97920 100644
--- a/app/Jobs/Ninja/AdjustEmailQuota.php
+++ b/app/Jobs/Ninja/AdjustEmailQuota.php
@@ -11,7 +11,6 @@
namespace App\Jobs\Ninja;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\EmailInvoice;
use App\Libraries\MultiDB;
use App\Models\Account;
diff --git a/app/Jobs/Ninja/CheckDbStatus.php b/app/Jobs/Ninja/CheckDbStatus.php
index a573cff8c219..b5302fe79e6e 100644
--- a/app/Jobs/Ninja/CheckDbStatus.php
+++ b/app/Jobs/Ninja/CheckDbStatus.php
@@ -11,7 +11,6 @@
namespace App\Jobs\Ninja;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\EmailInvoice;
use App\Libraries\MultiDB;
use App\Models\Account;
diff --git a/app/Jobs/Ninja/CompanySizeCheck.php b/app/Jobs/Ninja/CompanySizeCheck.php
index b64404707d04..8adaec609548 100644
--- a/app/Jobs/Ninja/CompanySizeCheck.php
+++ b/app/Jobs/Ninja/CompanySizeCheck.php
@@ -11,7 +11,6 @@
namespace App\Jobs\Ninja;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\EmailInvoice;
use App\Libraries\MultiDB;
use App\Models\Account;
diff --git a/app/Jobs/Ninja/SendReminders.php b/app/Jobs/Ninja/SendReminders.php
index 89d5dbe28599..ec9d9aaf7e3a 100644
--- a/app/Jobs/Ninja/SendReminders.php
+++ b/app/Jobs/Ninja/SendReminders.php
@@ -88,6 +88,8 @@ class SendReminders implements ShouldQueue
$reminder_template = $invoice->calculateTemplate('invoice');
+ info("hitting a reminder for {$invoice->number} with template {$reminder_template}");
+
if(in_array($reminder_template, ['reminder1', 'reminder2', 'reminder3', 'endless_reminder']))
$this->sendReminder($invoice, $reminder_template);
@@ -216,15 +218,18 @@ class SendReminders implements ShouldQueue
//only send if enable_reminder setting is toggled to yes
if($this->checkSendSetting($invoice, $template)) {
- EmailEntity::dispatchNow($invitation, $invitation->company, $template);
+ info("firing email");
- event(new InvoiceWasEmailed($invitation, $invoice->company, Ninja::eventVars()));
+ EmailEntity::dispatchNow($invitation, $invitation->company, $template);
}
});
+
+ if($this->checkSendSetting($invoice, $template))
+ event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars()));
$invoice->last_sent_date = now();
$invoice->next_send_date = $this->calculateNextSendDate($invoice);
@@ -232,7 +237,6 @@ class SendReminders implements ShouldQueue
if(in_array($template, ['reminder1', 'reminder2', 'reminder3']))
$invoice->{$template."_sent"} = now();
-
$invoice->save();
}
diff --git a/app/Jobs/Payment/EmailPayment.php b/app/Jobs/Payment/EmailPayment.php
index 8c3487a6824c..e93fc5faaf22 100644
--- a/app/Jobs/Payment/EmailPayment.php
+++ b/app/Jobs/Payment/EmailPayment.php
@@ -2,6 +2,7 @@
namespace App\Jobs\Payment;
+use App\DataMapper\Analytics\EmailInvoiceFailure;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
use App\Events\Payment\PaymentWasEmailed;
@@ -10,7 +11,9 @@ use App\Helpers\Email\BuildEmail;
use App\Jobs\Mail\BaseMailerJob;
use App\Jobs\Utils\SystemLogger;
use App\Libraries\MultiDB;
+use App\Mail\Engine\PaymentEmailEngine;
use App\Mail\TemplateEmail;
+use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Payment;
use App\Models\SystemLog;
@@ -21,6 +24,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
+use Turbo124\Beacon\Facades\LightLogs;
class EmailPayment extends BaseMailerJob implements ShouldQueue
{
@@ -33,6 +37,9 @@ class EmailPayment extends BaseMailerJob implements ShouldQueue
private $contact;
private $company;
+
+ public $settings;
+
/**
* Create a new job instance.
*
@@ -41,12 +48,12 @@ class EmailPayment extends BaseMailerJob implements ShouldQueue
* @param $contact
* @param $company
*/
- public function __construct(Payment $payment, $email_builder, $contact, company)
+ public function __construct(Payment $payment, Company $company, ClientContact $contact)
{
$this->payment = $payment;
- $this->email_builder = $email_builder;
$this->contact = $contact;
$this->company = $company;
+ $this->settings = $payment->client->getMergedSettings();
}
/**
@@ -62,14 +69,15 @@ class EmailPayment extends BaseMailerJob implements ShouldQueue
if ($this->contact->email) {
- MultiDB::setDb($this->payment->company->db); //this may fail if we don't pass the serialized object with the company record
- //todo fix!!
+ MultiDB::setDb($this->company->db);
//if we need to set an email driver do it now
$this->setMailDriver();
+ $email_builder = (new PaymentEmailEngine($this->payment, $this->contact))->build();
+
Mail::to($this->contact->email, $this->contact->present()->name())
- ->send(new TemplateEmail($this->email_builder, $this->contact->user, $this->contact->customer));
+ ->send(new TemplateEmail($email_builder, $this->contact->user, $this->contact->client));
if (count(Mail::failures()) > 0) {
event(new PaymentWasEmailedAndFailed($this->payment, Mail::failures(), Ninja::eventVars()));
@@ -77,21 +85,22 @@ class EmailPayment extends BaseMailerJob implements ShouldQueue
return $this->logMailError(Mail::failures());
}
- //fire any events
event(new PaymentWasEmailed($this->payment, $this->payment->company, Ninja::eventVars()));
- //sleep(5);
}
}
- private function logMailError($errors)
+ public function failed($exception = null)
{
- SystemLogger::dispatch(
- $errors,
- SystemLog::CATEGORY_MAIL,
- SystemLog::EVENT_MAIL_SEND,
- SystemLog::TYPE_FAILURE,
- $this->payment->client
- );
+ info('the job failed');
+
+ $job_failure = new EmailInvoiceFailure();
+ $job_failure->string_metric5 = 'payment';
+ $job_failure->string_metric6 = $exception->getMessage();
+
+ LightLogs::create($job_failure)
+ ->batch();
+
}
+
}
diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php
index 574a24ea3ebe..56d155479b4c 100644
--- a/app/Jobs/RecurringInvoice/SendRecurring.php
+++ b/app/Jobs/RecurringInvoice/SendRecurring.php
@@ -14,7 +14,6 @@ namespace App\Jobs\RecurringInvoice;
use App\DataMapper\Analytics\SendRecurringFailure;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Factory\RecurringInvoiceToInvoiceFactory;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Entity\EmailEntity;
use App\Models\Invoice;
use App\Models\RecurringInvoice;
@@ -74,8 +73,6 @@ class SendRecurring implements ShouldQueue
$invoice->invitations->each(function ($invitation) use ($invoice) {
- $email_builder = (new InvoiceEmail())->build($invitation);
-
if($invitation->contact && strlen($invitation->contact->email) >=1){
EmailEntity::dispatch($invitation, $invoice->company);
info("Firing email for invoice {$invoice->number}");
diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php
index a49d560f90c8..4ad02907e345 100644
--- a/app/Jobs/Util/ReminderJob.php
+++ b/app/Jobs/Util/ReminderJob.php
@@ -12,7 +12,6 @@
namespace App\Jobs\Util;
use App\Events\Invoice\InvoiceWasEmailed;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\EmailInvoice;
use App\Libraries\MultiDB;
use App\Models\Account;
@@ -69,11 +68,9 @@ class ReminderJob implements ShouldQueue
$reminder_template = $invoice->calculateTemplate('invoice');
$invoice->service()->touchReminder($this->reminder_template)->save();
- $invoice->invitations->each(function ($invitation) use ($invoice) {
- $email_builder = (new InvoiceEmail())->build($invitation);
-
- EmailInvoice::dispatch($email_builder, $invitation, $invoice->company);
+ $invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
+ EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
info("Firing email for invoice {$invoice->number}");
});
diff --git a/app/Jobs/Util/SendFailedEmails.php b/app/Jobs/Util/SendFailedEmails.php
index 35973ac60ba6..19281c19a1e7 100644
--- a/app/Jobs/Util/SendFailedEmails.php
+++ b/app/Jobs/Util/SendFailedEmails.php
@@ -11,9 +11,7 @@
namespace App\Jobs\Util;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Entity\EmailEntity;
-use App\Jobs\Invoice\EmailInvoice;
use App\Libraries\MultiDB;
use App\Models\SystemLog;
use Illuminate\Bus\Queueable;
@@ -66,7 +64,6 @@ class SendFailedEmails implements ShouldQueue
$invitation = $job_meta_array['entity_name']::where('key', $job_meta_array['invitation_key'])->with('contact')->first();
if ($invitation->invoice) {
- $email_builder = (new InvoiceEmail())->build($invitation, $job_meta_array['reminder_template']);
if ($invitation->contact->send_email && $invitation->contact->email) {
EmailEntity::dispatch($invitation, $invitation->company, $job_meta_array['reminder_template']);
diff --git a/app/Listeners/Invoice/InvoiceReminderEmailActivity.php b/app/Listeners/Invoice/InvoiceReminderEmailActivity.php
new file mode 100644
index 000000000000..7da20a5d60c1
--- /dev/null
+++ b/app/Listeners/Invoice/InvoiceReminderEmailActivity.php
@@ -0,0 +1,59 @@
+activity_repo = $activity_repo;
+ }
+
+ /**
+ * Handle the event.
+ *
+ * @param object $event
+ * @return void
+ */
+ public function handle($event)
+ {
+ MultiDB::setDb($event->company->db);
+
+ $fields = new stdClass;
+
+ $fields->invoice_id = $event->invitation->invoice->id;
+ $fields->user_id = $event->invitation->invoice->user_id;
+ $fields->company_id = $event->invitation->invoice->company_id;
+ $fields->client_contact_id = $event->invitation->invoice->client_contact_id;
+ $fields->activity_type_id = $event->reminder;
+
+ $this->activity_repo->save($fields, $event->invitation->invoice, $event->event_vars);
+ }
+}
diff --git a/app/Listeners/Payment/PaymentNotification.php b/app/Listeners/Payment/PaymentNotification.php
index f57e070e0a1b..07f194170169 100644
--- a/app/Listeners/Payment/PaymentNotification.php
+++ b/app/Listeners/Payment/PaymentNotification.php
@@ -63,7 +63,7 @@ class PaymentNotification implements ShouldQueue
if (($key = array_search('mail', $methods)) !== false) {
unset($methods[$key]);
- EntityPaidMailer::dispatch($payment, $payment->company);
+ EntityPaidMailer::dispatch($payment, $payment->company, $user);
}
diff --git a/app/Mail/Engine/InvoiceEmailEngine.php b/app/Mail/Engine/InvoiceEmailEngine.php
index 0eb4ce4cf9f5..3a455925f846 100644
--- a/app/Mail/Engine/InvoiceEmailEngine.php
+++ b/app/Mail/Engine/InvoiceEmailEngine.php
@@ -44,9 +44,10 @@ class InvoiceEmailEngine extends BaseEmailEngine
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'];
+ elseif(strlen($this->client->getSetting('email_template_'.$this->reminder_template)) > 0)
+ $body_template = $this->client->getSetting('email_template_'.$this->reminder_template);
else{
- //$body_template = $this->client->getSetting('email_template_'.$this->reminder_template);
- $body_template = EmailTemplateDefaults::getDefaultTemplate($this->client->getSetting('email_template_'.$this->reminder_template), $this->client->locale());
+ $body_template = EmailTemplateDefaults::getDefaultTemplate('email_template_'.$this->reminder_template, $this->client->locale());
}
/* Use default translations if a custom message has not been set*/
@@ -63,10 +64,17 @@ class InvoiceEmailEngine extends BaseEmailEngine
);
}
- if(is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0)
+ 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'];
+ info("subject = template data");
+ }
+ elseif(strlen($this->client->getSetting('email_subject_'.$this->reminder_template)) > 0){
+ $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
+ info("subject = settings var");
+ }
else{
- $subject_template = EmailTemplateDefaults::getDefaultTemplate($this->client->getSetting('email_subject_'.$this->reminder_template), $this->client->locale());
+ info("subject = default template " . 'email_subject_'.$this->reminder_template);
+ $subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale());
// $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
}
diff --git a/app/Mail/Engine/PaymentEmailEngine.php b/app/Mail/Engine/PaymentEmailEngine.php
new file mode 100644
index 000000000000..48724998d6bd
--- /dev/null
+++ b/app/Mail/Engine/PaymentEmailEngine.php
@@ -0,0 +1,263 @@
+payment = $payment;
+ $this->company = $payment->company;
+ $this->client = $payment->client;
+ $this->contact = $contact ?: $this->client->primary_contact()->first();
+ $this->settings = $this->client->getMergedSettings();
+ $this->template_data = $template_data;
+ }
+
+ public function build()
+ {
+
+ 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'];
+ elseif(strlen($this->client->getSetting('email_template_payment')) > 0)
+ $body_template = $this->client->getSetting('email_template_payment');
+ else{
+ $body_template = EmailTemplateDefaults::getDefaultTemplate('email_template_payment', $this->client->locale());
+ }
+
+ /* 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()
+ );
+ }
+
+ 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'];
+ }
+ elseif(strlen($this->client->getSetting('email_subject_payment')) > 0){
+ $subject_template = $this->client->getSetting('email_subject_payment');
+ }
+ else{
+ $subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_payment', $this->client->locale());
+ }
+
+ if (iconv_strlen($subject_template) == 0) {
+ $subject_template = trans(
+ 'texts.payment_subject',
+ ['number' => $payment->number, 'company' => $payment->company->present()->name()],
+ null,
+ $this->client->locale()
+ );
+ }
+
+ $this->setTemplate($this->client->getSetting('email_style'))
+ ->setContact($this->contact)
+ ->setVariables($this->makeValues())
+ ->setSubject($subject_template)
+ ->setBody($body_template)
+ ->setFooter('')
+ ->setViewLink('')
+ ->setViewText('');
+
+ return $this;
+
+ }
+
+
+ private function makePaymentVariables()
+ {
+ $data = [];
+
+ $data['$from'] = ['value' => '', 'label' => ctrans('texts.from')];
+ $data['$to'] = ['value' => '', 'label' => ctrans('texts.to')];
+ $data['$number'] = ['value' => $this->payment->number ?: ' ', 'label' => ctrans('texts.payment_number')];
+ $data['$payment.number'] = &$data['$number'];
+ $data['$entity'] = ['value' => '', 'label' => ctrans('texts.payment')];
+ $data['$payment.amount'] = ['value' => Number::formatMoney($this->payment->amount, $this->client) ?: ' ', 'label' => ctrans('texts.amount')];
+ $data['$amount'] = &$data['$payment.amount'];
+ $data['$payment.date'] = ['value' => $this->formatDate($this->payment->date, $this->client->date_format()), 'label' => ctrans('texts.payment_date')];
+ $data['$transaction_reference'] = ['value' => $this->payment->transaction_reference, 'label' => ctrans('texts.transaction_reference')];
+ $data['$public_notes'] = ['value' => $this->payment->public_notes, 'label' => ctrans('texts.notes')];
+
+ $data['$payment1'] = ['value' => $this->formatCustomFieldValue('payment1', $this->payment->custom_value1) ?: ' ', 'label' => $this->makeCustomField('payment1')];
+ $data['$payment2'] = ['value' => $this->formatCustomFieldValue('payment2', $this->payment->custom_value2) ?: ' ', 'label' => $this->makeCustomField('payment2')];
+ $data['$payment3'] = ['value' => $this->formatCustomFieldValue('payment3', $this->payment->custom_value3) ?: ' ', 'label' => $this->makeCustomField('payment3')];
+ $data['$payment4'] = ['value' => $this->formatCustomFieldValue('payment4', $this->payment->custom_value4) ?: ' ', 'label' => $this->makeCustomField('payment4')];
+ // $data['$type'] = ['value' => $this->payment->type->name ?: '', 'label' => ctrans('texts.payment_type')];
+
+ $data['$client1'] = ['value' => $this->formatCustomFieldValue('client1', $this->client->custom_value1) ?: ' ', 'label' => $this->makeCustomField('client1')];
+ $data['$client2'] = ['value' => $this->formatCustomFieldValue('client2', $this->client->custom_value2) ?: ' ', 'label' => $this->makeCustomField('client2')];
+ $data['$client3'] = ['value' => $this->formatCustomFieldValue('client3', $this->client->custom_value3) ?: ' ', 'label' => $this->makeCustomField('client3')];
+ $data['$client4'] = ['value' => $this->formatCustomFieldValue('client4', $this->client->custom_value4) ?: ' ', 'label' => $this->makeCustomField('client4')];
+ $data['$address1'] = ['value' => $this->client->address1 ?: ' ', 'label' => ctrans('texts.address1')];
+ $data['$address2'] = ['value' => $this->client->address2 ?: ' ', 'label' => ctrans('texts.address2')];
+ $data['$id_number'] = ['value' => $this->client->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
+ $data['$vat_number'] = ['value' => $this->client->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
+ $data['$website'] = ['value' => $this->client->present()->website() ?: ' ', 'label' => ctrans('texts.website')];
+ $data['$phone'] = ['value' => $this->client->present()->phone() ?: ' ', 'label' => ctrans('texts.phone')];
+ $data['$country'] = ['value' => isset($this->client->country->name) ? $this->client->country->name : '', 'label' => ctrans('texts.country')];
+ $data['$email'] = ['value' => isset($this->contact) ? $this->contact->email : 'no contact email on record', 'label' => ctrans('texts.email')];
+ $data['$client_name'] = ['value' => $this->client->present()->name() ?: ' ', 'label' => ctrans('texts.client_name')];
+ $data['$client.name'] = &$data['$client_name'];
+ $data['$client.address1'] = &$data['$address1'];
+ $data['$client.address2'] = &$data['$address2'];
+ $data['$client_address'] = ['value' => $this->client->present()->address() ?: ' ', 'label' => ctrans('texts.address')];
+ $data['$client.address'] = &$data['$client_address'];
+ $data['$client.id_number'] = &$data['$id_number'];
+ $data['$client.vat_number'] = &$data['$vat_number'];
+ $data['$client.website'] = &$data['$website'];
+ $data['$client.phone'] = &$data['$phone'];
+ $data['$city_state_postal'] = ['value' => $this->client->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, false) ?: ' ', 'label' => ctrans('texts.city_state_postal')];
+ $data['$client.city_state_postal'] = &$data['$city_state_postal'];
+ $data['$postal_city_state'] = ['value' => $this->client->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, true) ?: ' ', 'label' => ctrans('texts.postal_city_state')];
+ $data['$client.postal_city_state'] = &$data['$postal_city_state'];
+ $data['$client.country'] = &$data['$country'];
+ $data['$client.email'] = &$data['$email'];
+
+ $data['$client.balance'] = ['value' => Number::formatMoney($this->client->balance, $this->client), 'label' => ctrans('texts.account_balance')];
+ $data['$outstanding'] = ['value' => Number::formatMoney($this->client->balance, $this->client), 'label' => ctrans('texts.account_balance')];
+ $data['$client_balance'] = ['value' => Number::formatMoney($this->client->balance, $this->client), 'label' => ctrans('texts.account_balance')];
+ $data['$paid_to_date'] = ['value' => Number::formatMoney($this->client->paid_to_date, $this->client), 'label' => ctrans('texts.paid_to_date')];
+
+ $data['$contact.full_name'] = ['value' => $this->contact->present()->name(), 'label' => ctrans('texts.name')];
+ $data['$contact.email'] = ['value' => $this->contact->email, 'label' => ctrans('texts.email')];
+ $data['$contact.phone'] = ['value' => $this->contact->phone, 'label' => ctrans('texts.phone')];
+
+ $data['$contact.name'] = ['value' => isset($this->contact) ? $this->contact->present()->name() : 'no contact name on record', 'label' => ctrans('texts.contact_name')];
+ $data['$contact.first_name'] = ['value' => isset($this->contact) ? $this->contact->first_name : '', 'label' => ctrans('texts.first_name')];
+ $data['$contact.last_name'] = ['value' => isset($this->contact) ? $this->contact->last_name : '', 'label' => ctrans('texts.last_name')];
+ $data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom3'] = ['value' => isset($this->contact) ? $this->contact->custom_value3 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom4'] = ['value' => isset($this->contact) ? $this->contact->custom_value4 : ' ', 'label' => $this->makeCustomField('contact1')];
+
+ $data['$company.city_state_postal'] = ['value' => $this->company->present()->cityStateZip($this->settings->city, $this->settings->state, $this->settings->postal_code, false) ?: ' ', 'label' => ctrans('texts.city_state_postal')];
+ $data['$company.postal_city_state'] = ['value' => $this->company->present()->cityStateZip($this->settings->city, $this->settings->state, $this->settings->postal_code, true) ?: ' ', 'label' => ctrans('texts.postal_city_state')];
+ $data['$company.name'] = ['value' => $this->company->present()->name() ?: ' ', 'label' => ctrans('texts.company_name')];
+ $data['$company.address1'] = ['value' => $this->settings->address1 ?: ' ', 'label' => ctrans('texts.address1')];
+ $data['$company.address2'] = ['value' => $this->settings->address2 ?: ' ', 'label' => ctrans('texts.address2')];
+ $data['$company.city'] = ['value' => $this->settings->city ?: ' ', 'label' => ctrans('texts.city')];
+ $data['$company.state'] = ['value' => $this->settings->state ?: ' ', 'label' => ctrans('texts.state')];
+ $data['$company.postal_code'] = ['value' => $this->settings->postal_code ?: ' ', 'label' => ctrans('texts.postal_code')];
+ //$data['$company.country'] = ['value' => $this->getCountryName(), 'label' => ctrans('texts.country')];
+ $data['$company.phone'] = ['value' => $this->settings->phone ?: ' ', 'label' => ctrans('texts.phone')];
+ $data['$company.email'] = ['value' => $this->settings->email ?: ' ', 'label' => ctrans('texts.email')];
+ $data['$company.vat_number'] = ['value' => $this->settings->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
+ $data['$company.id_number'] = ['value' => $this->settings->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
+ $data['$company.website'] = ['value' => $this->settings->website ?: ' ', 'label' => ctrans('texts.website')];
+ $data['$company.address'] = ['value' => $this->company->present()->address($this->settings) ?: ' ', 'label' => ctrans('texts.address')];
+
+ $logo = $this->company->present()->logo($this->settings);
+
+ $data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
+ $data['$company_logo'] = &$data['$company.logo'];
+ $data['$company1'] = ['value' => $this->formatCustomFieldValue('company1', $this->settings->custom_value1) ?: ' ', 'label' => $this->makeCustomField('company1')];
+ $data['$company2'] = ['value' => $this->formatCustomFieldValue('company2', $this->settings->custom_value2) ?: ' ', 'label' => $this->makeCustomField('company2')];
+ $data['$company3'] = ['value' => $this->formatCustomFieldValue('company3', $this->settings->custom_value3) ?: ' ', 'label' => $this->makeCustomField('company3')];
+ $data['$company4'] = ['value' => $this->formatCustomFieldValue('company4', $this->settings->custom_value4) ?: ' ', 'label' => $this->makeCustomField('company4')];
+
+ $data['$view_link'] = ['value' => ''.ctrans('texts.view_payment').'', 'label' => ctrans('texts.view_payment')];
+ $data['$view_url'] = ['value' => $this->payment->getLink(), 'label' => ctrans('texts.view_payment')];
+
+ $data['$invoices'] = ['value' => $this->formatInvoices(), 'label' => ctrans('texts.invoices')];
+
+ return $data;
+ }
+
+ private function formatInvoices()
+ {
+ $invoice_list = '';
+
+ foreach($this->payment->invoices as $invoice)
+ {
+ $invoice_list .= ctrans('texts.invoice_number_short') . " {$invoice->number} - " . Number::formatMoney($invoice->pivot->amount, $this->client) . "
";
+ }
+
+ return $invoice_list;
+ }
+
+ private function makeCustomField($field) :string
+ {
+ $custom_fields = $this->company->custom_fields;
+
+ if ($custom_fields && property_exists($custom_fields, $field)) {
+ $custom_field = $custom_fields->{$field};
+
+ $custom_field_parts = explode('|', $custom_field);
+
+ return $custom_field_parts[0];
+ }
+
+ return '';
+ }
+
+ private function formatCustomFieldValue($field, $value) :string
+ {
+ $custom_fields = $this->company->custom_fields;
+ $custom_field = '';
+
+ if ($custom_fields && property_exists($custom_fields, $field)) {
+ $custom_field = $custom_fields->{$field};
+ $custom_field_parts = explode('|', $custom_field);
+
+ if(count($custom_field_parts) >= 2)
+ $custom_field = $custom_field_parts[1];
+ }
+
+ switch ($custom_field) {
+ case 'date':
+ return $this->formatDate($value, $this->client->date_format());
+ break;
+
+ default:
+ return is_null($value) ? '' : $value;
+ break;
+ }
+ }
+
+ public function makeValues() :array
+ {
+ $data = [];
+
+ $values = $this->makePaymentVariables();
+
+ foreach ($values as $key => $value) {
+ $data[$key] = $value['value'];
+ }
+
+ return $data;
+ }
+}
+
diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php
index 62cd47dda126..49d7f5896d28 100644
--- a/app/Mail/TemplateEmail.php
+++ b/app/Mail/TemplateEmail.php
@@ -67,7 +67,8 @@ class TemplateEmail extends Mailable
'footer' => $this->build_email->getFooter(),
'view_link' => $this->build_email->getViewLink(),
'view_text' => $this->build_email->getViewText(),
- 'title' => $this->build_email->getSubject(),
+ 'title' => '',
+ // 'title' => $this->build_email->getSubject(),
'signature' => $settings->email_signature,
'settings' => $settings,
'company' => $company,
diff --git a/app/Models/Activity.php b/app/Models/Activity.php
index e271bc920fb4..607dc86890fa 100644
--- a/app/Models/Activity.php
+++ b/app/Models/Activity.php
@@ -80,6 +80,11 @@ class Activity extends StaticModel
const UPDATE_CLIENT = 61; //
const UPDATE_VENDOR = 62; //
+ const INVOICE_REMINDER1_SENT = 63;
+ const INVOICE_REMINDER2_SENT = 64;
+ const INVOICE_REMINDER3_SENT = 65;
+ const INVOICE_REMINDER_ENDLESS_SENT = 66;
+
protected $casts = [
'is_system' => 'boolean',
'updated_at' => 'timestamp',
diff --git a/app/Models/Payment.php b/app/Models/Payment.php
index f30542e69dd1..3fcad72d5be5 100644
--- a/app/Models/Payment.php
+++ b/app/Models/Payment.php
@@ -67,6 +67,10 @@ class Payment extends BaseModel
'number',
'is_manual',
'private_notes',
+ 'custom_value1',
+ 'custom_value2',
+ 'custom_value3',
+ 'custom_value4',
];
protected $casts = [
@@ -284,4 +288,10 @@ class Payment extends BaseModel
event(new PaymentWasVoided($this, $this->company, Ninja::eventVars()));
}
+
+ public function getLink()
+ {
+ return route('client.payments.show', $this->hashed_id);
+ }
+
}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index 6a0db9ffcaab..c035126c8e4c 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -35,6 +35,7 @@ use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasDeleted;
use App\Events\Expense\ExpenseWasRestored;
use App\Events\Expense\ExpenseWasUpdated;
+use App\Events\Invoice\InvoiceReminderWasEmailed;
use App\Events\Invoice\InvoiceWasArchived;
use App\Events\Invoice\InvoiceWasCancelled;
use App\Events\Invoice\InvoiceWasCreated;
@@ -121,6 +122,7 @@ use App\Listeners\Invoice\InvoiceEmailActivity;
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;
use App\Listeners\Invoice\InvoiceReversedActivity;
use App\Listeners\Invoice\InvoiceViewedActivity;
@@ -285,6 +287,9 @@ class EventServiceProvider extends ServiceProvider
InvoiceWasEmailedAndFailed::class => [
InvoiceEmailFailedActivity::class,
],
+ InvoiceReminderWasEmailed::class => [
+ InvoiceReminderEmailActivity::class,
+ ],
InvoiceWasDeleted::class => [
InvoiceDeletedActivity::class,
CreateInvoicePdf::class,
diff --git a/app/Repositories/ClientRepository.php b/app/Repositories/ClientRepository.php
index e4924f387f7e..d133ff887d1f 100644
--- a/app/Repositories/ClientRepository.php
+++ b/app/Repositories/ClientRepository.php
@@ -53,28 +53,25 @@ class ClientRepository extends BaseRepository
*/
public function save(array $data, Client $client) : ?Client
{
- $client->fill($data);
- $client->save();
-
- if ($client->id_number == '' || ! $client->id_number) {
- $client->id_number = $this->getNextClientNumber($client);
+ /* When uploading documents, only the document array is sent, so we must return early*/
+ if (array_key_exists('documents', $data) && count($data['documents']) >=1) {
+ $this->saveDocuments($data['documents'], $client);
+ return $client;
}
+ $client->fill($data);
+
+ if (!isset($client->id_number))
+ $client->id_number = $this->getNextClientNumber($client);
+
+ if (empty($data['name']))
+ $data['name'] = $client->present()->name();
+
$client->save();
$this->contact_repo->save($data, $client);
- if (empty($data['name'])) {
- $data['name'] = $client->present()->name();
- }
-
- //info("{$client->present()->name} has a balance of {$client->balance} with a paid to date of {$client->paid_to_date}");
-
- if (array_key_exists('documents', $data)) {
- $this->saveDocuments($data['documents'], $client);
- }
-
return $client;
}
diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php
index 1fe1d0deed01..63aee8f49ee4 100644
--- a/app/Services/Invoice/MarkPaid.php
+++ b/app/Services/Invoice/MarkPaid.php
@@ -14,6 +14,7 @@ namespace App\Services\Invoice;
use App\Events\Invoice\InvoiceWasPaid;
use App\Events\Payment\PaymentWasCreated;
use App\Factory\PaymentFactory;
+use App\Jobs\Payment\EmailPayment;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\AbstractService;
@@ -74,6 +75,8 @@ class MarkPaid extends AbstractService
->applyNumber()
->save();
+ EmailPayment::dispatch($payment, $payment->company, $payment->client->primary_contact()->first());
+
/* Update Invoice balance */
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
event(new InvoiceWasPaid($this->invoice, $payment->company, Ninja::eventVars()));
diff --git a/app/Services/Invoice/SendEmail.php b/app/Services/Invoice/SendEmail.php
index a69bf12c3511..4436a5e419bb 100644
--- a/app/Services/Invoice/SendEmail.php
+++ b/app/Services/Invoice/SendEmail.php
@@ -11,7 +11,6 @@
namespace App\Services\Invoice;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Entity\EmailEntity;
use App\Models\ClientContact;
use App\Models\Invoice;
@@ -46,8 +45,6 @@ class SendEmail extends AbstractService
}
$this->invoice->invitations->each(function ($invitation) {
- $email_builder = (new InvoiceEmail())->build($invitation, $this->reminder_template);
-
if ($invitation->contact->send_email && $invitation->contact->email) {
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
diff --git a/app/Services/Invoice/TriggeredActions.php b/app/Services/Invoice/TriggeredActions.php
index c110c2492cff..caa5a5e17314 100644
--- a/app/Services/Invoice/TriggeredActions.php
+++ b/app/Services/Invoice/TriggeredActions.php
@@ -14,7 +14,6 @@ namespace App\Services\Invoice;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Payment\PaymentWasCreated;
use App\Factory\PaymentFactory;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Invoice\EmailEntity;
use App\Models\Client;
use App\Models\Invoice;
diff --git a/app/Services/Payment/SendEmail.php b/app/Services/Payment/SendEmail.php
index dc4b42b7d008..388a8cf04add 100644
--- a/app/Services/Payment/SendEmail.php
+++ b/app/Services/Payment/SendEmail.php
@@ -11,7 +11,6 @@
namespace App\Services\Payment;
-use App\Helpers\Email\PaymentEmail;
use App\Jobs\Payment\EmailPayment;
class SendEmail
@@ -33,11 +32,9 @@ class SendEmail
*/
public function run()
{
- $email_builder = (new PaymentEmail())->build($this->payment, $this->contact);
-
- $this->payment->client->contacts->each(function ($contact) use ($email_builder) {
- if ($contact->send && $contact->email) {
- EmailPayment::dispatchNow($this->payment, $email_builder, $contact, $this->payment->company);
+ $this->payment->client->contacts->each(function ($contact) {
+ if ($contact->send_email && $contact->email) {
+ EmailPayment::dispatchNow($this->payment, $this->payment->company, $contact);
}
});
}
diff --git a/app/Services/Payment/UpdateInvoicePayment.php b/app/Services/Payment/UpdateInvoicePayment.php
index 341e3c746595..31643652ba2f 100644
--- a/app/Services/Payment/UpdateInvoicePayment.php
+++ b/app/Services/Payment/UpdateInvoicePayment.php
@@ -12,7 +12,6 @@
namespace App\Services\Payment;
use App\Events\Invoice\InvoiceWasUpdated;
-use App\Helpers\Email\PaymentEmail;
use App\Jobs\Payment\EmailPayment;
use App\Jobs\Util\SystemLogger;
use App\Models\Invoice;
diff --git a/app/Services/Quote/SendEmail.php b/app/Services/Quote/SendEmail.php
index f2382567b92e..ae42c3b7ad81 100644
--- a/app/Services/Quote/SendEmail.php
+++ b/app/Services/Quote/SendEmail.php
@@ -11,7 +11,6 @@
namespace App\Services\Quote;
-use App\Helpers\Email\QuoteEmail;
use App\Jobs\Entity\EmailEntity;
use App\Jobs\Quote\EmailQuote;
use App\Models\ClientContact;
@@ -46,9 +45,6 @@ class SendEmail
$this->quote->invitations->each(function ($invitation) {
if ($invitation->contact->send_email && $invitation->contact->email) {
- $email_builder = (new QuoteEmail())->build($invitation, $this->reminder_template);
-
- // EmailQuote::dispatchNow($email_builder, $invitation, $invitation->company);
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
}
diff --git a/app/Utils/Ninja.php b/app/Utils/Ninja.php
index 5d4dc56f9b0a..d88bcf28664e 100644
--- a/app/Utils/Ninja.php
+++ b/app/Utils/Ninja.php
@@ -121,4 +121,22 @@ class Ninja
'is_system' => app()->runningInConsole(),
];
}
+
+ public static function transformTranslations($settings) :array
+ {
+ $translations = [];
+
+ $trans = (array)$settings->translations;
+
+ if(count($trans) == 0)
+ return $translations;
+
+ foreach($trans as $key => $value)
+ {
+ $translations['texts.'.$key] = $value;
+ }
+
+ return $translations;
+
+ }
}
diff --git a/app/Utils/Traits/SavesDocuments.php b/app/Utils/Traits/SavesDocuments.php
index 4b46743998d6..6afb48c5313f 100644
--- a/app/Utils/Traits/SavesDocuments.php
+++ b/app/Utils/Traits/SavesDocuments.php
@@ -17,7 +17,7 @@ use App\Models\Company;
trait SavesDocuments
{
- public function saveDocuments($document_array, $entity, $is_public = false)
+ public function saveDocuments($document_array, $entity, $is_public = true)
{
if ($entity instanceof Company) {
$account = $entity->account;
diff --git a/database/migrations/2020_11_08_212050_custom_fields_for_payments_table.php b/database/migrations/2020_11_08_212050_custom_fields_for_payments_table.php
new file mode 100644
index 000000000000..c7aa8461721c
--- /dev/null
+++ b/database/migrations/2020_11_08_212050_custom_fields_for_payments_table.php
@@ -0,0 +1,33 @@
+string('custom_value1')->nullable();
+ $table->string('custom_value2')->nullable();
+ $table->string('custom_value3')->nullable();
+ $table->string('custom_value4')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ //
+ }
+}
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index 3cfd7ae4e121..0636c6169370 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -3296,4 +3296,11 @@ return [
'pay_with' => 'Pay with',
'n/a' => 'N/A',
+ 'payment_number' => 'Payment Number',
+
+ 'activity_63' => ':user emailed reminder 1 for invoice :invoice to :contact',
+ 'activity_64' => ':user emailed reminder 2 for invoice :invoice to :contact',
+ 'activity_65' => ':user emailed reminder 3 for invoice :invoice to :contact',
+ 'activity_66' => ':user emailed reminder endless for invoice :invoice to :contact',
+
];
diff --git a/tests/Feature/InvoiceEmailTest.php b/tests/Feature/InvoiceEmailTest.php
index 10c1ab7e00bc..06e8d33d8058 100644
--- a/tests/Feature/InvoiceEmailTest.php
+++ b/tests/Feature/InvoiceEmailTest.php
@@ -10,7 +10,6 @@
*/
namespace Tests\Feature;
-use App\Helpers\Email\InvoiceEmail;
use App\Jobs\Entity\EmailEntity;
use App\Mail\TemplateEmail;
use App\Models\ClientContact;