diff --git a/app/Events/Quote/QuoteWasApproved.php b/app/Events/Quote/QuoteWasApproved.php new file mode 100644 index 000000000000..421911d2ddab --- /dev/null +++ b/app/Events/Quote/QuoteWasApproved.php @@ -0,0 +1,29 @@ +quote = $quote; + } +} diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php index e4cd267ef1ef..751b359ae893 100644 --- a/app/Http/Controllers/ClientPortal/QuoteController.php +++ b/app/Http/Controllers/ClientPortal/QuoteController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\ClientPortal; +use App\Events\Quote\QuoteWasApproved; use App\Http\Controllers\Controller; use App\Http\Requests\ClientPortal\ProcessQuotesInBulkRequest; use App\Http\Requests\ClientPortal\ShowQuoteRequest; @@ -98,6 +99,7 @@ class QuoteController extends Controller if ($process) { foreach ($quotes as $quote) { $quote->service()->approve()->save(); + event(new QuoteWasApproved($quote)); } return route('client.quotes.index')->withSuccess('Quote(s) approved successfully.'); diff --git a/app/Jobs/Invoice/InvoiceWorkflowSettings.php b/app/Jobs/Invoice/InvoiceWorkflowSettings.php new file mode 100644 index 000000000000..9678680ebc32 --- /dev/null +++ b/app/Jobs/Invoice/InvoiceWorkflowSettings.php @@ -0,0 +1,64 @@ +invoice = $invoice; + $this->client = $client ?? $invoice->client; + $this->base_repository = new BaseRepository(); + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if ($this->client->getSetting('auto_archive_invoice')) { + /** Throws: Payment amount xxx does not match invoice totals. */ + $this->base_repository->archive($this->invoice); + } + + if ($this->client->getSetting('auto_email_invoice')) { + $this->invoice->invitations->each(function ($invitation, $key) { + $this->invoice->service()->sendEmail($invitation->contact); + }); + } + } +} diff --git a/app/Jobs/Quote/QuoteWorkflowSettings.php b/app/Jobs/Quote/QuoteWorkflowSettings.php new file mode 100644 index 000000000000..54288c0fd604 --- /dev/null +++ b/app/Jobs/Quote/QuoteWorkflowSettings.php @@ -0,0 +1,62 @@ +quote = $quote; + $this->client = $client ?? $quote->client; + $this->base_repository = new BaseRepository(); + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if ($this->client->getSetting('auto_archive_quote')) { + $this->base_repository->archive($this->quote); + } + + if ($this->client->getSetting('auto_email_quote')) { + $this->quote->invitations->each(function ($invitation, $key) { + $this->quote->service()->sendEmail($invitation->contact); + }); + } + } +} diff --git a/app/Listeners/Activity/PaymentCreatedActivity.php b/app/Listeners/Activity/PaymentCreatedActivity.php index 52e1434c6433..68f0b939e771 100644 --- a/app/Listeners/Activity/PaymentCreatedActivity.php +++ b/app/Listeners/Activity/PaymentCreatedActivity.php @@ -11,6 +11,7 @@ namespace App\Listeners\Activity; +use App\Jobs\Invoice\InvoiceWorkflowSettings; use App\Models\Activity; use App\Models\Invoice; use App\Models\Payment; @@ -54,6 +55,8 @@ class PaymentCreatedActivity implements ShouldQueue foreach ($invoices as $invoice) { //todo we may need to add additional logic if in the future we apply payments to other entity Types, not just invoices $fields->invoice_id = $invoice->id; + InvoiceWorkflowSettings::dispatchNow($invoice); + $this->activityRepo->save($fields, $invoice); } diff --git a/app/Listeners/Quote/ReachWorkflowSettings.php b/app/Listeners/Quote/ReachWorkflowSettings.php new file mode 100644 index 000000000000..9cd54bbac131 --- /dev/null +++ b/app/Listeners/Quote/ReachWorkflowSettings.php @@ -0,0 +1,31 @@ +quote); + } +} diff --git a/app/Mail/Invoices/InvoiceWasPaid.php b/app/Mail/Invoices/InvoiceWasPaid.php new file mode 100644 index 000000000000..70ebef1fdf72 --- /dev/null +++ b/app/Mail/Invoices/InvoiceWasPaid.php @@ -0,0 +1,33 @@ +view('email.invoices.paid'); + } +} diff --git a/app/Mail/Quote/QuoteWasApproved.php b/app/Mail/Quote/QuoteWasApproved.php new file mode 100644 index 000000000000..5467cb7b7ef4 --- /dev/null +++ b/app/Mail/Quote/QuoteWasApproved.php @@ -0,0 +1,33 @@ +view('email.quotes.approved'); + } +} diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 40a2a200062e..bb88ca399f6c 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -26,6 +26,7 @@ use App\Models\PaymentTerm; use App\Services\Invoice\InvoiceService; use App\Services\Ledger\LedgerService; use App\Utils\Number; +use App\Utils\Traits\Archivable; use App\Utils\Traits\InvoiceEmailBuilder; use App\Utils\Traits\Invoice\ActionsInvoice; use App\Utils\Traits\MakesDates; diff --git a/app/Models/Quote.php b/app/Models/Quote.php index 49d4ae481971..8868db17862a 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -18,6 +18,7 @@ use App\Jobs\Invoice\CreateInvoicePdf; use App\Jobs\Quote\CreateQuotePdf; use App\Models\Filterable; use App\Services\Quote\QuoteService; +use App\Utils\Traits\Archivable; use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesInvoiceValues; diff --git a/app/PaymentDrivers/PayPalExpressPaymentDriver.php b/app/PaymentDrivers/PayPalExpressPaymentDriver.php index dc7b8193fe51..93c78b46ee49 100644 --- a/app/PaymentDrivers/PayPalExpressPaymentDriver.php +++ b/app/PaymentDrivers/PayPalExpressPaymentDriver.php @@ -158,11 +158,9 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver $this->attachInvoices($payment, $request->input('hashed_ids')); - event(new PaymentWasCreated($payment, $payment->company)); - $payment->service()->UpdateInvoicePayment(); - - //UpdateInvoicePayment::dispatchNow($payment, $payment->company); + + event(new PaymentWasCreated($payment, $payment->company)); return redirect()->route('client.payments.show', ['payment'=>$this->encodePrimaryKey($payment->id)]); } diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 058ed0b49ac6..4e34fe2eb407 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -344,12 +344,11 @@ class StripePaymentDriver extends BasePaymentDriver /* Link invoices to payment*/ $this->attachInvoices($payment, $hashed_ids); + + $payment->service()->UpdateInvoicePayment(); event(new PaymentWasCreated($payment, $payment->company)); - $payment->service()->UpdateInvoicePayment(); - //UpdateInvoicePayment::dispatchNow($payment, $payment->company); - SystemLogger::dispatch( [ 'server_response' => $payment_intent, diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 3f24490708c3..85bc5e3ec942 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -28,6 +28,7 @@ use App\Events\Payment\PaymentWasCreated; use App\Events\Payment\PaymentWasDeleted; use App\Events\Payment\PaymentWasRefunded; use App\Events\Payment\PaymentWasVoided; +use App\Events\Quote\QuoteWasApproved; use App\Events\User\UserLoggedIn; use App\Events\User\UserWasCreated; use App\Events\User\UserWasDeleted; @@ -50,6 +51,7 @@ use App\Listeners\Invoice\UpdateInvoiceActivity; use App\Listeners\Invoice\UpdateInvoiceInvitations; use App\Listeners\Misc\InvitationViewedListener; use App\Listeners\Payment\PaymentNotification; +use App\Listeners\Quote\ReachWorkflowSettings; use App\Listeners\SendVerificationNotification; use App\Listeners\SetDBListener; use App\Listeners\User\DeletedUserActivity; @@ -144,10 +146,12 @@ class EventServiceProvider extends ServiceProvider InvitationWasViewed::class => [ InvitationViewedListener::class ], - CompanyWasDeleted::class => [ DeleteCompanyDocuments::class, ], + QuoteWasApproved::class => [ + ReachWorkflowSettings::class, + ], ]; /** diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index c7c7fbc3e70e..d02986b7651f 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -71,7 +71,7 @@ class BaseRepository } $entity->delete(); - + $className = $this->getEventClass($entity, 'Archived'); if (class_exists($className)) { diff --git a/resources/views/email/invoices/paid.blade.php b/resources/views/email/invoices/paid.blade.php new file mode 100644 index 000000000000..551ae48d58b9 --- /dev/null +++ b/resources/views/email/invoices/paid.blade.php @@ -0,0 +1,26 @@ +@component('email.template.master', ['design' => 'light']) + +@slot('header') + @component('email.components.header', ['p' => 'Payment for your invoice has been completed!', 'logo' => 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png']) + Invoice paid + @endcomponent + +@endslot + +@slot('greeting') + Hello, +@endslot + +We want to inform you that payment was completed for your invoice. Amount: $10,000.00. + +@component('email.components.button', ['url' => 'https://invoiceninja.com', 'show_link' => true]) + Visit InvoiceNinja +@endcomponent + +@slot('below_card') + @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) + For any info, please visit InvoiceNinja. + @endcomponent +@endslot + +@endcomponent \ No newline at end of file diff --git a/resources/views/email/quotes/approved.blade.php b/resources/views/email/quotes/approved.blade.php new file mode 100644 index 000000000000..fcded100d7ef --- /dev/null +++ b/resources/views/email/quotes/approved.blade.php @@ -0,0 +1,26 @@ +@component('email.template.master', ['design' => 'light']) + +@slot('header') + @component('email.components.header', ['p' => 'Your quote was approved!', 'logo' => 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png']) + Quote approved + @endcomponent + +@endslot + +@slot('greeting') + Hello, +@endslot + +We want to inform you that quote was approved. Put nicer text here. + +@component('email.components.button', ['url' => 'https://invoiceninja.com', 'show_link' => true]) + Visit InvoiceNinja +@endcomponent + +@slot('below_card') + @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) + For any info, please visit InvoiceNinja. + @endcomponent +@endslot + +@endcomponent \ No newline at end of file diff --git a/resources/views/portal/ninja2020/gateways/stripe/add_credit_card.blade.php b/resources/views/portal/ninja2020/gateways/stripe/add_credit_card.blade.php index 592065c79f74..fae306867e16 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/add_credit_card.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/add_credit_card.blade.php @@ -37,7 +37,7 @@ {{ ctrans('texts.name') }}