mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 04:07:32 -05:00 
			
		
		
		
	Add payment failure emails
This commit is contained in:
		
							parent
							
								
									e2365ee0f9
								
							
						
					
					
						commit
						6eaf3632d9
					
				@ -518,7 +518,12 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public string $payment_flow = 'default'; //smooth
 | 
					    public string $payment_flow = 'default'; //smooth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $email_subject_payment_failed = '';
 | 
				
			||||||
 | 
					    public string $email_template_payment_failed = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static $casts = [
 | 
					    public static $casts = [
 | 
				
			||||||
 | 
					        'email_template_payment_failed'      => 'string',
 | 
				
			||||||
 | 
					        'email_subject_payment_failed'       => 'string',
 | 
				
			||||||
        'payment_flow'                       => 'string',
 | 
					        'payment_flow'                       => 'string',
 | 
				
			||||||
        'enable_quote_reminder1'             => 'bool',
 | 
					        'enable_quote_reminder1'             => 'bool',
 | 
				
			||||||
        'quote_num_days_reminder1'           => 'int',
 | 
					        'quote_num_days_reminder1'           => 'int',
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@ class EmailTemplateDefaults
 | 
				
			|||||||
        'email_template_custom2',
 | 
					        'email_template_custom2',
 | 
				
			||||||
        'email_template_custom3',
 | 
					        'email_template_custom3',
 | 
				
			||||||
        'email_template_purchase_order',
 | 
					        'email_template_purchase_order',
 | 
				
			||||||
 | 
					        'email_template_payment_failed'
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function getDefaultTemplate($template, $locale)
 | 
					    public static function getDefaultTemplate($template, $locale)
 | 
				
			||||||
@ -39,6 +40,8 @@ class EmailTemplateDefaults
 | 
				
			|||||||
        switch ($template) {
 | 
					        switch ($template) {
 | 
				
			||||||
            /* Template */
 | 
					            /* Template */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case 'email_template_payment_failed':
 | 
				
			||||||
 | 
					                return self::emailPaymentFailedTemplate();
 | 
				
			||||||
            case 'email_template_invoice':
 | 
					            case 'email_template_invoice':
 | 
				
			||||||
                return self::emailInvoiceTemplate();
 | 
					                return self::emailInvoiceTemplate();
 | 
				
			||||||
            case 'email_template_quote':
 | 
					            case 'email_template_quote':
 | 
				
			||||||
@ -73,6 +76,9 @@ class EmailTemplateDefaults
 | 
				
			|||||||
            case 'email_subject_invoice':
 | 
					            case 'email_subject_invoice':
 | 
				
			||||||
                return self::emailInvoiceSubject();
 | 
					                return self::emailInvoiceSubject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case 'email_subject_payment_failed':
 | 
				
			||||||
 | 
					                return self::emailPaymentFailedSubject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'email_subject_quote':
 | 
					            case 'email_subject_quote':
 | 
				
			||||||
                return self::emailQuoteSubject();
 | 
					                return self::emailQuoteSubject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -127,6 +133,16 @@ class EmailTemplateDefaults
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function emailPaymentFailedSubject()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return ctrans('texts.notification_invoice_payment_failed_subject', ['invoice' => '$number']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function emailPaymentFailedTemplate()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return '<p>$client<br><br>'.ctrans('texts.client_payment_failure_body', ['invoice' => '$number', 'amount' => '$amount']).'</p><div class="center">$gateway_payment_error</div><br><div class="center">$payment_button</div>';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function emailQuoteReminder1Subject()
 | 
					    public static function emailQuoteReminder1Subject()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return ctrans('texts.quote_reminder_subject', ['quote' => '$number', 'company' => '$company.name']);
 | 
					        return ctrans('texts.quote_reminder_subject', ['quote' => '$number', 'company' => '$company.name']);
 | 
				
			||||||
@ -135,9 +151,7 @@ class EmailTemplateDefaults
 | 
				
			|||||||
    public static function emailQuoteReminder1Body()
 | 
					    public static function emailQuoteReminder1Body()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_message = '<p>$client<br><br>'.self::transformText('quote_reminder_message').'</p><div class="center">$view_button</div>';
 | 
					        return '<p>$client<br><br>'.self::transformText('quote_reminder_message').'</p><div class="center">$view_button</div>';
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $invoice_message;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								app/Events/Invoice/InvoiceAutoBillFailed.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Events/Invoice/InvoiceAutoBillFailed.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Events\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class InvoiceAutoBillFailed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class InvoiceAutoBillFailed
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new event instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Invoice $invoice
 | 
				
			||||||
 | 
					     * @param Company $company
 | 
				
			||||||
 | 
					     * @param array $event_vars
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(public Invoice $invoice, public Company $company, public array $event_vars, public ?string $notes)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								app/Events/Invoice/InvoiceAutoBillSuccess.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Events/Invoice/InvoiceAutoBillSuccess.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Events\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class InvoiceAutoBillSuccess.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class InvoiceAutoBillSuccess
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new event instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Invoice $invoice
 | 
				
			||||||
 | 
					     * @param Company $company
 | 
				
			||||||
 | 
					     * @param array $event_vars
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(public Invoice $invoice, public Company $company, public array $event_vars)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -35,7 +35,7 @@ class PrePaymentController extends Controller
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Show the list of payments.
 | 
					     * Show the list of payments.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return Factory|View
 | 
					     * @return Factory|View|\Illuminate\Http\RedirectResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index()
 | 
					    public function index()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -84,7 +84,7 @@ class PaymentFailedMailer implements ShouldQueue
 | 
				
			|||||||
        $invoice = false;
 | 
					        $invoice = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->payment_hash) {
 | 
					        if ($this->payment_hash) {
 | 
				
			||||||
            // $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
 | 
					            
 | 
				
			||||||
            $amount = $this->payment_hash?->amount_with_fee() ?: 0;
 | 
					            $amount = $this->payment_hash?->amount_with_fee() ?: 0;
 | 
				
			||||||
            $invoice = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
 | 
					            $invoice = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										59
									
								
								app/Listeners/Invoice/InvoiceAutoBillFailedActivity.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Listeners/Invoice/InvoiceAutoBillFailedActivity.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Listeners\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InvoiceAutoBillFailedActivity implements ShouldQueue
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $activity_repo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $delay = 10;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create the event listener.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ActivityRepository $activity_repo
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(ActivityRepository $activity_repo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->activity_repo = $activity_repo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handle the event.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  object  $event
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function handle($event)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDB($event->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields = new stdClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields->user_id = $user_id;
 | 
				
			||||||
 | 
					        $fields->client_id = $event->invoice->client_id;
 | 
				
			||||||
 | 
					        $fields->company_id = $event->invoice->company_id;
 | 
				
			||||||
 | 
					        $fields->activity_type_id = Activity::AUTOBILL_FAILURE;
 | 
				
			||||||
 | 
					        $fields->invoice_id = $event->invoice->id;
 | 
				
			||||||
 | 
					        $fields->notes = $event->notes ?? '';
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								app/Listeners/Invoice/InvoiceAutoBillSuccessActivity.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								app/Listeners/Invoice/InvoiceAutoBillSuccessActivity.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Listeners\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InvoiceAutoBillSuccessActivity implements ShouldQueue
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $activity_repo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $delay = 10;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create the event listener.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ActivityRepository $activity_repo
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(ActivityRepository $activity_repo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->activity_repo = $activity_repo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handle the event.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  object  $event
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function handle($event)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDB($event->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields = new stdClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields->user_id = $user_id;
 | 
				
			||||||
 | 
					        $fields->client_id = $event->invoice->client_id;
 | 
				
			||||||
 | 
					        $fields->company_id = $event->invoice->company_id;
 | 
				
			||||||
 | 
					        $fields->activity_type_id = Activity::AUTOBILL_SUCCESS;
 | 
				
			||||||
 | 
					        $fields->invoice_id = $event->invoice->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -11,12 +11,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Mail\Admin;
 | 
					namespace App\Mail\Admin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Utils\HtmlEngine;
 | 
					use App\Utils\HtmlEngine;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use stdClass;
 | 
					use App\DataMapper\EmailTemplateDefaults;
 | 
				
			||||||
 | 
					use App\Utils\Number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClientPaymentFailureObject
 | 
					class ClientPaymentFailureObject
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -60,20 +62,20 @@ class ClientPaymentFailureObject
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        App::forgetInstance('translator');
 | 
					        App::forgetInstance('translator');
 | 
				
			||||||
        /* Init a new copy of the translator*/
 | 
					 | 
				
			||||||
        $t = app('translator');
 | 
					        $t = app('translator');
 | 
				
			||||||
        /* Set the locale*/
 | 
					 | 
				
			||||||
        App::setLocale($this->client->locale());
 | 
					        App::setLocale($this->client->locale());
 | 
				
			||||||
        /* Set customized translations _NOW_ */
 | 
					 | 
				
			||||||
        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
					        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
 | 
					        $this->invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = $this->getData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $mail_obj = new stdClass();
 | 
					        $mail_obj = new stdClass();
 | 
				
			||||||
        $mail_obj->amount = $this->getAmount();
 | 
					        $mail_obj->amount = $this->getAmount();
 | 
				
			||||||
        $mail_obj->subject = $this->getSubject();
 | 
					        $mail_obj->subject = $data['subject'];
 | 
				
			||||||
        $mail_obj->data = $this->getData();
 | 
					        $mail_obj->data = $this->getData();
 | 
				
			||||||
        $mail_obj->markdown = 'email.client.generic';
 | 
					
 | 
				
			||||||
 | 
					        $mail_obj->markdown = 'email.template.client';
 | 
				
			||||||
        $mail_obj->tag = $this->company->company_key;
 | 
					        $mail_obj->tag = $this->company->company_key;
 | 
				
			||||||
        $mail_obj->text_view = 'email.template.text';
 | 
					        $mail_obj->text_view = 'email.template.text';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -82,16 +84,32 @@ class ClientPaymentFailureObject
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function getAmount()
 | 
					    private function getAmount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
 | 
					        $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Number::formatMoney($amount, $this->client);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function getSubject()
 | 
					    private function getSubject()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return
 | 
					    
 | 
				
			||||||
            ctrans(
 | 
					        if(strlen($this->client->getSetting('email_subject_payment_failed') ?? '') > 2){
 | 
				
			||||||
                'texts.notification_invoice_payment_failed_subject',
 | 
					            return $this->client->getSetting('email_subject_payment_failed');
 | 
				
			||||||
                ['invoice' => implode(',', $this->invoices->pluck('number')->toArray())]
 | 
					        }
 | 
				
			||||||
            );
 | 
					        else {
 | 
				
			||||||
 | 
					            return EmailTemplateDefaults::getDefaultTemplate('email_subject_payment_failed', $this->client->locale());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function getBody()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					        if(strlen($this->client->getSetting('email_template_payment_failed') ?? '') > 2) {
 | 
				
			||||||
 | 
					            return $this->client->getSetting('email_template_payment_failed');
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return EmailTemplateDefaults::getDefaultTemplate('email_template_payment_failed', $this->client->locale());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function getData()
 | 
					    private function getData()
 | 
				
			||||||
@ -104,17 +122,17 @@ class ClientPaymentFailureObject
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $signature = $this->client->getSetting('email_signature');
 | 
					        $signature = $this->client->getSetting('email_signature');
 | 
				
			||||||
        $html_variables = (new HtmlEngine($invitation))->makeValues();
 | 
					        $html_variables = (new HtmlEngine($invitation))->makeValues();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $html_variables['$gateway_payment_error'] = $this->error ?? '';
 | 
				
			||||||
 | 
					        $html_variables['$total'] = $this->getAmount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $signature = str_replace(array_keys($html_variables), array_values($html_variables), $signature);
 | 
					        $signature = str_replace(array_keys($html_variables), array_values($html_variables), $signature);
 | 
				
			||||||
 | 
					        $subject = str_replace(array_keys($html_variables), array_values($html_variables), $this->getSubject());
 | 
				
			||||||
 | 
					        $content = str_replace(array_keys($html_variables), array_values($html_variables), $this->getBody());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'title' => ctrans(
 | 
					            'subject' => $subject,
 | 
				
			||||||
                'texts.notification_invoice_payment_failed_subject',
 | 
					            'body' => $content,
 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'invoice' => $this->invoices->first()->number,
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'greeting' => ctrans('texts.email_salutation', ['name' => $this->client->present()->name()]),
 | 
					 | 
				
			||||||
            'content' => ctrans('texts.client_payment_failure_body', ['invoice' => implode(',', $this->invoices->pluck('number')->toArray()), 'amount' => $this->getAmount()]),
 | 
					 | 
				
			||||||
            'signature' => $signature,
 | 
					            'signature' => $signature,
 | 
				
			||||||
            'logo' => $this->company->present()->logo(),
 | 
					            'logo' => $this->company->present()->logo(),
 | 
				
			||||||
            'settings' => $this->client->getMergedSettings(),
 | 
					            'settings' => $this->client->getMergedSettings(),
 | 
				
			||||||
 | 
				
			|||||||
@ -265,6 +265,10 @@ class Activity extends StaticModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public const QUOTE_REMINDER1_SENT = 142;
 | 
					    public const QUOTE_REMINDER1_SENT = 142;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const AUTOBILL_SUCCESS = 143; //:invoice auto billing succeeded
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const AUTOBILL_FAILURE = 144; //:invoice autobilling failed :note
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $casts = [
 | 
					    protected $casts = [
 | 
				
			||||||
        'is_system' => 'boolean',
 | 
					        'is_system' => 'boolean',
 | 
				
			||||||
        'updated_at' => 'timestamp',
 | 
					        'updated_at' => 'timestamp',
 | 
				
			||||||
@ -286,7 +290,6 @@ class Activity extends StaticModel
 | 
				
			|||||||
        return $this->encodePrimaryKey($this->id);
 | 
					        return $this->encodePrimaryKey($this->id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getEntityType()
 | 
					    public function getEntityType()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return self::class;
 | 
					        return self::class;
 | 
				
			||||||
 | 
				
			|||||||
@ -31,6 +31,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundExceptio
 | 
				
			|||||||
 * @package App\Models
 | 
					 * @package App\Models
 | 
				
			||||||
 * @property-read mixed $hashed_id
 | 
					 * @property-read mixed $hashed_id
 | 
				
			||||||
 * @property string $number
 | 
					 * @property string $number
 | 
				
			||||||
 | 
					 * @property object|null $e_invoice
 | 
				
			||||||
 * @property int $company_id
 | 
					 * @property int $company_id
 | 
				
			||||||
 * @property int $id
 | 
					 * @property int $id
 | 
				
			||||||
 * @property int $user_id
 | 
					 * @property int $user_id
 | 
				
			||||||
@ -296,17 +297,12 @@ class BaseModel extends Model
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // special catch here for einvoicing eventing
 | 
					        // special catch here for einvoicing eventing
 | 
				
			||||||
        if($event_id == Webhook::EVENT_SENT_INVOICE && $this->e_invoice){
 | 
					        if($event_id == Webhook::EVENT_SENT_INVOICE && ($this instanceof Invoice) && $this->e_invoice){
 | 
				
			||||||
            $this->handleEinvoiceSending();
 | 
					            // Einvoice
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function handleEinvoiceSending()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the base64 encoded PDF string of the entity
 | 
					     * Returns the base64 encoded PDF string of the entity
 | 
				
			||||||
     * @deprecated - unused implementation
 | 
					     * @deprecated - unused implementation
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,18 @@ class UpdatePaymentMethods
 | 
				
			|||||||
            $this->addOrUpdateCard($method, $customer->id, $client, GatewayType::CREDIT_CARD);
 | 
					            $this->addOrUpdateCard($method, $customer->id, $client, GatewayType::CREDIT_CARD);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $link_methods = PaymentMethod::all(
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'customer' => $customer->id,
 | 
				
			||||||
 | 
					                'type' => 'link',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            $this->stripe->stripe_connect_auth
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach ($link_methods as $method) {
 | 
				
			||||||
 | 
					            $this->addOrUpdateCard($method, $customer->id, $client, GatewayType::CREDIT_CARD);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $alipay_methods = PaymentMethod::all(
 | 
					        $alipay_methods = PaymentMethod::all(
 | 
				
			||||||
            [
 | 
					            [
 | 
				
			||||||
            'customer' => $customer->id,
 | 
					            'customer' => $customer->id,
 | 
				
			||||||
@ -217,9 +229,14 @@ class UpdatePaymentMethods
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function buildPaymentMethodMeta(PaymentMethod $method, $type_id)
 | 
					    private function buildPaymentMethodMeta(PaymentMethod $method, $type_id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        nlog($method->type);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        switch ($type_id) {
 | 
					        switch ($type_id) {
 | 
				
			||||||
            case GatewayType::CREDIT_CARD:
 | 
					            case GatewayType::CREDIT_CARD:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if($method->type == 'link')
 | 
				
			||||||
 | 
					                    return new \stdClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /**
 | 
					                /**
 | 
				
			||||||
                 * @class \Stripe\PaymentMethod $method
 | 
					                 * @class \Stripe\PaymentMethod $method
 | 
				
			||||||
                 * @property \Stripe\StripeObject $card
 | 
					                 * @property \Stripe\StripeObject $card
 | 
				
			||||||
 | 
				
			|||||||
@ -155,6 +155,8 @@ use App\Listeners\Activity\TaskUpdatedActivity;
 | 
				
			|||||||
use App\Listeners\Invoice\InvoiceEmailActivity;
 | 
					use App\Listeners\Invoice\InvoiceEmailActivity;
 | 
				
			||||||
use App\Listeners\SendVerificationNotification;
 | 
					use App\Listeners\SendVerificationNotification;
 | 
				
			||||||
use App\Events\Credit\CreditWasEmailedAndFailed;
 | 
					use App\Events\Credit\CreditWasEmailedAndFailed;
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceAutoBillFailed;
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceAutoBillSuccess;
 | 
				
			||||||
use App\Listeners\Activity\CreatedQuoteActivity;
 | 
					use App\Listeners\Activity\CreatedQuoteActivity;
 | 
				
			||||||
use App\Listeners\Activity\DeleteClientActivity;
 | 
					use App\Listeners\Activity\DeleteClientActivity;
 | 
				
			||||||
use App\Listeners\Activity\DeleteCreditActivity;
 | 
					use App\Listeners\Activity\DeleteCreditActivity;
 | 
				
			||||||
@ -250,6 +252,8 @@ use App\Events\RecurringExpense\RecurringExpenseWasArchived;
 | 
				
			|||||||
use App\Events\RecurringExpense\RecurringExpenseWasRestored;
 | 
					use App\Events\RecurringExpense\RecurringExpenseWasRestored;
 | 
				
			||||||
use App\Events\RecurringInvoice\RecurringInvoiceWasArchived;
 | 
					use App\Events\RecurringInvoice\RecurringInvoiceWasArchived;
 | 
				
			||||||
use App\Events\RecurringInvoice\RecurringInvoiceWasRestored;
 | 
					use App\Events\RecurringInvoice\RecurringInvoiceWasRestored;
 | 
				
			||||||
 | 
					use App\Listeners\Invoice\InvoiceAutoBillFailedActivity;
 | 
				
			||||||
 | 
					use App\Listeners\Invoice\InvoiceAutoBillSuccessActivity;
 | 
				
			||||||
use App\Listeners\PurchaseOrder\CreatePurchaseOrderActivity;
 | 
					use App\Listeners\PurchaseOrder\CreatePurchaseOrderActivity;
 | 
				
			||||||
use App\Listeners\PurchaseOrder\PurchaseOrderViewedActivity;
 | 
					use App\Listeners\PurchaseOrder\PurchaseOrderViewedActivity;
 | 
				
			||||||
use App\Listeners\PurchaseOrder\UpdatePurchaseOrderActivity;
 | 
					use App\Listeners\PurchaseOrder\UpdatePurchaseOrderActivity;
 | 
				
			||||||
@ -426,6 +430,12 @@ class EventServiceProvider extends ServiceProvider
 | 
				
			|||||||
            ExpenseRestoredActivity::class,
 | 
					            ExpenseRestoredActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        //Invoices
 | 
					        //Invoices
 | 
				
			||||||
 | 
					        InvoiceAutoBillSuccess::class => [
 | 
				
			||||||
 | 
					            InvoiceAutoBillSuccessActivity::class,
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        InvoiceAutoBillFailed::class => [
 | 
				
			||||||
 | 
					            InvoiceAutoBillFailedActivity::class,
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
        InvoiceWasMarkedSent::class => [
 | 
					        InvoiceWasMarkedSent::class => [
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvoiceWasUpdated::class => [
 | 
					        InvoiceWasUpdated::class => [
 | 
				
			||||||
 | 
				
			|||||||
@ -222,6 +222,10 @@ class StaticServiceProvider extends ServiceProvider
 | 
				
			|||||||
                    'subject' => EmailTemplateDefaults::emailPaymentSubject(),
 | 
					                    'subject' => EmailTemplateDefaults::emailPaymentSubject(),
 | 
				
			||||||
                    'body' => EmailTemplateDefaults::emailPaymentTemplate(),
 | 
					                    'body' => EmailTemplateDefaults::emailPaymentTemplate(),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
 | 
					                'payment_failed' => [
 | 
				
			||||||
 | 
					                    'subject' => EmailTemplateDefaults::emailPaymentFailedSubject(),
 | 
				
			||||||
 | 
					                    'body' => EmailTemplateDefaults::emailPaymentFailedTemplate(),
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
                'quote_reminder1' => [
 | 
					                'quote_reminder1' => [
 | 
				
			||||||
                    'subject' => EmailTemplateDefaults::emailQuoteReminder1Subject(),
 | 
					                    'subject' => EmailTemplateDefaults::emailQuoteReminder1Subject(),
 | 
				
			||||||
                    'body' => EmailTemplateDefaults::emailQuoteReminder1Body(),
 | 
					                    'body' => EmailTemplateDefaults::emailQuoteReminder1Body(),
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,8 @@ use App\Models\PaymentHash;
 | 
				
			|||||||
use App\Models\PaymentType;
 | 
					use App\Models\PaymentType;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
use App\DataMapper\InvoiceItem;
 | 
					use App\DataMapper\InvoiceItem;
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceAutoBillFailed;
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceAutoBillSuccess;
 | 
				
			||||||
use App\Factory\PaymentFactory;
 | 
					use App\Factory\PaymentFactory;
 | 
				
			||||||
use App\Services\AbstractService;
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
use App\Models\ClientGatewayToken;
 | 
					use App\Models\ClientGatewayToken;
 | 
				
			||||||
@ -157,6 +159,8 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nlog('payment NOT captured for '.$this->invoice->number.' with error '.$e->getMessage());
 | 
					            nlog('payment NOT captured for '.$this->invoice->number.' with error '.$e->getMessage());
 | 
				
			||||||
 | 
					            event(new InvoiceAutoBillFailed($this->invoice, $this->invoice->company, Ninja::eventVars(), $e->getMessage()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->auto_bill_tries += 1;
 | 
					        $this->invoice->auto_bill_tries += 1;
 | 
				
			||||||
@ -170,6 +174,7 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if ($payment) {
 | 
					        if ($payment) {
 | 
				
			||||||
            info('Auto Bill payment captured for '.$this->invoice->number);
 | 
					            info('Auto Bill payment captured for '.$this->invoice->number);
 | 
				
			||||||
 | 
					            event(new InvoiceAutoBillSuccess($this->invoice, $this->invoice->company, Ninja::eventVars()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -733,6 +733,7 @@ class HtmlEngine
 | 
				
			|||||||
        $data['$payment.number'] = ['value' => '', 'label' => ctrans('texts.payment_number')];
 | 
					        $data['$payment.number'] = ['value' => '', 'label' => ctrans('texts.payment_number')];
 | 
				
			||||||
        $data['$payment.transaction_reference'] = ['value' => '', 'label' => ctrans('texts.transaction_reference')];
 | 
					        $data['$payment.transaction_reference'] = ['value' => '', 'label' => ctrans('texts.transaction_reference')];
 | 
				
			||||||
        $data['$payment.refunded'] = ['value' => '', 'label' => ctrans('texts.refund')];
 | 
					        $data['$payment.refunded'] = ['value' => '', 'label' => ctrans('texts.refund')];
 | 
				
			||||||
 | 
					        $data['$gateway_payment_error'] = ['value' => '', 'label' => ctrans('texts.error')];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->entity_string == 'invoice' && $this->entity->net_payments()->exists()) {
 | 
					        if ($this->entity_string == 'invoice' && $this->entity->net_payments()->exists()) {
 | 
				
			||||||
            $payment_list = '<br><br>';
 | 
					            $payment_list = '<br><br>';
 | 
				
			||||||
 | 
				
			|||||||
@ -5321,6 +5321,9 @@ $lang = array(
 | 
				
			|||||||
    'applies_to' => 'Applies To',
 | 
					    'applies_to' => 'Applies To',
 | 
				
			||||||
    'accept_purchase_order' => 'Accept Purchase Order',
 | 
					    'accept_purchase_order' => 'Accept Purchase Order',
 | 
				
			||||||
    'round_to_seconds' => 'Round To Seconds',
 | 
					    'round_to_seconds' => 'Round To Seconds',
 | 
				
			||||||
 | 
					    'activity_142' => 'Quote :number Reminder 1 Sent',
 | 
				
			||||||
 | 
					    'activity_143' => 'Auto Bill succeeded for Invoice :invoice',
 | 
				
			||||||
 | 
					    'activity_144' => 'Auto Bill failed for Invoice :invoice. :notes',
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return $lang;
 | 
					return $lang;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user