diff --git a/app/Events/Quote/QuoteWasViewed.php b/app/Events/Quote/QuoteWasViewed.php index 725964994ac5..80452990837c 100644 --- a/app/Events/Quote/QuoteWasViewed.php +++ b/app/Events/Quote/QuoteWasViewed.php @@ -12,7 +12,6 @@ namespace App\Events\Quote; use App\Models\Company; -use App\Models\QuoteWasViewed; use Illuminate\Queue\SerializesModels; /** diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 720a7f04a358..7b7800974c62 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -16,6 +16,7 @@ use App\Http\Requests\Credit\ShowCreditRequest; use App\Http\Requests\Credit\StoreCreditRequest; use App\Http\Requests\Credit\UpdateCreditRequest; use App\Jobs\Credit\StoreCredit; +use App\Jobs\Entity\EmailEntity; use App\Jobs\Invoice\EmailCredit; use App\Jobs\Invoice\MarkInvoicePaid; use App\Models\Client; @@ -545,7 +546,13 @@ class CreditController extends BaseController } break; case 'email': - EmailCredit::dispatch($credit, $credit->company); + // EmailCredit::dispatch($credit, $credit->company); + + $credit->invitations->load('contact.client.country', 'credit.client.country', 'credit.company')->each(function ($invitation) use ($credit) { + EmailEntity::dispatch($invitation, $credit->company); + }); + + if (! $bulk) { return response()->json(['message'=>'email sent'], 200); } diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index f3e069e8578e..e99d92f0e231 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -19,10 +19,12 @@ use App\Jobs\Mail\EntitySentMailer; use App\Models\Credit; use App\Models\Invoice; use App\Models\Quote; +use App\Models\RecurringInvoice; use App\Notifications\SendGenericNotification; use App\Transformers\CreditTransformer; use App\Transformers\InvoiceTransformer; use App\Transformers\QuoteTransformer; +use App\Transformers\RecurringInvoiceTransformer; use App\Utils\Traits\MakesHash; class EmailController extends BaseController @@ -131,21 +133,27 @@ class EmailController extends BaseController EntitySentMailer::dispatch($invitation, $entity_string, $entity_obj->user, $invitation->company); - if ($this instanceof Invoice) { + if ($entity_obj instanceof Invoice) { $this->entity_type = Invoice::class; $this->entity_transformer = InvoiceTransformer::class; } - if ($this instanceof Quote) { + if ($entity_obj instanceof Quote) { $this->entity_type = Quote::class; $this->entity_transformer = QuoteTransformer::class; } - if ($this instanceof Credit) { + if ($entity_obj instanceof Credit) { $this->entity_type = Credit::class; $this->entity_transformer = CreditTransformer::class; } + if ($entity_obj instanceof RecurringInvoice) { + $this->entity_type = RecurringInvoice::class; + $this->entity_transformer = RecurringInvoiceTransformer::class; + } + + $entity_obj->service()->markSent()->save(); return $this->itemResponse($entity_obj); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 26cf34d64788..5cfc5dbdc51a 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -706,7 +706,7 @@ class InvoiceController extends BaseController if (request()->has('email_type') && property_exists($invoice->company->settings, request()->input('email_type'))) { $this->reminder_template = $invoice->client->getSetting(request()->input('email_type')); } else { - $this->reminder_template = $invoice->calculateTemplate(); + $this->reminder_template = $invoice->calculateTemplate('invoice'); } //touch reminder1,2,3_sent + last_sent here if the email is a reminder. diff --git a/app/Http/Requests/Task/UpdateTaskRequest.php b/app/Http/Requests/Task/UpdateTaskRequest.php index a7f2b3311f75..902e51a60c82 100644 --- a/app/Http/Requests/Task/UpdateTaskRequest.php +++ b/app/Http/Requests/Task/UpdateTaskRequest.php @@ -40,25 +40,14 @@ class UpdateTaskRequest extends Request /* Ensure we have a client name, and that all emails are unique*/ if ($this->input('number')) { - $rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.$this->taskss->company_id; + $rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.$this->task->company_id; } return $this->globalRules($rules); } - // public function messages() - // { - // return [ - // 'unique' => ctrans('validation.unique', ['attribute' => 'email']), - // 'email' => ctrans('validation.email', ['attribute' => 'email']), - // 'name.required' => ctrans('validation.required', ['attribute' => 'name']), - // 'required' => ctrans('validation.required', ['attribute' => 'email']), - // ]; - // } - protected function prepareForValidation() { - $input = $this->decodePrimaryKeys($this->all()); $this->replace($input); diff --git a/app/Http/ValidationRules/User/RelatedUserRule.php b/app/Http/ValidationRules/User/RelatedUserRule.php index 03fa08629958..82ecbc6d8ac2 100644 --- a/app/Http/ValidationRules/User/RelatedUserRule.php +++ b/app/Http/ValidationRules/User/RelatedUserRule.php @@ -50,6 +50,10 @@ class RelatedUserRule implements Rule */ private function checkUserIsRelated($user_id) : bool { + + if(empty($user_id)) + return true; + return User::query() ->where('id', $user_id) ->where('account_id', auth()->user()->company()->account_id) diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php index 01826882b267..a49d560f90c8 100644 --- a/app/Jobs/Util/ReminderJob.php +++ b/app/Jobs/Util/ReminderJob.php @@ -66,7 +66,7 @@ class ReminderJob implements ShouldQueue if ($invoice->isPayable()) { - $reminder_template = $invoice->calculateTemplate(); + $reminder_template = $invoice->calculateTemplate('invoice'); $invoice->service()->touchReminder($this->reminder_template)->save(); $invoice->invitations->each(function ($invitation) use ($invoice) { diff --git a/app/Mail/Engine/QuoteEmailEngine.php b/app/Mail/Engine/QuoteEmailEngine.php new file mode 100644 index 000000000000..698127a98802 --- /dev/null +++ b/app/Mail/Engine/QuoteEmailEngine.php @@ -0,0 +1,90 @@ +invitation = $invitation; + $this->reminder_template = $reminder_template; + $this->client = $invitation->contact->client; + $this->quote = $invitation->quote; + $this->contact = $invitation->contact; + } + + public function build() + { + + $body_template = $this->client->getSetting('email_template_'.$this->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', + [ + 'quote' => $this->quote->number, + 'company' => $this->quote->company->present()->name(), + 'amount' => Number::formatMoney($this->quote->balance, $this->client), + ], + null, + $this->client->locale() + ); + } + + $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); + + if (iconv_strlen($subject_template) == 0) { + + $subject_template = trans( + 'texts.quote_subject', + [ + 'number' => $this->quote->number, + 'account' => $this->quote->company->present()->name(), + ], + null, + $this->client->locale() + ); + + } + + $this->setTemplate($this->client->getSetting('email_style')) + ->setContact($this->contact) + ->setVariables($this->quote->makeValues($this->contact))//move make values into the htmlengine + ->setSubject($subject_template) + ->setBody($body_template) + ->setFooter("".ctrans('texts.view_quote').'') + ->setViewLink($this->invitation->getLink()) + ->setViewText(ctrans('texts.view_quote')); + + if ($this->client->getSetting('pdf_email_attachment') !== false) { + $this->setAttachments($invitation->pdf_file_path()); + } + + return $this; + + } + +} + diff --git a/app/Models/Task.php b/app/Models/Task.php index 70cda18fd158..373ae4f548f3 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -26,6 +26,7 @@ class Task extends BaseModel 'client_id', 'invoice_id', 'project_id', + 'assigned_user_id', 'custom_value1', 'custom_value2', 'custom_value3', diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index cd4982814508..4db7a15ae816 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -15,6 +15,7 @@ use App\Models\Credit; use App\Services\Credit\ApplyPayment; use App\Services\Credit\CreateInvitations; use App\Services\Credit\MarkSent; +use App\Services\Credit\SendEmail; class CreditService { @@ -55,6 +56,14 @@ class CreditService return $this; } + public function sendEmail($contact = null) + { + $send_email = new SendEmail($this->credit, null, $contact); + + return $send_email->run(); + } + + public function setCalculatedStatus() { diff --git a/app/Services/Credit/SendEmail.php b/app/Services/Credit/SendEmail.php new file mode 100644 index 000000000000..31e12ac6b371 --- /dev/null +++ b/app/Services/Credit/SendEmail.php @@ -0,0 +1,60 @@ +credit = $credit; + + $this->reminder_template = $reminder_template; + + $this->contact = $contact; + } + + /** + * Builds the correct template to send. + * @param string $this->reminder_template The template name ie reminder1 + * @return array + */ + public function run() + { + if (! $this->reminder_template) { + $this->reminder_template = $this->credit->calculateTemplate('credit'); + } + + $this->credit->invitations->each(function ($invitation) { + if ($invitation->contact->send_email && $invitation->contact->email) { + $email_builder = (new CreditEmail())->build($invitation, $this->reminder_template); + + // EmailCredit::dispatchNow($email_builder, $invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company); + + } + }); + + $this->credit->service()->markSent(); + } +} diff --git a/app/Services/Invoice/SendEmail.php b/app/Services/Invoice/SendEmail.php index 293273c05118..332ae1e812a0 100644 --- a/app/Services/Invoice/SendEmail.php +++ b/app/Services/Invoice/SendEmail.php @@ -12,6 +12,7 @@ namespace App\Services\Invoice; use App\Helpers\Email\InvoiceEmail; +use App\Jobs\Entity\EmailEntity; use App\Jobs\Invoice\EmailInvoice; use App\Models\ClientContact; use App\Models\Invoice; @@ -50,7 +51,9 @@ class SendEmail extends AbstractService $email_builder = (new InvoiceEmail())->build($invitation, $this->reminder_template); if ($invitation->contact->send_email && $invitation->contact->email) { - EmailInvoice::dispatch($email_builder, $invitation, $invitation->company); +// EmailInvoice::dispatch($email_builder, $invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company); + } }); } diff --git a/app/Services/Quote/SendEmail.php b/app/Services/Quote/SendEmail.php index 2096a36db86a..23d900c4b141 100644 --- a/app/Services/Quote/SendEmail.php +++ b/app/Services/Quote/SendEmail.php @@ -12,6 +12,7 @@ namespace App\Services\Quote; use App\Helpers\Email\QuoteEmail; +use App\Jobs\Entity\EmailEntity; use App\Jobs\Quote\EmailQuote; use App\Models\ClientContact; use App\Models\Quote; @@ -48,7 +49,9 @@ class SendEmail if ($invitation->contact->send_email && $invitation->contact->email) { $email_builder = (new QuoteEmail())->build($invitation, $this->reminder_template); - EmailQuote::dispatchNow($email_builder, $invitation, $invitation->company); + // EmailQuote::dispatchNow($email_builder, $invitation, $invitation->company); + EmailEntity::dispatchNow($invitation, $invitation->company); + } }); diff --git a/tests/Integration/SendFailedEmailsTest.php b/tests/Integration/SendFailedEmailsTest.php index b61038ef65b7..c7b0a4afa397 100644 --- a/tests/Integration/SendFailedEmailsTest.php +++ b/tests/Integration/SendFailedEmailsTest.php @@ -40,7 +40,7 @@ class SendFailedEmailsTest extends TestCase public function testReminderFires() { $invitation = $this->invoice->invitations->first(); - $reminder_template = $this->invoice->calculateTemplate(); + $reminder_template = $this->invoice->calculateTemplate('invoice'); $sl = [ 'entity_name' => \App\Models\InvoiceInvitation::class, @@ -63,11 +63,6 @@ class SendFailedEmailsTest extends TestCase $this->assertNotNull($sys_log); - // Queue::fake(); SendFailedEmails::dispatch(); - - //Queue::assertPushed(SendFailedEmails::class); - //Queue::assertPushed(EmailInvoice::class); - //$this->expectsJobs(EmailInvoice::class); } }