mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 22:07:33 -05:00 
			
		
		
		
	
						commit
						2ed241e7c8
					
				@ -2,6 +2,15 @@
 | 
			
		||||
 | 
			
		||||
## [Unreleased (daily channel)](https://github.com/invoiceninja/invoiceninja/tree/v5-develop)
 | 
			
		||||
## Fixed:
 | 
			
		||||
- Fix User created/updated/deleted Actvity display format
 | 
			
		||||
- Fix for Stripe autobill / token regression
 | 
			
		||||
 | 
			
		||||
## Added:
 | 
			
		||||
- Invoice / Quote / Credit created notifications
 | 
			
		||||
- Logout route - deletes all auth tokens
 | 
			
		||||
 | 
			
		||||
## [v5.1.54-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.50-release)
 | 
			
		||||
## Fixed:
 | 
			
		||||
- Fixes for e-mails, encoding & parsing invalid HTML
 | 
			
		||||
 | 
			
		||||
## [v5.1.50-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.50-release)
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
5.1.54
 | 
			
		||||
5.1.55
 | 
			
		||||
@ -183,6 +183,16 @@ class InvoiceSum
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allow us to get the entity without persisting it
 | 
			
		||||
     * @return Invoice the temp
 | 
			
		||||
     */
 | 
			
		||||
    public function getTempEntity()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setCalculatedAttributes();
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getInvoice()
 | 
			
		||||
    {
 | 
			
		||||
        //Build invoice values here and return Invoice
 | 
			
		||||
 | 
			
		||||
@ -196,6 +196,12 @@ class InvoiceSumInclusive
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTempEntity()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setCalculatedAttributes();
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getInvoice()
 | 
			
		||||
    {
 | 
			
		||||
        //Build invoice values here and return Invoice
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ use App\DataMapper\Analytics\LoginSuccess;
 | 
			
		||||
use App\Http\Controllers\BaseController;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Jobs\Account\CreateAccount;
 | 
			
		||||
use App\Jobs\Company\CreateCompanyToken;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use App\Libraries\OAuth\OAuth;
 | 
			
		||||
use App\Libraries\OAuth\Providers\Google;
 | 
			
		||||
@ -199,6 +200,15 @@ class LoginController extends BaseController
 | 
			
		||||
            $cu = CompanyUser::query()
 | 
			
		||||
                  ->where('user_id', auth()->user()->id);
 | 
			
		||||
 | 
			
		||||
            $cu->first()->account->companies->each(function ($company) use($cu, $request){
 | 
			
		||||
 | 
			
		||||
                if($company->tokens()->where('is_system', true)->count() == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    CreateCompanyToken::dispatchNow($company, $cu->first()->user, $request->server('HTTP_USER_AGENT'));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return $this->listResponse($cu);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
@ -262,9 +272,16 @@ class LoginController extends BaseController
 | 
			
		||||
 | 
			
		||||
        $cu = CompanyUser::query()
 | 
			
		||||
                          ->where('user_id', $company_token->user_id);
 | 
			
		||||
        //->where('company_id', $company_token->company_id);
 | 
			
		||||
 | 
			
		||||
        //$ct = CompanyUser::whereUserId(auth()->user()->id);
 | 
			
		||||
 | 
			
		||||
        $cu->first()->account->companies->each(function ($company) use($cu, $request){
 | 
			
		||||
 | 
			
		||||
            if($company->tokens()->where('is_system', true)->count() == 0)
 | 
			
		||||
            {
 | 
			
		||||
                CreateCompanyToken::dispatchNow($company, $cu->first()->user, $request->server('HTTP_USER_AGENT'));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return $this->refreshResponse($cu);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -317,6 +334,14 @@ class LoginController extends BaseController
 | 
			
		||||
                $cu = CompanyUser::query()
 | 
			
		||||
                                  ->where('user_id', auth()->user()->id);
 | 
			
		||||
 | 
			
		||||
                $cu->first()->account->companies->each(function ($company) use($cu){
 | 
			
		||||
 | 
			
		||||
                    if($company->tokens()->where('is_system', true)->count() == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        CreateCompanyToken::dispatchNow($company, $cu->first()->user, request()->server('HTTP_USER_AGENT'));
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return $this->listResponse($cu);
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
@ -348,9 +373,17 @@ class LoginController extends BaseController
 | 
			
		||||
            $timeout = auth()->user()->company()->default_password_timeout / 60000;
 | 
			
		||||
            Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
 | 
			
		||||
 | 
			
		||||
            $ct = CompanyUser::whereUserId(auth()->user()->id);
 | 
			
		||||
            $cu = CompanyUser::whereUserId(auth()->user()->id);
 | 
			
		||||
 | 
			
		||||
            return $this->listResponse($ct);
 | 
			
		||||
            $cu->first()->account->companies->each(function ($company) use($cu){
 | 
			
		||||
 | 
			
		||||
                if($company->tokens()->where('is_system', true)->count() == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    CreateCompanyToken::dispatchNow($company, $cu->first()->user, request()->server('HTTP_USER_AGENT'));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return $this->listResponse($cu);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,9 @@
 | 
			
		||||
namespace App\Http\Requests\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Http\Requests\Request;
 | 
			
		||||
use App\Http\ValidationRules\Invoice\InvoiceBalanceSanity;
 | 
			
		||||
use App\Http\ValidationRules\Invoice\LockedInvoiceRule;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Utils\Traits\ChecksEntityStatus;
 | 
			
		||||
use App\Utils\Traits\CleanLineItems;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
@ -55,6 +57,9 @@ class UpdateInvoiceRequest extends Request
 | 
			
		||||
 | 
			
		||||
        $rules['line_items'] = 'array';
 | 
			
		||||
 | 
			
		||||
        if($this->input('status_id') != Invoice::STATUS_DRAFT)
 | 
			
		||||
            $rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
 | 
			
		||||
 | 
			
		||||
        return $rules;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								app/Http/ValidationRules/Invoice/InvoiceBalanceSanity.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								app/Http/ValidationRules/Invoice/InvoiceBalanceSanity.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Http\ValidationRules\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use Illuminate\Contracts\Validation\Rule;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class LockedInvoiceRule.
 | 
			
		||||
 */
 | 
			
		||||
class InvoiceBalanceSanity implements Rule
 | 
			
		||||
{
 | 
			
		||||
    public $invoice;
 | 
			
		||||
 | 
			
		||||
    public $input;
 | 
			
		||||
 | 
			
		||||
    private $message;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function __construct(Invoice $invoice, $input)
 | 
			
		||||
    {
 | 
			
		||||
        $this->invoice = $invoice;
 | 
			
		||||
        $this->input = $input;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $attribute
 | 
			
		||||
     * @param mixed $value
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function passes($attribute, $value)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->checkIfInvoiceBalanceIsSane(); //if it exists, return false!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function message()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->message;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    private function checkIfInvoiceBalanceIsSane() : bool
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $this->invoice->line_items = $this->input['line_items'];
 | 
			
		||||
 | 
			
		||||
        DB::beginTransaction();
 | 
			
		||||
 
 | 
			
		||||
            $temp_invoice = $this->invoice->calc()->getTempEntity();
 | 
			
		||||
 
 | 
			
		||||
        DB::rollBack();
 | 
			
		||||
 | 
			
		||||
        if($temp_invoice->balance < 0){
 | 
			
		||||
            $this->message = 'Invoice balance cannot go negative';
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								app/Listeners/Credit/CreditCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Listeners/Credit/CreditCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Credit Ninja (https://creditninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/creditninja/creditninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2021. Credit Ninja LLC (https://creditninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Listeners\Credit;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Mail\NinjaMailer;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use App\Mail\Admin\EntityCreatedObject;
 | 
			
		||||
use App\Notifications\Admin\EntitySentNotification;
 | 
			
		||||
use App\Utils\Traits\Notifications\UserNotifies;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
 | 
			
		||||
class CreditCreatedNotification implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use UserNotifies;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle the event.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  object  $event
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function handle($event)
 | 
			
		||||
    {
 | 
			
		||||
        MultiDB::setDb($event->company->db);
 | 
			
		||||
 | 
			
		||||
        $first_notification_sent = true;
 | 
			
		||||
 | 
			
		||||
        $credit = $event->credit;
 | 
			
		||||
 | 
			
		||||
        $nmo = new NinjaMailerObject;
 | 
			
		||||
        $nmo->mailable = new NinjaMailer( (new EntityCreatedObject($credit, 'credit'))->build() );
 | 
			
		||||
        $nmo->company = $credit->company;
 | 
			
		||||
        $nmo->settings = $credit->company->settings;
 | 
			
		||||
 | 
			
		||||
        /* We loop through each user and determine whether they need to be notified */
 | 
			
		||||
        foreach ($event->company->company_users as $company_user) {
 | 
			
		||||
 | 
			
		||||
            /* The User */
 | 
			
		||||
            $user = $company_user->user;
 | 
			
		||||
 | 
			
		||||
            /* This is only here to handle the alternate message channels - ie Slack */
 | 
			
		||||
            // $notification = new EntitySentNotification($event->invitation, 'credit');
 | 
			
		||||
 | 
			
		||||
            /* Returns an array of notification methods */
 | 
			
		||||
            $methods = $this->findUserNotificationTypes($credit->invitations()->first(), $company_user, 'credit', ['all_notifications', 'credit_created', 'credit_created_all']);
 | 
			
		||||
 | 
			
		||||
            /* If one of the methods is email then we fire the EntitySentMailer */
 | 
			
		||||
            if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
 | 
			
		||||
                unset($methods[$key]);
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
                $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                NinjaMailerJob::dispatch($nmo);
 | 
			
		||||
                
 | 
			
		||||
                /* This prevents more than one notification being sent */
 | 
			
		||||
                $first_notification_sent = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Override the methods in the Notification Class */
 | 
			
		||||
            // $notification->method = $methods;
 | 
			
		||||
 | 
			
		||||
            //  Notify on the alternate channels 
 | 
			
		||||
            // $user->notify($notification);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								app/Listeners/Invoice/InvoiceCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Listeners/Invoice/InvoiceCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Listeners\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Mail\NinjaMailer;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use App\Mail\Admin\EntityCreatedObject;
 | 
			
		||||
use App\Notifications\Admin\EntitySentNotification;
 | 
			
		||||
use App\Utils\Traits\Notifications\UserNotifies;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
 | 
			
		||||
class InvoiceCreatedNotification implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use UserNotifies;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle the event.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  object  $event
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function handle($event)
 | 
			
		||||
    {
 | 
			
		||||
        MultiDB::setDb($event->company->db);
 | 
			
		||||
 | 
			
		||||
        $first_notification_sent = true;
 | 
			
		||||
 | 
			
		||||
        $invoice = $event->invoice;
 | 
			
		||||
 | 
			
		||||
        $nmo = new NinjaMailerObject;
 | 
			
		||||
        $nmo->mailable = new NinjaMailer( (new EntityCreatedObject($invoice, 'invoice'))->build() );
 | 
			
		||||
        $nmo->company = $invoice->company;
 | 
			
		||||
        $nmo->settings = $invoice->company->settings;
 | 
			
		||||
 | 
			
		||||
        /* We loop through each user and determine whether they need to be notified */
 | 
			
		||||
        foreach ($event->company->company_users as $company_user) {
 | 
			
		||||
 | 
			
		||||
            /* The User */
 | 
			
		||||
            $user = $company_user->user;
 | 
			
		||||
 | 
			
		||||
            /* This is only here to handle the alternate message channels - ie Slack */
 | 
			
		||||
            // $notification = new EntitySentNotification($event->invitation, 'invoice');
 | 
			
		||||
 | 
			
		||||
            /* Returns an array of notification methods */
 | 
			
		||||
            $methods = $this->findUserNotificationTypes($invoice->invitations()->first(), $company_user, 'invoice', ['all_notifications', 'invoice_created', 'invoice_created_all']);
 | 
			
		||||
 | 
			
		||||
            /* If one of the methods is email then we fire the EntitySentMailer */
 | 
			
		||||
            if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
 | 
			
		||||
                unset($methods[$key]);
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
                $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                NinjaMailerJob::dispatch($nmo);
 | 
			
		||||
                
 | 
			
		||||
                /* This prevents more than one notification being sent */
 | 
			
		||||
                $first_notification_sent = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Override the methods in the Notification Class */
 | 
			
		||||
            // $notification->method = $methods;
 | 
			
		||||
 | 
			
		||||
            //  Notify on the alternate channels 
 | 
			
		||||
            // $user->notify($notification);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								app/Listeners/Quote/QuoteCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Listeners/Quote/QuoteCreatedNotification.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Quote Ninja (https://quoteninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/quoteninja/quoteninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2021. Quote Ninja LLC (https://quoteninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Listeners\Quote;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Mail\NinjaMailer;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use App\Mail\Admin\EntityCreatedObject;
 | 
			
		||||
use App\Notifications\Admin\EntitySentNotification;
 | 
			
		||||
use App\Utils\Traits\Notifications\UserNotifies;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
 | 
			
		||||
class QuoteCreatedNotification implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use UserNotifies;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle the event.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  object  $event
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function handle($event)
 | 
			
		||||
    {
 | 
			
		||||
        MultiDB::setDb($event->company->db);
 | 
			
		||||
 | 
			
		||||
        $first_notification_sent = true;
 | 
			
		||||
 | 
			
		||||
        $quote = $event->quote;
 | 
			
		||||
 | 
			
		||||
        $nmo = new NinjaMailerObject;
 | 
			
		||||
        $nmo->mailable = new NinjaMailer( (new EntityCreatedObject($quote, 'quote'))->build() );
 | 
			
		||||
        $nmo->company = $quote->company;
 | 
			
		||||
        $nmo->settings = $quote->company->settings;
 | 
			
		||||
 | 
			
		||||
        /* We loop through each user and determine whether they need to be notified */
 | 
			
		||||
        foreach ($event->company->company_users as $company_user) {
 | 
			
		||||
 | 
			
		||||
            /* The User */
 | 
			
		||||
            $user = $company_user->user;
 | 
			
		||||
 | 
			
		||||
            /* This is only here to handle the alternate message channels - ie Slack */
 | 
			
		||||
            // $notification = new EntitySentNotification($event->invitation, 'quote');
 | 
			
		||||
 | 
			
		||||
            /* Returns an array of notification methods */
 | 
			
		||||
            $methods = $this->findUserNotificationTypes($quote->invitations()->first(), $company_user, 'quote', ['all_notifications', 'quote_created', 'quote_created_all']);
 | 
			
		||||
 | 
			
		||||
            /* If one of the methods is email then we fire the EntitySentMailer */
 | 
			
		||||
            if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
 | 
			
		||||
                unset($methods[$key]);
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
                $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                NinjaMailerJob::dispatch($nmo);
 | 
			
		||||
                
 | 
			
		||||
                /* This prevents more than one notification being sent */
 | 
			
		||||
                $first_notification_sent = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Override the methods in the Notification Class */
 | 
			
		||||
            // $notification->method = $methods;
 | 
			
		||||
 | 
			
		||||
            //  Notify on the alternate channels 
 | 
			
		||||
            // $user->notify($notification);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -43,8 +43,8 @@ class ArchivedUserActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $event->user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name . " Archived User";
 | 
			
		||||
        $fields->user_id = $event->creating_user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name . " Archived User " . $event->user->present()->name();
 | 
			
		||||
 | 
			
		||||
        $fields->company_id = $event->company->id;
 | 
			
		||||
        $fields->activity_type_id = Activity::ARCHIVE_USER;
 | 
			
		||||
 | 
			
		||||
@ -43,8 +43,8 @@ class CreatedUserActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $event->user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Created the user";
 | 
			
		||||
        $fields->user_id = $event->creating_user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Created the user " . $event->user->present()->name();
 | 
			
		||||
        $fields->company_id = $event->company->id;
 | 
			
		||||
        $fields->activity_type_id = Activity::CREATE_USER;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -48,8 +48,8 @@ class DeletedUserActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $event->user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name . " Deleted User";
 | 
			
		||||
        $fields->user_id = $event->creating_user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Deleted the user " . $event->user->present()->name();
 | 
			
		||||
        $fields->company_id = $event->company->id;
 | 
			
		||||
        $fields->activity_type_id = Activity::DELETE_USER;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,8 +43,8 @@ class RestoredUserActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $event->user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Restored user";        
 | 
			
		||||
        $fields->user_id = $creating_user->user->id;
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Restored user " . $event->user->present()->name();
 | 
			
		||||
 | 
			
		||||
        $fields->company_id = $event->company->id;
 | 
			
		||||
        $fields->activity_type_id = Activity::RESTORE_USER;
 | 
			
		||||
 | 
			
		||||
@ -42,8 +42,9 @@ class UpdatedUserActivity implements ShouldQueue
 | 
			
		||||
        MultiDB::setDb($event->company->db);
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
        $fields->user_id = $event->user->id;    
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name . " Updated user";
 | 
			
		||||
        $fields->user_id = $event->creating_user->id;    
 | 
			
		||||
        $fields->notes = $event->creating_user->present()->name() . " Updated user " . $event->user->present()->name();
 | 
			
		||||
 | 
			
		||||
        $fields->company_id = $event->company->id;
 | 
			
		||||
        $fields->activity_type_id = Activity::UPDATE_USER;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										127
									
								
								app/Mail/Admin/EntityCreatedObject.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								app/Mail/Admin/EntityCreatedObject.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Mail\Admin;
 | 
			
		||||
 | 
			
		||||
use App\Utils\Number;
 | 
			
		||||
use stdClass;
 | 
			
		||||
 | 
			
		||||
class EntityCreatedObject
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public $entity_type;
 | 
			
		||||
 | 
			
		||||
    public $entity;
 | 
			
		||||
 | 
			
		||||
    public $contact;
 | 
			
		||||
 | 
			
		||||
    public $company;
 | 
			
		||||
 | 
			
		||||
    public $settings;
 | 
			
		||||
 | 
			
		||||
    private $template_subject;
 | 
			
		||||
 | 
			
		||||
    private $template_body;
 | 
			
		||||
 | 
			
		||||
    public function __construct($entity, $entity_type)
 | 
			
		||||
    {
 | 
			
		||||
        $this->entity_type = $entity_type;
 | 
			
		||||
        $this->entity = $entity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function build()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $this->contact = $this->entity->invitations()->first()->contact;
 | 
			
		||||
        $this->company = $this->entity->company;
 | 
			
		||||
 | 
			
		||||
        $this->setTemplate();
 | 
			
		||||
 | 
			
		||||
        $mail_obj = new stdClass;
 | 
			
		||||
        $mail_obj->amount = $this->getAmount();
 | 
			
		||||
        $mail_obj->subject = $this->getSubject();
 | 
			
		||||
        $mail_obj->data = $this->getData();
 | 
			
		||||
        $mail_obj->markdown = 'email.admin.generic';
 | 
			
		||||
        $mail_obj->tag = $this->company->company_key;
 | 
			
		||||
 | 
			
		||||
        return $mail_obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function setTemplate()
 | 
			
		||||
    {
 | 
			
		||||
        // nlog($this->template);
 | 
			
		||||
 | 
			
		||||
        switch ($this->entity_type) {
 | 
			
		||||
            case 'invoice':
 | 
			
		||||
                $this->template_subject = "texts.notification_invoice_created_subject";
 | 
			
		||||
                $this->template_body = "texts.notification_invoice_sent";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'quote':
 | 
			
		||||
                $this->template_subject = "texts.notification_quote_created_subject";
 | 
			
		||||
                $this->template_body = "texts.notification_quote_sent";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'credit':
 | 
			
		||||
                $this->template_subject = "texts.notification_credit_created_subject";
 | 
			
		||||
                $this->template_body = "texts.notification_credit_sent";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                $this->template_subject = "texts.notification_invoice_created_subject";
 | 
			
		||||
                $this->template_body = "texts.notification_invoice_sent";
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getAmount()
 | 
			
		||||
    {
 | 
			
		||||
        return Number::formatMoney($this->entity->amount, $this->entity->client);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getSubject()
 | 
			
		||||
    {
 | 
			
		||||
        return
 | 
			
		||||
            ctrans(
 | 
			
		||||
                $this->template_subject,
 | 
			
		||||
                [
 | 
			
		||||
                        'client' => $this->contact->present()->name(),
 | 
			
		||||
                        'invoice' => $this->entity->number,
 | 
			
		||||
                    ]
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getMessage()
 | 
			
		||||
    {
 | 
			
		||||
        return ctrans(
 | 
			
		||||
                $this->template_body,
 | 
			
		||||
                [
 | 
			
		||||
                    'amount' => $this->getAmount(),
 | 
			
		||||
                    'client' => $this->contact->present()->name(),
 | 
			
		||||
                    'invoice' => $this->entity->number,
 | 
			
		||||
                ]
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getData()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->entity->client->getMergedSettings();
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'title' => $this->getSubject(),
 | 
			
		||||
            'message' => $this->getMessage(),
 | 
			
		||||
            'url' => $this->entity->invitations()->first()->getAdminLink(),
 | 
			
		||||
            'button' => ctrans("texts.view_{$this->entity_type}"),
 | 
			
		||||
            'signature' => $settings->email_signature,
 | 
			
		||||
            'logo' => $this->company->present()->logo(),
 | 
			
		||||
            'settings' => $settings,
 | 
			
		||||
            'whitelabel' => $this->company->account->isPaid() ? true : false,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -69,14 +69,18 @@ class Charge
 | 
			
		||||
        $response = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $response = $local_stripe->paymentIntents->create([
 | 
			
		||||
 | 
			
		||||
            $data = [
 | 
			
		||||
              'amount' => $this->stripe->convertToStripeAmount($amount, $this->stripe->client->currency()->precision),
 | 
			
		||||
              'currency' => $this->stripe->client->getCurrencyCode(),
 | 
			
		||||
              'payment_method' => $cgt->token,
 | 
			
		||||
              'customer' => $cgt->gateway_customer_reference,
 | 
			
		||||
              'confirm' => true,
 | 
			
		||||
              'description' => $description,
 | 
			
		||||
            ]);
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            $response = $this->stripe->createPaymentIntent($data);
 | 
			
		||||
            // $response = $local_stripe->paymentIntents->create($data);
 | 
			
		||||
 | 
			
		||||
            SystemLogger::dispatch($response, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client);
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
 | 
			
		||||
@ -127,6 +127,7 @@ use App\Listeners\Activity\VendorDeletedActivity;
 | 
			
		||||
use App\Listeners\Activity\VendorRestoredActivity;
 | 
			
		||||
use App\Listeners\Activity\VendorUpdatedActivity;
 | 
			
		||||
use App\Listeners\Contact\UpdateContactLastLogin;
 | 
			
		||||
use App\Listeners\Credit\CreditCreatedNotification;
 | 
			
		||||
use App\Listeners\Credit\CreditEmailedNotification;
 | 
			
		||||
use App\Listeners\Credit\CreditRestoredActivity;
 | 
			
		||||
use App\Listeners\Credit\CreditViewedActivity;
 | 
			
		||||
@ -136,6 +137,7 @@ use App\Listeners\Invoice\CreateInvoiceHtmlBackup;
 | 
			
		||||
use App\Listeners\Invoice\CreateInvoicePdf;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceArchivedActivity;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceCancelledActivity;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceCreatedNotification;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceDeletedActivity;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceEmailActivity;
 | 
			
		||||
use App\Listeners\Invoice\InvoiceEmailFailedActivity;
 | 
			
		||||
@ -155,6 +157,7 @@ use App\Listeners\Payment\PaymentNotification;
 | 
			
		||||
use App\Listeners\Payment\PaymentRestoredActivity;
 | 
			
		||||
use App\Listeners\Quote\QuoteApprovedActivity;
 | 
			
		||||
use App\Listeners\Quote\QuoteArchivedActivity;
 | 
			
		||||
use App\Listeners\Quote\QuoteCreatedNotification;
 | 
			
		||||
use App\Listeners\Quote\QuoteDeletedActivity;
 | 
			
		||||
use App\Listeners\Quote\QuoteEmailActivity;
 | 
			
		||||
use App\Listeners\Quote\QuoteEmailedNotification;
 | 
			
		||||
@ -260,6 +263,7 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
        ],
 | 
			
		||||
        CreditWasCreated::class => [
 | 
			
		||||
            CreatedCreditActivity::class,
 | 
			
		||||
            CreditCreatedNotification::class,
 | 
			
		||||
        ],
 | 
			
		||||
        CreditWasDeleted::class => [
 | 
			
		||||
            DeleteCreditActivity::class,
 | 
			
		||||
@ -318,6 +322,7 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
        ],
 | 
			
		||||
        InvoiceWasCreated::class => [
 | 
			
		||||
            CreateInvoiceActivity::class,
 | 
			
		||||
            InvoiceCreatedNotification::class,
 | 
			
		||||
        //    CreateInvoicePdf::class,
 | 
			
		||||
        ],
 | 
			
		||||
        InvoiceWasPaid::class => [
 | 
			
		||||
@ -373,6 +378,7 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
        ],
 | 
			
		||||
        QuoteWasCreated::class => [
 | 
			
		||||
            CreatedQuoteActivity::class,
 | 
			
		||||
            QuoteCreatedNotification::class,
 | 
			
		||||
        ],
 | 
			
		||||
        QuoteWasUpdated::class => [
 | 
			
		||||
            QuoteUpdatedActivity::class,
 | 
			
		||||
 | 
			
		||||
@ -302,8 +302,14 @@ class BaseRepository
 | 
			
		||||
        /* Perform model specific tasks */
 | 
			
		||||
        if ($model instanceof Invoice) {
 | 
			
		||||
 | 
			
		||||
nlog("in base");
 | 
			
		||||
nlog($state['finished_amount']);
 | 
			
		||||
nlog($state['starting_amount']);
 | 
			
		||||
nlog($model->status_id);
 | 
			
		||||
 | 
			
		||||
            if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
 | 
			
		||||
 | 
			
		||||
                $model->service()->updateStatus()->save();
 | 
			
		||||
                $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']), "Update adjustment for invoice {$model->number}");
 | 
			
		||||
                $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,8 @@ return [
 | 
			
		||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
			
		||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
			
		||||
    'app_domain' => env('APP_DOMAIN', ''),
 | 
			
		||||
    'app_version' => '5.1.54',
 | 
			
		||||
    'app_tag' => '5.1.54-release',
 | 
			
		||||
    'app_version' => '5.1.55',
 | 
			
		||||
    'app_tag' => '5.1.55-release',
 | 
			
		||||
    'minimum_client_version' => '5.0.16',
 | 
			
		||||
    'terms_version' => '1.0.1',
 | 
			
		||||
    'api_secret' => env('API_SECRET', false),
 | 
			
		||||
 | 
			
		||||
@ -4204,6 +4204,22 @@ $LANG = array(
 | 
			
		||||
     'promo_code' => 'Promo code',
 | 
			
		||||
     'recurring_invoice_issued_to' => 'Recurring invoice issued to',
 | 
			
		||||
     'subscription' => 'Subscription',
 | 
			
		||||
     'new_subscription' => 'New Subscription',
 | 
			
		||||
     'deleted_subscription' => 'Successfully deleted subscription',
 | 
			
		||||
     'removed_subscription' => 'Successfully removed subscription',
 | 
			
		||||
     'restored_subscription' => 'Successfully restored subscription',
 | 
			
		||||
     'search_subscription' => 'Search 1 Subscription',
 | 
			
		||||
     'search_subscriptions' => 'Search :count Subscriptions',
 | 
			
		||||
     'subdomain_is_not_available' => 'Subdomain is not available',
 | 
			
		||||
     'connect_gmail' => 'Connect Gmail',
 | 
			
		||||
     'disconnect_gmail' => 'Disconnect Gmail',
 | 
			
		||||
     'connected_gmail' => 'Successfully connected Gmail',
 | 
			
		||||
     'disconnected_gmail' => 'Successfully disconnected Gmail',
 | 
			
		||||
     'update_fail_help' => 'Changes to the codebase may be blocking the update, you can run this command to discard the changes:',
 | 
			
		||||
     'client_id_number' => 'Client ID Number',
 | 
			
		||||
     'count_minutes' => ':count Minutes',
 | 
			
		||||
     'password_timeout' => 'Password Timeout',
 | 
			
		||||
     'shared_invoice_credit_counter' => 'Shared Invoice/Credit Counter',
 | 
			
		||||
 | 
			
		||||
    'activity_80' => ':user created subscription :subscription',
 | 
			
		||||
    'activity_81' => ':user updated subscription :subscription',
 | 
			
		||||
@ -4212,6 +4228,13 @@ $LANG = array(
 | 
			
		||||
    'activity_84' => ':user restored subscription :subscription',
 | 
			
		||||
    'amount_greater_than_balance_v5' => 'The amount is greater than the invoice balance. You cannot overpay an invoice.',
 | 
			
		||||
    'click_to_continue' => 'Click to continue',
 | 
			
		||||
 | 
			
		||||
    'notification_invoice_created_subject' => 'Invoice :invoice was created to :client',
 | 
			
		||||
    'notification_invoice_created_subject' => 'Invoice :invoice was created for :client',
 | 
			
		||||
    'notification_quote_created_subject' => 'Quote :invoice was created to :client',
 | 
			
		||||
    'notification_quote_created_subject' => 'Quote :invoice was created for :client',
 | 
			
		||||
    'notification_credit_created_subject' => 'Credit :invoice was created to :client',
 | 
			
		||||
    'notification_credit_created_subject' => 'Credit :invoice was created for :client',
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
return $LANG;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user