mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 21:47:32 -05:00 
			
		
		
		
	Merge pull request #8989 from turbo124/v5-develop
Translation for line item
This commit is contained in:
		
						commit
						1a8643807a
					
				@ -61,7 +61,7 @@ class MobileLocalization extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function laravelResources()
 | 
					    private function laravelResources()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $resources = $this->getResources();
 | 
					        $resources =(array)$this->getResources();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(is_iterable($resources)){
 | 
					        if(is_iterable($resources)){
 | 
				
			||||||
            foreach ($resources as $key => $val) {
 | 
					            foreach ($resources as $key => $val) {
 | 
				
			||||||
 | 
				
			|||||||
@ -628,11 +628,11 @@ class BaseExport
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if(in_array($column, ['client.user_id', 'user_id'])) {
 | 
					        if(in_array($column, ['client.user_id', 'user_id'])) {
 | 
				
			||||||
            return $entity->client->user->present()->name();
 | 
					            return $entity->client->user ? $entity->client->user->present()->name() : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
 | 
					        if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
 | 
				
			||||||
            return $entity->client->assigned_user->present()->name();
 | 
					            return $entity->client->assigned_user ? $entity->client->assigned_user->present()->name() : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(in_array($column, ['client.country_id', 'country_id'])) {
 | 
					        if(in_array($column, ['client.country_id', 'country_id'])) {
 | 
				
			||||||
@ -760,7 +760,7 @@ class BaseExport
 | 
				
			|||||||
                return $transformed_payment[$column];
 | 
					                return $transformed_payment[$column];
 | 
				
			||||||
            } elseif (array_key_exists(str_replace("payment.", "", $column), $transformed_payment)) {
 | 
					            } elseif (array_key_exists(str_replace("payment.", "", $column), $transformed_payment)) {
 | 
				
			||||||
                return $transformed_payment[$column];
 | 
					                return $transformed_payment[$column];
 | 
				
			||||||
            }
 | 
					            } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // nlog("export: Could not resolve payment key: {$column}");
 | 
					            // nlog("export: Could not resolve payment key: {$column}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -177,6 +177,14 @@ class CreditExport extends BaseExport
 | 
				
			|||||||
            $entity['credit.status'] = $credit->stringStatus($credit->status_id);
 | 
					            $entity['credit.status'] = $credit->stringStatus($credit->status_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('credit.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
 | 
					        if (in_array('credit.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['credit.user_id'] = $credit->user ? $credit->user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -151,7 +151,15 @@ class InvoiceExport extends BaseExport
 | 
				
			|||||||
            $entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
 | 
					            $entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        if (in_array('invoice.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -227,6 +227,13 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
            $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
 | 
					            $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        if (in_array('invoice.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -167,6 +167,14 @@ class PaymentExport extends BaseExport
 | 
				
			|||||||
            $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
 | 
					            $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('payment.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('payment.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['payment.user_id'] = $payment->user ? $payment->user->present()->name() : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
 | 
					        // $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
 | 
				
			|||||||
@ -149,6 +149,15 @@ class QuoteExport extends BaseExport
 | 
				
			|||||||
            $entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
 | 
					            $entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        if (in_array('quote.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -198,6 +198,16 @@ class QuoteItemExport extends BaseExport
 | 
				
			|||||||
        if (in_array('status_id', $this->input['report_keys'])) {
 | 
					        if (in_array('status_id', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['status'] = $quote->stringStatus($quote->status_id);
 | 
					            $entity['status'] = $quote->stringStatus($quote->status_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					        if (in_array('quote.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -157,6 +157,15 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
            $entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
 | 
					            $entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('recurring_invoice.assigned_user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['recurring_invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('recurring_invoice.user_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['recurring_invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/ClientDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/ClientDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ClientDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/CreditDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/CreditDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreditDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								app/Export/Decorators/Decorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/Export/Decorators/Decorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Task;
 | 
				
			||||||
 | 
					use App\Models\Quote;
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Credit;
 | 
				
			||||||
 | 
					use App\Models\Vendor;
 | 
				
			||||||
 | 
					use App\Models\Expense;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\Payment;
 | 
				
			||||||
 | 
					use App\Models\Product;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Decorator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __invoke(mixed $entity, string $key)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return match($entity){
 | 
				
			||||||
 | 
					            ($entity instanceof Client) => $value = (new ClientDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Payment) => $value = (new PaymentDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Invoice) => $value = (new InvoiceDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof RecurringInvoice) => $value = (new RecurringInvoiceDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Credit) => $value = (new CreditDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Quote) => $value = (new QuoteDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Task) => $value = (new TaskDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Expense) => $value = (new ExpenseDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Project) => $value = (new ProjectDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Product) => $value = (new ProductDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof Vendor) => $value = (new VendorDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            ($entity instanceof PurchaseOrder) => $value = (new PurchaseOrderDecorator($entity, $key))->transform(),
 | 
				
			||||||
 | 
					            default => $value = '',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								app/Export/Decorators/DecoratorInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Export/Decorators/DecoratorInterface.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface DecoratorInterface {
 | 
				
			||||||
 | 
					    public function transform(): string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/ExpenseDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/ExpenseDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExpenseDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/InvoiceDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/InvoiceDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InvoiceDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/PaymentDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/PaymentDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PaymentDecorator implements DecoratorInterface{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/ProductDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/ProductDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProductDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/ProjectDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/ProjectDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProjectDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/PurchaseOrderDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/PurchaseOrderDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PurchaseOrderDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/QuoteDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/QuoteDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QuoteDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/RecurringInvoiceDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/RecurringInvoiceDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RecurringInvoiceDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/TaskDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/TaskDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TaskDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Export/Decorators/VendorDecorator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Export/Decorators/VendorDecorator.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\Decorators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VendorDecorator implements DecoratorInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function transform(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 'Payment Decorator';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -11,13 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Factory;
 | 
					namespace App\Factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\DataMapper\ClientRegistrationFields;
 | 
					 | 
				
			||||||
use App\DataMapper\CompanySettings;
 | 
					 | 
				
			||||||
use App\DataMapper\Tax\TaxModel;
 | 
					 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\DataMapper\Tax\TaxModel;
 | 
				
			||||||
 | 
					use App\DataMapper\CompanySettings;
 | 
				
			||||||
 | 
					use App\DataMapper\ClientRegistrationFields;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CompanyFactory
 | 
					class CompanyFactory
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -48,7 +48,7 @@ class CompanyFactory
 | 
				
			|||||||
        $company->markdown_email_enabled = true;
 | 
					        $company->markdown_email_enabled = true;
 | 
				
			||||||
        $company->markdown_enabled = false;
 | 
					        $company->markdown_enabled = false;
 | 
				
			||||||
        $company->tax_data = new TaxModel();
 | 
					        $company->tax_data = new TaxModel();
 | 
				
			||||||
        
 | 
					        $company->first_month_of_year = 1;
 | 
				
			||||||
        return $company;
 | 
					        return $company;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,7 @@ class DesignFilters extends QueryFilters
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $this->builder->where('is_template', $bool_val);
 | 
					        return $this->builder->where('is_template', $bool_val);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Filter the designs by `is_custom` column.
 | 
					     * Filter the designs by `is_custom` column.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -527,7 +527,10 @@ class LoginController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (request()->has('id_token')) {
 | 
					        if (request()->has('id_token')) {
 | 
				
			||||||
            $user = $google->getTokenResponse(request()->input('id_token'));
 | 
					            $user = $google->getTokenResponse(request()->input('id_token'));
 | 
				
			||||||
        } else {
 | 
					        }elseif(request()->has('access_token')){
 | 
				
			||||||
 | 
					            $user = $google->harvestUser(request()->input('access_token'));
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
            return response()->json(['message' => 'Illegal request'], 403);
 | 
					            return response()->json(['message' => 'Illegal request'], 403);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,36 +11,37 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Client\ClientWasCreated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Events\Client\ClientWasUpdated;
 | 
					 | 
				
			||||||
use App\Factory\ClientFactory;
 | 
					 | 
				
			||||||
use App\Filters\ClientFilters;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\BulkClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\CreateClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\DestroyClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\EditClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\PurgeClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\ReactivateClientEmailRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\ShowClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\StoreClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\UpdateClientRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Client\UploadClientRequest;
 | 
					 | 
				
			||||||
use App\Jobs\Client\UpdateTaxData;
 | 
					 | 
				
			||||||
use App\Jobs\PostMark\ProcessPostmarkWebhook;
 | 
					 | 
				
			||||||
use App\Models\Account;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\SystemLog;
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
use App\Repositories\ClientRepository;
 | 
					 | 
				
			||||||
use App\Transformers\ClientTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\BulkOptions;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use App\Utils\Traits\Uploadable;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
use Postmark\PostmarkClient;
 | 
					use Postmark\PostmarkClient;
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					use App\Factory\ClientFactory;
 | 
				
			||||||
 | 
					use App\Filters\ClientFilters;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Utils\Traits\Uploadable;
 | 
				
			||||||
 | 
					use App\Utils\Traits\BulkOptions;
 | 
				
			||||||
 | 
					use App\Jobs\Client\UpdateTaxData;
 | 
				
			||||||
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
 | 
					use App\Repositories\ClientRepository;
 | 
				
			||||||
 | 
					use App\Events\Client\ClientWasCreated;
 | 
				
			||||||
 | 
					use App\Events\Client\ClientWasUpdated;
 | 
				
			||||||
 | 
					use App\Transformers\ClientTransformer;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
 | 
					use App\Jobs\PostMark\ProcessPostmarkWebhook;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\BulkClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\EditClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\ShowClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\PurgeClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\StoreClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\CreateClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\UpdateClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\UploadClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\DestroyClientRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Client\ReactivateClientEmailRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ClientController.
 | 
					 * Class ClientController.
 | 
				
			||||||
@ -217,12 +218,31 @@ class ClientController extends BaseController
 | 
				
			|||||||
        $clients = Client::withTrashed()
 | 
					        $clients = Client::withTrashed()
 | 
				
			||||||
                         ->company()
 | 
					                         ->company()
 | 
				
			||||||
                         ->whereIn('id', $request->ids)
 | 
					                         ->whereIn('id', $request->ids)
 | 
				
			||||||
                         ->cursor()
 | 
					                         ->get();                         
 | 
				
			||||||
                         ->each(function ($client) use ($action, $user) {
 | 
					
 | 
				
			||||||
                             if ($user->can('edit', $client)) {
 | 
					        if($action == 'template' && $user->can('view', $clients->first())) {
 | 
				
			||||||
                                 $this->client_repo->{$action}($client);
 | 
					
 | 
				
			||||||
                             }
 | 
					            $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
                         });
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $clients->pluck('id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Client::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					                         
 | 
				
			||||||
 | 
					        $clients->each(function ($client) use ($action, $user) {
 | 
				
			||||||
 | 
					            if ($user->can('edit', $client)) {
 | 
				
			||||||
 | 
					                $this->client_repo->{$action}($client);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
 | 
					        return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -364,8 +384,15 @@ class ClientController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            /** @var \Postmark\Models\DynamicResponseModel $response */
 | 
				
			||||||
            $response = $postmark->activateBounce((int)$bounce_id);
 | 
					            $response = $postmark->activateBounce((int)$bounce_id);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					            if($response && $response?->Message == 'OK' && !$response->Bounce->Inactive && $response->Bounce->Email){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $email =  $response->Bounce->Email;
 | 
				
			||||||
 | 
					                //remove email from quarantine. //@TODO
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'Success'], 200);
 | 
					            return response()->json(['message' => 'Success'], 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,35 +11,36 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Credit\CreditWasCreated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Events\Credit\CreditWasUpdated;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Factory\CloneCreditFactory;
 | 
					use App\Models\Credit;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Factory\CreditFactory;
 | 
					use App\Factory\CreditFactory;
 | 
				
			||||||
use App\Filters\CreditFilters;
 | 
					use App\Filters\CreditFilters;
 | 
				
			||||||
use App\Http\Requests\Credit\ActionCreditRequest;
 | 
					use App\Jobs\Credit\ZipCredits;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Entity\EmailEntity;
 | 
				
			||||||
 | 
					use App\Factory\CloneCreditFactory;
 | 
				
			||||||
 | 
					use App\Services\PdfMaker\PdfMerge;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
 | 
					use App\Repositories\CreditRepository;
 | 
				
			||||||
 | 
					use App\Events\Credit\CreditWasCreated;
 | 
				
			||||||
 | 
					use App\Events\Credit\CreditWasUpdated;
 | 
				
			||||||
 | 
					use App\Transformers\CreditTransformer;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
use App\Http\Requests\Credit\BulkCreditRequest;
 | 
					use App\Http\Requests\Credit\BulkCreditRequest;
 | 
				
			||||||
use App\Http\Requests\Credit\CreateCreditRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Credit\DestroyCreditRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Credit\EditCreditRequest;
 | 
					use App\Http\Requests\Credit\EditCreditRequest;
 | 
				
			||||||
use App\Http\Requests\Credit\ShowCreditRequest;
 | 
					use App\Http\Requests\Credit\ShowCreditRequest;
 | 
				
			||||||
use App\Http\Requests\Credit\StoreCreditRequest;
 | 
					use App\Http\Requests\Credit\StoreCreditRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Credit\ActionCreditRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Credit\CreateCreditRequest;
 | 
				
			||||||
use App\Http\Requests\Credit\UpdateCreditRequest;
 | 
					use App\Http\Requests\Credit\UpdateCreditRequest;
 | 
				
			||||||
use App\Http\Requests\Credit\UploadCreditRequest;
 | 
					use App\Http\Requests\Credit\UploadCreditRequest;
 | 
				
			||||||
use App\Jobs\Credit\ZipCredits;
 | 
					use App\Http\Requests\Credit\DestroyCreditRequest;
 | 
				
			||||||
use App\Jobs\Entity\EmailEntity;
 | 
					 | 
				
			||||||
use App\Models\Account;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\Credit;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
use App\Repositories\CreditRepository;
 | 
					 | 
				
			||||||
use App\Services\PdfMaker\PdfMerge;
 | 
					 | 
				
			||||||
use App\Transformers\CreditTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class CreditController.
 | 
					 * Class CreditController.
 | 
				
			||||||
@ -550,6 +551,25 @@ class CreditController extends BaseController
 | 
				
			|||||||
            }, 'print.pdf', ['Content-Type' => 'application/pdf']);
 | 
					            }, 'print.pdf', ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($action == 'template' && $user->can('view', $credits->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $credits->pluck('hashed_id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Credit::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $credits->each(function ($credit, $key) use ($action, $user) {
 | 
					        $credits->each(function ($credit, $key) use ($action, $user) {
 | 
				
			||||||
            if ($user->can('edit', $credit)) {
 | 
					            if ($user->can('edit', $credit)) {
 | 
				
			||||||
                $this->performAction($credit, $action, true);
 | 
					                $this->performAction($credit, $action, true);
 | 
				
			||||||
 | 
				
			|||||||
@ -69,8 +69,11 @@ class EmailController extends BaseController
 | 
				
			|||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('cc_email') && $request->cc_email && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
 | 
					        if ($request->has('cc_email') && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
 | 
				
			||||||
            $mo->cc[] = new Address($request->cc_email);
 | 
					 
 | 
				
			||||||
 | 
					            foreach($request->cc_email as $email)
 | 
				
			||||||
 | 
					                $mo->cc[] = new Address($email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
 | 
					        $entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
 | 
				
			||||||
 | 
				
			|||||||
@ -56,11 +56,14 @@ class ExportController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index(StoreExportRequest $request)
 | 
					    public function index(StoreExportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $hash = Str::uuid();
 | 
					        $hash = Str::uuid();
 | 
				
			||||||
        $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
 | 
					        $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
 | 
				
			||||||
        Cache::put($hash, $url, now()->addHour());
 | 
					        Cache::put($hash, $url, now()->addHour());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user(), $hash);
 | 
					        CompanyExport::dispatch($user->getCompany(), $user, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['message' => 'Processing', 'url' => $url], 200);
 | 
					        return response()->json(['message' => 'Processing', 'url' => $url], 200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -416,7 +416,6 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $invoice->service()
 | 
					        $invoice->service()
 | 
				
			||||||
                ->triggeredActions($request)
 | 
					                ->triggeredActions($request)
 | 
				
			||||||
                // ->deletePdf()
 | 
					 | 
				
			||||||
                ->adjustInventory($old_invoice);
 | 
					                ->adjustInventory($old_invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
 | 
				
			|||||||
@ -11,25 +11,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Payment\PaymentWasUpdated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Factory\PaymentFactory;
 | 
					 | 
				
			||||||
use App\Filters\PaymentFilters;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\CreatePaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\DestroyPaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\EditPaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\RefundPaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\ShowPaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\StorePaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\UpdatePaymentRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\Payment\UploadPaymentRequest;
 | 
					 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Models\Account;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Repositories\PaymentRepository;
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Transformers\PaymentTransformer;
 | 
					use App\Factory\PaymentFactory;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Filters\PaymentFilters;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					use App\Repositories\PaymentRepository;
 | 
				
			||||||
 | 
					use App\Transformers\PaymentTransformer;
 | 
				
			||||||
 | 
					use App\Events\Payment\PaymentWasUpdated;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\EditPaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\ShowPaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\StorePaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\CreatePaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\RefundPaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\UpdatePaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\UploadPaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\DestroyPaymentRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Payment\BulkActionPaymentRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class PaymentController.
 | 
					 * Class PaymentController.
 | 
				
			||||||
@ -499,16 +501,39 @@ class PaymentController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function bulk()
 | 
					    public function bulk(BulkActionPaymentRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $action = request()->input('action');
 | 
					        $action = $request->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ids = request()->input('ids');
 | 
					        $ids = $request->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $payments = Payment::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$payments) {
 | 
				
			||||||
 | 
					            return response()->json(['message' => ctrans('texts.record_not_found')]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($action == 'template' && $user->can('view', $payments->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = request()->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					nlog($payments->pluck('hashed_id')->toArray());
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $payments->pluck('hashed_id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Payment::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payments = Payment::withTrashed()->find($this->transformKeys($ids));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payments->each(function ($payment, $key) use ($action, $user) {
 | 
					        $payments->each(function ($payment, $key) use ($action, $user) {
 | 
				
			||||||
            if ($user->can('edit', $payment)) {
 | 
					            if ($user->can('edit', $payment)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -137,9 +137,9 @@ class PreviewController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function show()
 | 
					    public function show()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // if(request()->has('template')) {
 | 
					        if(request()->has('template')) {
 | 
				
			||||||
            return $this->template();
 | 
					            return $this->template();
 | 
				
			||||||
        // }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (request()->has('entity') &&
 | 
					        if (request()->has('entity') &&
 | 
				
			||||||
            request()->has('entity_id') &&
 | 
					            request()->has('entity_id') &&
 | 
				
			||||||
 | 
				
			|||||||
@ -11,23 +11,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Factory\ProjectFactory;
 | 
					use App\Factory\ProjectFactory;
 | 
				
			||||||
use App\Filters\ProjectFilters;
 | 
					use App\Filters\ProjectFilters;
 | 
				
			||||||
use App\Http\Requests\Project\CreateProjectRequest;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Http\Requests\Project\DestroyProjectRequest;
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
 | 
					use App\Repositories\ProjectRepository;
 | 
				
			||||||
 | 
					use App\Transformers\ProjectTransformer;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
use App\Http\Requests\Project\EditProjectRequest;
 | 
					use App\Http\Requests\Project\EditProjectRequest;
 | 
				
			||||||
use App\Http\Requests\Project\ShowProjectRequest;
 | 
					use App\Http\Requests\Project\ShowProjectRequest;
 | 
				
			||||||
use App\Http\Requests\Project\StoreProjectRequest;
 | 
					use App\Http\Requests\Project\StoreProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\CreateProjectRequest;
 | 
				
			||||||
use App\Http\Requests\Project\UpdateProjectRequest;
 | 
					use App\Http\Requests\Project\UpdateProjectRequest;
 | 
				
			||||||
use App\Http\Requests\Project\UploadProjectRequest;
 | 
					use App\Http\Requests\Project\UploadProjectRequest;
 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Http\Requests\Project\DestroyProjectRequest;
 | 
				
			||||||
use App\Models\Project;
 | 
					use App\Http\Requests\Project\BulkProjectRequest;
 | 
				
			||||||
use App\Repositories\ProjectRepository;
 | 
					 | 
				
			||||||
use App\Transformers\ProjectTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ProjectController.
 | 
					 * Class ProjectController.
 | 
				
			||||||
@ -490,18 +492,36 @@ class ProjectController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function bulk()
 | 
					    public function bulk(BulkProjectRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $action = request()->input('action');
 | 
					        $action = $request->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ids = request()->input('ids');
 | 
					        $ids = $request->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $projects = Project::withTrashed()->find($this->transformKeys($ids));
 | 
					        $projects = Project::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $projects->each(function ($project, $key) use ($action, $user) {
 | 
					        if($action == 'template' && $user->can('view', $projects->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $projects->pluck('hashed_id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Project::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $projects->each(function ($project) use ($action, $user) {
 | 
				
			||||||
            if ($user->can('edit', $project)) {
 | 
					            if ($user->can('edit', $project)) {
 | 
				
			||||||
                $this->project_repo->{$action}($project);
 | 
					                $this->project_repo->{$action}($project);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -19,10 +19,10 @@ use Illuminate\Support\Facades\Storage;
 | 
				
			|||||||
class ProtectedDownloadController extends BaseController
 | 
					class ProtectedDownloadController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function index(Request $request)
 | 
					    public function index(Request $request, string $hash)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var string $hashed_path */
 | 
					        /** @var string $hashed_path */
 | 
				
			||||||
        $hashed_path = Cache::pull($request->hash);
 | 
					        $hashed_path = Cache::pull($hash);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (!$hashed_path) {
 | 
					        if (!$hashed_path) {
 | 
				
			||||||
            throw new SystemError('File no longer available', 404);
 | 
					            throw new SystemError('File no longer available', 404);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,33 +11,34 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Entity\CreateRawPdf;
 | 
				
			||||||
 | 
					use App\Services\PdfMaker\PdfMerge;
 | 
				
			||||||
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
use App\Factory\PurchaseOrderFactory;
 | 
					use App\Factory\PurchaseOrderFactory;
 | 
				
			||||||
use App\Filters\PurchaseOrderFilters;
 | 
					use App\Filters\PurchaseOrderFilters;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\ActionPurchaseOrderRequest;
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
 | 
					use App\Jobs\PurchaseOrder\ZipPurchaseOrders;
 | 
				
			||||||
 | 
					use App\Repositories\PurchaseOrderRepository;
 | 
				
			||||||
 | 
					use App\Jobs\PurchaseOrder\PurchaseOrderEmail;
 | 
				
			||||||
 | 
					use App\Transformers\PurchaseOrderTransformer;
 | 
				
			||||||
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
 | 
				
			||||||
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\BulkPurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\BulkPurchaseOrderRequest;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\CreatePurchaseOrderRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\DestroyPurchaseOrderRequest;
 | 
					 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\EditPurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\EditPurchaseOrderRequest;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\ShowPurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\ShowPurchaseOrderRequest;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\StorePurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\StorePurchaseOrderRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\PurchaseOrder\ActionPurchaseOrderRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\PurchaseOrder\CreatePurchaseOrderRequest;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\UpdatePurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\UpdatePurchaseOrderRequest;
 | 
				
			||||||
use App\Http\Requests\PurchaseOrder\UploadPurchaseOrderRequest;
 | 
					use App\Http\Requests\PurchaseOrder\UploadPurchaseOrderRequest;
 | 
				
			||||||
use App\Jobs\Entity\CreateRawPdf;
 | 
					use App\Http\Requests\PurchaseOrder\DestroyPurchaseOrderRequest;
 | 
				
			||||||
use App\Jobs\PurchaseOrder\PurchaseOrderEmail;
 | 
					 | 
				
			||||||
use App\Jobs\PurchaseOrder\ZipPurchaseOrders;
 | 
					 | 
				
			||||||
use App\Models\Account;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					 | 
				
			||||||
use App\Repositories\PurchaseOrderRepository;
 | 
					 | 
				
			||||||
use App\Services\PdfMaker\PdfMerge;
 | 
					 | 
				
			||||||
use App\Transformers\PurchaseOrderTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderController extends BaseController
 | 
					class PurchaseOrderController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -524,6 +525,24 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
            }, 'print.pdf', ['Content-Type' => 'application/pdf']);
 | 
					            }, 'print.pdf', ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($action == 'template' && $user->can('view', $purchase_orders->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $purchase_orders->pluck('hashed_id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                PurchaseOrder::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Send the other actions to the switch
 | 
					         * Send the other actions to the switch
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
 | 
				
			|||||||
@ -11,40 +11,41 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Quote\QuoteWasCreated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Events\Quote\QuoteWasUpdated;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Factory\CloneQuoteFactory;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Factory\CloneQuoteToInvoiceFactory;
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use App\Factory\QuoteFactory;
 | 
					use App\Factory\QuoteFactory;
 | 
				
			||||||
use App\Filters\QuoteFilters;
 | 
					use App\Filters\QuoteFilters;
 | 
				
			||||||
use App\Http\Requests\Quote\ActionQuoteRequest;
 | 
					use App\Jobs\Quote\ZipQuotes;
 | 
				
			||||||
use App\Http\Requests\Quote\BulkActionQuoteRequest;
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Http\Requests\Quote\CreateQuoteRequest;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Http\Requests\Quote\DestroyQuoteRequest;
 | 
					use App\Factory\CloneQuoteFactory;
 | 
				
			||||||
 | 
					use App\Services\PdfMaker\PdfMerge;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
 | 
					use App\Events\Quote\QuoteWasCreated;
 | 
				
			||||||
 | 
					use App\Events\Quote\QuoteWasUpdated;
 | 
				
			||||||
 | 
					use App\Repositories\QuoteRepository;
 | 
				
			||||||
 | 
					use App\Transformers\QuoteTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Transformers\InvoiceTransformer;
 | 
				
			||||||
 | 
					use App\Transformers\ProjectTransformer;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
 | 
					use App\Factory\CloneQuoteToInvoiceFactory;
 | 
				
			||||||
use App\Http\Requests\Quote\EditQuoteRequest;
 | 
					use App\Http\Requests\Quote\EditQuoteRequest;
 | 
				
			||||||
use App\Http\Requests\Quote\ShowQuoteRequest;
 | 
					use App\Http\Requests\Quote\ShowQuoteRequest;
 | 
				
			||||||
use App\Http\Requests\Quote\StoreQuoteRequest;
 | 
					use App\Http\Requests\Quote\StoreQuoteRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Quote\ActionQuoteRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Quote\CreateQuoteRequest;
 | 
				
			||||||
use App\Http\Requests\Quote\UpdateQuoteRequest;
 | 
					use App\Http\Requests\Quote\UpdateQuoteRequest;
 | 
				
			||||||
use App\Http\Requests\Quote\UploadQuoteRequest;
 | 
					use App\Http\Requests\Quote\UploadQuoteRequest;
 | 
				
			||||||
use App\Jobs\Quote\ZipQuotes;
 | 
					use App\Http\Requests\Quote\DestroyQuoteRequest;
 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Http\Requests\Quote\BulkActionQuoteRequest;
 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
use App\Models\Project;
 | 
					 | 
				
			||||||
use App\Models\Quote;
 | 
					 | 
				
			||||||
use App\Repositories\QuoteRepository;
 | 
					 | 
				
			||||||
use App\Services\PdfMaker\PdfMerge;
 | 
					 | 
				
			||||||
use App\Transformers\InvoiceTransformer;
 | 
					 | 
				
			||||||
use App\Transformers\ProjectTransformer;
 | 
					 | 
				
			||||||
use App\Transformers\QuoteTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class QuoteController.
 | 
					 * Class QuoteController.
 | 
				
			||||||
@ -517,9 +518,9 @@ class QuoteController extends BaseController
 | 
				
			|||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $action = request()->input('action');
 | 
					        $action = $request->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ids = request()->input('ids');
 | 
					        $ids = $request->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->account->account_sms_verified) {
 | 
					        if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->account->account_sms_verified) {
 | 
				
			||||||
            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
					            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
				
			||||||
@ -584,6 +585,28 @@ class QuoteController extends BaseController
 | 
				
			|||||||
            return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
					            return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($action == 'template' && $user->can('view', $quotes->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $ids,
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Quote::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Send the other actions to the switch
 | 
					         * Send the other actions to the switch
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
 | 
				
			|||||||
@ -11,29 +11,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Task\TaskWasCreated;
 | 
					use App\Models\Task;
 | 
				
			||||||
use App\Events\Task\TaskWasUpdated;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\TaskStatus;
 | 
				
			||||||
use App\Factory\TaskFactory;
 | 
					use App\Factory\TaskFactory;
 | 
				
			||||||
use App\Filters\TaskFilters;
 | 
					use App\Filters\TaskFilters;
 | 
				
			||||||
use App\Http\Requests\Task\CreateTaskRequest;
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Http\Requests\Task\DestroyTaskRequest;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Utils\Traits\Uploadable;
 | 
				
			||||||
 | 
					use App\Utils\Traits\BulkOptions;
 | 
				
			||||||
 | 
					use App\Events\Task\TaskWasCreated;
 | 
				
			||||||
 | 
					use App\Events\Task\TaskWasUpdated;
 | 
				
			||||||
 | 
					use App\Repositories\TaskRepository;
 | 
				
			||||||
 | 
					use App\Utils\Traits\SavesDocuments;
 | 
				
			||||||
 | 
					use App\Transformers\TaskTransformer;
 | 
				
			||||||
 | 
					use App\Services\Template\TemplateAction;
 | 
				
			||||||
 | 
					use App\Http\Requests\Task\BulkTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\EditTaskRequest;
 | 
					use App\Http\Requests\Task\EditTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\ShowTaskRequest;
 | 
					use App\Http\Requests\Task\ShowTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\SortTaskRequest;
 | 
					use App\Http\Requests\Task\SortTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\StoreTaskRequest;
 | 
					use App\Http\Requests\Task\StoreTaskRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Task\CreateTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\UpdateTaskRequest;
 | 
					use App\Http\Requests\Task\UpdateTaskRequest;
 | 
				
			||||||
use App\Http\Requests\Task\UploadTaskRequest;
 | 
					use App\Http\Requests\Task\UploadTaskRequest;
 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Http\Requests\Task\DestroyTaskRequest;
 | 
				
			||||||
use App\Models\Task;
 | 
					 | 
				
			||||||
use App\Models\TaskStatus;
 | 
					 | 
				
			||||||
use App\Repositories\TaskRepository;
 | 
					 | 
				
			||||||
use App\Transformers\TaskTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\BulkOptions;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use App\Utils\Traits\SavesDocuments;
 | 
					 | 
				
			||||||
use App\Utils\Traits\Uploadable;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class TaskController.
 | 
					 * Class TaskController.
 | 
				
			||||||
@ -497,16 +499,36 @@ class TaskController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function bulk()
 | 
					    public function bulk(BulkTaskRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $action = request()->input('action');
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ids = request()->input('ids');
 | 
					        $action = $request->input('action');
 | 
				
			||||||
        $tasks = Task::withTrashed()->find($this->transformKeys($ids));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $tasks->each(function ($task, $key) use ($action) {
 | 
					        $ids = $request->input('ids');
 | 
				
			||||||
            /** @var \App\Models\User $user */
 | 
					        
 | 
				
			||||||
            $user = auth()->user();
 | 
					        $tasks = Task::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($action == 'template' && $user->can('view', $tasks->first())) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash_or_response = request()->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TemplateAction::dispatch(
 | 
				
			||||||
 | 
					                $tasks->pluck('hashed_id')->toArray(),
 | 
				
			||||||
 | 
					                $request->template_id,
 | 
				
			||||||
 | 
					                Task::class,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $user->company(),
 | 
				
			||||||
 | 
					                $user->company()->db,
 | 
				
			||||||
 | 
					                $hash_or_response,
 | 
				
			||||||
 | 
					                $request->boolean('send_email')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash_or_response], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $tasks->each(function ($task) use ($action, $user) {
 | 
				
			||||||
            if ($user->can('edit', $task)) {
 | 
					            if ($user->can('edit', $task)) {
 | 
				
			||||||
                $this->task_repo->{$action}($task);
 | 
					                $this->task_repo->{$action}($task);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Locale
 | 
					class Locale
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    private array $locales = [
 | 
				
			||||||
 | 
					                        'en',
 | 
				
			||||||
 | 
					                        'it',
 | 
				
			||||||
 | 
					                        'de',
 | 
				
			||||||
 | 
					                        'fr',
 | 
				
			||||||
 | 
					                        'pt_BR',
 | 
				
			||||||
 | 
					                        'nl',
 | 
				
			||||||
 | 
					                        'es',
 | 
				
			||||||
 | 
					                        'nb_NO',
 | 
				
			||||||
 | 
					                        'da',
 | 
				
			||||||
 | 
					                        'ja',
 | 
				
			||||||
 | 
					                        'sv',
 | 
				
			||||||
 | 
					                        'es_ES',
 | 
				
			||||||
 | 
					                        'fr_CA',
 | 
				
			||||||
 | 
					                        'lt',
 | 
				
			||||||
 | 
					                        'pl',
 | 
				
			||||||
 | 
					                        'cs',
 | 
				
			||||||
 | 
					                        'hr',
 | 
				
			||||||
 | 
					                        'sq',
 | 
				
			||||||
 | 
					                        'el',
 | 
				
			||||||
 | 
					                        'en_GB',
 | 
				
			||||||
 | 
					                        'pt_PT',
 | 
				
			||||||
 | 
					                        'sl',
 | 
				
			||||||
 | 
					                        'fi',
 | 
				
			||||||
 | 
					                        'ro',
 | 
				
			||||||
 | 
					                        'tr_TR',
 | 
				
			||||||
 | 
					                        'th',
 | 
				
			||||||
 | 
					                        'mk_MK',
 | 
				
			||||||
 | 
					                        'zh_TW',
 | 
				
			||||||
 | 
					                        'ru_RU',
 | 
				
			||||||
 | 
					                        'ar',
 | 
				
			||||||
 | 
					                        'fa',
 | 
				
			||||||
 | 
					                        'lv_LV',
 | 
				
			||||||
 | 
					                        'sr',
 | 
				
			||||||
 | 
					                        'sk',
 | 
				
			||||||
 | 
					                        'et',
 | 
				
			||||||
 | 
					                        'bg',
 | 
				
			||||||
 | 
					                        'he',
 | 
				
			||||||
 | 
					                        'km_KH',
 | 
				
			||||||
 | 
					                        'hu',
 | 
				
			||||||
 | 
					                        'fr_CH',
 | 
				
			||||||
 | 
					                    ];
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handle an incoming request.
 | 
					     * Handle an incoming request.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -25,10 +67,10 @@ class Locale
 | 
				
			|||||||
     * @return mixed
 | 
					     * @return mixed
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function handle($request, Closure $next)
 | 
					    public function handle($request, Closure $next)
 | 
				
			||||||
    {
 | 
					    { 
 | 
				
			||||||
        /*LOCALE SET */
 | 
					        /*LOCALE SET */
 | 
				
			||||||
        if ($request->has('lang') && is_string($request->input('lang'))) {
 | 
					        if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
 | 
				
			||||||
            $locale = $request->string('lang','en');
 | 
					            $locale = $request->input('lang');
 | 
				
			||||||
            App::setLocale($locale);
 | 
					            App::setLocale($locale);
 | 
				
			||||||
        } elseif (auth()->guard('contact')->user()) {
 | 
					        } elseif (auth()->guard('contact')->user()) {
 | 
				
			||||||
            App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
 | 
					            App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class VendorLocale
 | 
					class VendorLocale
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					        private array $locales = [
 | 
				
			||||||
 | 
					                        'en',
 | 
				
			||||||
 | 
					                        'it',
 | 
				
			||||||
 | 
					                        'de',
 | 
				
			||||||
 | 
					                        'fr',
 | 
				
			||||||
 | 
					                        'pt_BR',
 | 
				
			||||||
 | 
					                        'nl',
 | 
				
			||||||
 | 
					                        'es',
 | 
				
			||||||
 | 
					                        'nb_NO',
 | 
				
			||||||
 | 
					                        'da',
 | 
				
			||||||
 | 
					                        'ja',
 | 
				
			||||||
 | 
					                        'sv',
 | 
				
			||||||
 | 
					                        'es_ES',
 | 
				
			||||||
 | 
					                        'fr_CA',
 | 
				
			||||||
 | 
					                        'lt',
 | 
				
			||||||
 | 
					                        'pl',
 | 
				
			||||||
 | 
					                        'cs',
 | 
				
			||||||
 | 
					                        'hr',
 | 
				
			||||||
 | 
					                        'sq',
 | 
				
			||||||
 | 
					                        'el',
 | 
				
			||||||
 | 
					                        'en_GB',
 | 
				
			||||||
 | 
					                        'pt_PT',
 | 
				
			||||||
 | 
					                        'sl',
 | 
				
			||||||
 | 
					                        'fi',
 | 
				
			||||||
 | 
					                        'ro',
 | 
				
			||||||
 | 
					                        'tr_TR',
 | 
				
			||||||
 | 
					                        'th',
 | 
				
			||||||
 | 
					                        'mk_MK',
 | 
				
			||||||
 | 
					                        'zh_TW',
 | 
				
			||||||
 | 
					                        'ru_RU',
 | 
				
			||||||
 | 
					                        'ar',
 | 
				
			||||||
 | 
					                        'fa',
 | 
				
			||||||
 | 
					                        'lv_LV',
 | 
				
			||||||
 | 
					                        'sr',
 | 
				
			||||||
 | 
					                        'sk',
 | 
				
			||||||
 | 
					                        'et',
 | 
				
			||||||
 | 
					                        'bg',
 | 
				
			||||||
 | 
					                        'he',
 | 
				
			||||||
 | 
					                        'km_KH',
 | 
				
			||||||
 | 
					                        'hu',
 | 
				
			||||||
 | 
					                        'fr_CH',
 | 
				
			||||||
 | 
					                    ];
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handle an incoming request.
 | 
					     * Handle an incoming request.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -32,7 +74,7 @@ class VendorLocale
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*LOCALE SET */
 | 
					        /*LOCALE SET */
 | 
				
			||||||
        if ($request->has('lang') && is_string($request->input('lang'))) {
 | 
					        if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
 | 
				
			||||||
            $locale = $request->input('lang');
 | 
					            $locale = $request->input('lang');
 | 
				
			||||||
            App::setLocale($locale);
 | 
					            App::setLocale($locale);
 | 
				
			||||||
        } elseif (auth()->guard('vendor')->user()) {
 | 
					        } elseif (auth()->guard('vendor')->user()) {
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ class CreateAccountRequest extends Request
 | 
				
			|||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'first_name'        => 'string|max:100',
 | 
					            'first_name'        => 'string|max:100',
 | 
				
			||||||
            'last_name'         =>  'string:max:100',
 | 
					            'last_name'         =>  'string:max:100',
 | 
				
			||||||
            'password'          => 'required|string|min:6|max:1000',
 | 
					            'password'          => 'required|string|min:6|max:100',
 | 
				
			||||||
            'email'             =>  $email_rules,
 | 
					            'email'             =>  $email_rules,
 | 
				
			||||||
            'privacy_policy'    => 'required|boolean',
 | 
					            'privacy_policy'    => 'required|boolean',
 | 
				
			||||||
            'terms_of_service'  => 'required|boolean',
 | 
					            'terms_of_service'  => 'required|boolean',
 | 
				
			||||||
 | 
				
			|||||||
@ -35,9 +35,13 @@ class BulkClientRequest extends Request
 | 
				
			|||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
 | 
					            'action' => 'required|string|in:archive,restore,delete,template',
 | 
				
			||||||
            'ids' => ['required','bail','array',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)],
 | 
					            'ids' => ['required','bail','array',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)],
 | 
				
			||||||
            'action' => 'in:archive,restore,delete'
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					    public function prepareForValidation()
 | 
				
			||||||
 | 
				
			|||||||
@ -35,9 +35,15 @@ class BulkCreditRequest extends FormRequest
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'ids' => ['required','bail','array',Rule::exists('credits', 'id')->where('company_id', auth()->user()->company()->id)],
 | 
					            'ids' => ['required','bail','array',Rule::exists('credits', 'id')->where('company_id', $user->company()->id)],
 | 
				
			||||||
            'action' => 'required|bail|in:archive,restore,delete,email,bulk_download,bulk_print,mark_paid,clone_to_credit,history,mark_sent,download,send_email'
 | 
					            'action' => 'required|bail|in:archive,restore,delete,email,bulk_download,bulk_print,mark_paid,clone_to_credit,history,mark_sent,download,send_email,template',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -43,8 +43,10 @@ class SendEmailRequest extends Request
 | 
				
			|||||||
            'template' => 'bail|required',
 | 
					            'template' => 'bail|required',
 | 
				
			||||||
            'entity' => 'bail|required',
 | 
					            'entity' => 'bail|required',
 | 
				
			||||||
            'entity_id' => 'bail|required',
 | 
					            'entity_id' => 'bail|required',
 | 
				
			||||||
            'cc_email' => 'bail|sometimes|email|nullable',
 | 
					            'cc_email.*' => 'bail|sometimes|email|nullable',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					    public function prepareForValidation()
 | 
				
			||||||
@ -72,6 +74,14 @@ class SendEmailRequest extends Request
 | 
				
			|||||||
            $input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
 | 
					            $input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(isset($input['cc_email'])){
 | 
				
			||||||
 | 
					            $input['cc_email'] = collect(explode(",", $input['cc_email']))->map(function($email){
 | 
				
			||||||
 | 
					                return trim($email);
 | 
				
			||||||
 | 
					            })->filter(function($email){
 | 
				
			||||||
 | 
					                return filter_var($email, FILTER_VALIDATE_EMAIL);
 | 
				
			||||||
 | 
					            })->slice(0,4)->toArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->replace($input);
 | 
					        $this->replace($input);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,10 @@ class ImportRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->isAdmin();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										40
									
								
								app/Http/Requests/Payment/BulkActionPaymentRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/Http/Requests/Payment/BulkActionPaymentRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Payment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BulkActionPaymentRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'action' => 'required|string',
 | 
				
			||||||
 | 
					            'ids' => 'required|array',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										45
									
								
								app/Http/Requests/Project/BulkProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Http/Requests/Project/BulkProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BulkProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the validation rules that apply to the request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'action' => 'required|string',
 | 
				
			||||||
 | 
					            'ids' => 'required|array',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -30,7 +30,10 @@ class BulkPurchaseOrderRequest extends Request
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'ids' => 'required|bail|array|min:1',
 | 
					            'ids' => 'required|bail|array|min:1',
 | 
				
			||||||
            'action' => 'in:archive,restore,delete,email,bulk_download,bulk_print,mark_sent,download,send_email,add_to_inventory,expense,cancel'
 | 
					            'action' => 'in:template,archive,restore,delete,email,bulk_download,bulk_print,mark_sent,download,send_email,add_to_inventory,expense,cancel',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -31,7 +31,11 @@ class BulkActionQuoteRequest extends Request
 | 
				
			|||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules = [
 | 
					        $rules = [
 | 
				
			||||||
            'action' => 'sometimes|in:convert_to_invoice,convert_to_project,email,bulk_download,bulk_print,clone_to_invoice,approve,download,restore,archive,delete,send_email,mark_sent',
 | 
					            'action' => 'sometimes|in:template,convert_to_invoice,convert_to_project,email,bulk_download,bulk_print,clone_to_invoice,approve,download,restore,archive,delete,send_email,mark_sent',
 | 
				
			||||||
 | 
					            'ids' => 'required|array',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array($input['action'], ['convert,convert_to_invoice'])) {
 | 
					        if (in_array($input['action'], ['convert,convert_to_invoice'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -12,12 +12,9 @@
 | 
				
			|||||||
namespace App\Http\Requests\Task;
 | 
					namespace App\Http\Requests\Task;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
use App\Models\Task;
 | 
					 | 
				
			||||||
use App\Utils\Traits\BulkOptions;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BulkTaskRequest extends Request
 | 
					class BulkTaskRequest extends Request
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use BulkOptions;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Determine if the user is authorized to make this request.
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
@ -26,7 +23,7 @@ class BulkTaskRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize()
 | 
					    public function authorize()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->can(auth()->user()->isAdmin(), Task::class);
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -36,13 +33,14 @@ class BulkTaskRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $rules = $this->getGlobalRules();
 | 
					        
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'action' => 'required|string',
 | 
				
			||||||
 | 
					            'ids' => 'required|array',
 | 
				
			||||||
 | 
					            'template' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'template_id' => 'sometimes|string',
 | 
				
			||||||
 | 
					            'send_email' => 'sometimes|bool'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* We don't require IDs on bulk storing. */
 | 
					 | 
				
			||||||
        if ($this->action !== self::$STORE_METHOD) {
 | 
					 | 
				
			||||||
            $rules['ids'] = ['required'];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $rules;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ class TaskMap
 | 
				
			|||||||
            4 => 'client.name',
 | 
					            4 => 'client.name',
 | 
				
			||||||
            5 => 'client.email',
 | 
					            5 => 'client.email',
 | 
				
			||||||
            6 => 'task.description',
 | 
					            6 => 'task.description',
 | 
				
			||||||
            7 => 'task.is_billable',
 | 
					            7 => 'task.billable',
 | 
				
			||||||
            8 => 'task.start_date',
 | 
					            8 => 'task.start_date',
 | 
				
			||||||
            9 => 'task.end_date',
 | 
					            9 => 'task.end_date',
 | 
				
			||||||
            10 => 'task.start_time',
 | 
					            10 => 'task.start_time',
 | 
				
			||||||
 | 
				
			|||||||
@ -162,11 +162,12 @@ class BaseImport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function groupTasks($csvData, $key)
 | 
					    private function groupTasks($csvData, $key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        nlog($csvData[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $key || count(array_column($csvData, $key)) == 0) {
 | 
					        if (! $key || !is_array($csvData) || count($csvData) == 0 || !isset($csvData[0]['task.number']) || empty($csvData[0]['task.number'])) {
 | 
				
			||||||
            return $csvData;
 | 
					            return $csvData;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        // Group by tasks.
 | 
					        // Group by tasks.
 | 
				
			||||||
        $grouped = [];
 | 
					        $grouped = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -495,7 +496,7 @@ class BaseImport
 | 
				
			|||||||
                ];
 | 
					                ];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
nlog($count);
 | 
					        
 | 
				
			||||||
        return $count;
 | 
					        return $count;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,7 @@ class BaseTransformer
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getString($data, $field)
 | 
					    public function getString($data, $field)
 | 
				
			||||||
    {
 | 
					    {   
 | 
				
			||||||
        return isset($data[$field]) && $data[$field] ? trim($data[$field]) : '';
 | 
					        return isset($data[$field]) && $data[$field] ? trim($data[$field]) : '';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -179,6 +179,7 @@ class BaseTransformer
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function getClient($client_name, $client_email)
 | 
					    public function getClient($client_name, $client_email)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! empty($client_name)) {
 | 
					        if (! empty($client_name)) {
 | 
				
			||||||
            $client_id_search = Client::query()->where('company_id', $this->company->id)
 | 
					            $client_id_search = Client::query()->where('company_id', $this->company->id)
 | 
				
			||||||
                ->where('is_deleted', false)
 | 
					                ->where('is_deleted', false)
 | 
				
			||||||
 | 
				
			|||||||
@ -29,8 +29,11 @@ class TaskTransformer extends BaseTransformer
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->stubbed_timestamp = time();
 | 
					        $this->stubbed_timestamp = time();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $task_data = reset($task_items_data);
 | 
					        if(count($task_items_data) == count($task_items_data, COUNT_RECURSIVE)) 
 | 
				
			||||||
 | 
					            $task_data = $task_items_data;
 | 
				
			||||||
 | 
					        else 
 | 
				
			||||||
 | 
					            $task_data = reset($task_items_data);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        $clientId = $this->getClient(
 | 
					        $clientId = $this->getClient(
 | 
				
			||||||
            $this->getString($task_data, 'client.name'),
 | 
					            $this->getString($task_data, 'client.name'),
 | 
				
			||||||
            $this->getString($task_data, 'client.email')
 | 
					            $this->getString($task_data, 'client.email')
 | 
				
			||||||
 | 
				
			|||||||
@ -492,7 +492,7 @@ class CompanyExport implements ShouldQueue
 | 
				
			|||||||
        $nmo->company = $company_reference;
 | 
					        $nmo->company = $company_reference;
 | 
				
			||||||
        $nmo->settings = $this->company->settings;
 | 
					        $nmo->settings = $this->company->settings;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        NinjaMailerJob::dispatch($nmo, true);
 | 
					        (new NinjaMailerJob($nmo, true))->handle();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
 | 
					        UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ class CSVIngest implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $engine = $this->bootEngine();
 | 
					        $engine = $this->bootEngine();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice'] as $entity) {
 | 
					        foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice', 'task'] as $entity) {
 | 
				
			||||||
            $engine->import($entity);
 | 
					            $engine->import($entity);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ use App\Models\Invoice;
 | 
				
			|||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Models\SystemLog;
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
use App\Models\User;
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use GuzzleHttp\Exception\ClientException;
 | 
					use GuzzleHttp\Exception\ClientException;
 | 
				
			||||||
@ -164,7 +165,7 @@ class NinjaMailerJob implements ShouldQueue
 | 
				
			|||||||
             * this merges a text string with a json object
 | 
					             * this merges a text string with a json object
 | 
				
			||||||
             * need to harvest the ->Message property using the following
 | 
					             * need to harvest the ->Message property using the following
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            if (stripos($e->getMessage(), 'code 406') || stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
 | 
					            if (stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
 | 
				
			||||||
                $message = "Either Attachment too large, or recipient has been suppressed.";
 | 
					                $message = "Either Attachment too large, or recipient has been suppressed.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $this->fail();
 | 
					                $this->fail();
 | 
				
			||||||
@ -174,6 +175,20 @@ class NinjaMailerJob implements ShouldQueue
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (stripos($e->getMessage(), 'code 406')) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $email = $this->nmo->to_user->email ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $message = "Recipient {$email} has been suppressed and cannot receive emails from you.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->fail();
 | 
				
			||||||
 | 
					                $this->logMailError($message, $this->company->clients()->first());
 | 
				
			||||||
 | 
					                $this->cleanUpMailers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //only report once, not on all tries
 | 
					            //only report once, not on all tries
 | 
				
			||||||
            if ($this->attempts() == $this->tries) {
 | 
					            if ($this->attempts() == $this->tries) {
 | 
				
			||||||
                /* If the is an entity attached to the message send a failure mailer */
 | 
					                /* If the is an entity attached to the message send a failure mailer */
 | 
				
			||||||
 | 
				
			|||||||
@ -74,6 +74,7 @@ class EmailPayment implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if($this->settings->payment_email_all_contacts && $this->payment->invoices && $this->payment->invoices->count() >= 1) {
 | 
					            if($this->settings->payment_email_all_contacts && $this->payment->invoices && $this->payment->invoices->count() >= 1) {
 | 
				
			||||||
                $this->emailAllContacts($email_builder);
 | 
					                $this->emailAllContacts($email_builder);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $invitation = null;
 | 
					            $invitation = null;
 | 
				
			||||||
 | 
				
			|||||||
@ -96,8 +96,6 @@ class EmailRefundPayment implements ShouldQueue
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
           
 | 
					 | 
				
			||||||
            $nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
 | 
					            $nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
 | 
				
			||||||
            $nmo->to_user = $this->contact;
 | 
					            $nmo->to_user = $this->contact;
 | 
				
			||||||
            $nmo->settings = $this->settings;
 | 
					            $nmo->settings = $this->settings;
 | 
				
			||||||
 | 
				
			|||||||
@ -388,7 +388,7 @@ class ProcessPostmarkWebhook implements ShouldQueue
 | 
				
			|||||||
                        'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
 | 
					                        'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
 | 
				
			||||||
                        'server' => $event->Details->DestinationServer ??  '',
 | 
					                        'server' => $event->Details->DestinationServer ??  '',
 | 
				
			||||||
                        'server_ip' => $event->Details->DestinationIP ?? '',
 | 
					                        'server_ip' => $event->Details->DestinationIP ?? '',
 | 
				
			||||||
                        'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:m:s') ?? '',
 | 
					                        'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:i:s') ?? '',
 | 
				
			||||||
                    ];
 | 
					                    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            })->toArray();
 | 
					            })->toArray();
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,6 @@
 | 
				
			|||||||
namespace App\Libraries\OAuth\Providers;
 | 
					namespace App\Libraries\OAuth\Providers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Google_Client;
 | 
					use Google_Client;
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Google implements ProviderInterface
 | 
					class Google implements ProviderInterface
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function getTokenResponse($token)
 | 
					    public function getTokenResponse($token)
 | 
				
			||||||
@ -27,4 +26,28 @@ class Google implements ProviderInterface
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $payload['name'];
 | 
					        return $payload['name'];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function harvestUser($access_token)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new Google_Client();
 | 
				
			||||||
 | 
					        $client->setClientId(config('ninja.auth.google.client_id'));
 | 
				
			||||||
 | 
					        $client->setClientSecret(config('ninja.auth.google.client_secret'));
 | 
				
			||||||
 | 
					        $client->setAccessToken($access_token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $oauth2 = new \Google_Service_Oauth2($client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $userInfo = $oauth2->userinfo->get();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'email' => $userInfo['email'],
 | 
				
			||||||
 | 
					            'sub' => $userInfo['id'],
 | 
				
			||||||
 | 
					            'name' => $userInfo['name'],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -103,7 +103,7 @@ class ClientPresenter extends EntityPresenter
 | 
				
			|||||||
        if ($cityState = $this->getShippingCityState()) {
 | 
					        if ($cityState = $this->getShippingCityState()) {
 | 
				
			||||||
            $str .= e($cityState).'<br/>';
 | 
					            $str .= e($cityState).'<br/>';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($country = $client->shipping_country) {
 | 
					        if ($country = $client->shipping_country ?? $client->country) {
 | 
				
			||||||
            $str .= e($country->name).'<br/>';
 | 
					            $str .= e($country->name).'<br/>';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -261,10 +261,10 @@ class Task extends BaseModel
 | 
				
			|||||||
            $parent_entity = $this->client ?? $this->company;
 | 
					            $parent_entity = $this->client ?? $this->company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if($log[0])
 | 
					            if($log[0])
 | 
				
			||||||
                $log[0] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:m:s');
 | 
					                $log[0] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:i:s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if($log[1] && $log[1] != 0)
 | 
					            if($log[1] && $log[1] != 0)
 | 
				
			||||||
                $log[1] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:m:s');
 | 
					                $log[1] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:i:s');
 | 
				
			||||||
            else     
 | 
					            else     
 | 
				
			||||||
                $log[1] = ctrans('texts.running');
 | 
					                $log[1] = ctrans('texts.running');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -291,17 +291,21 @@ class Task extends BaseModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if($log[0])
 | 
					            if($log[0])
 | 
				
			||||||
                $logged['start_date_raw'] = $log[0];
 | 
					                $logged['start_date_raw'] = $log[0];
 | 
				
			||||||
                $logged['start_date'] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:m:s');
 | 
					                $logged['start_date'] = Carbon::createFromTimestamp($log[0])->setTimeZone($this->company->timezone()->name)->format($parent_entity->date_format().' H:i:s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if($log[1] && $log[1] != 0) {
 | 
					            if($log[1] && $log[1] != 0) {
 | 
				
			||||||
                $logged['end_date_raw'] = $log[1];
 | 
					                $logged['end_date_raw'] = $log[1];
 | 
				
			||||||
                $logged['end_date'] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:m:s');
 | 
					                $logged['end_date'] = Carbon::createFromTimestamp($log[1])->setTimeZone($this->company->timezone()->name)->format($parent_entity->date_format().' H:i:s');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else{
 | 
					            else{
 | 
				
			||||||
                $logged['end_date_raw'] = 0;
 | 
					                $logged['end_date_raw'] = 0;
 | 
				
			||||||
                $logged['end_date'] = ctrans('texts.running');
 | 
					                $logged['end_date'] = ctrans('texts.running');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $logged['duration'] = $duration;
 | 
					
 | 
				
			||||||
 | 
					            $logged['description'] = $log[2];
 | 
				
			||||||
 | 
					            $logged['billable'] = $log[3];
 | 
				
			||||||
 | 
					            $logged['duration_raw'] = $duration;
 | 
				
			||||||
 | 
					            $logged['duration'] = gmdate("H:i:s", $duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return $logged;
 | 
					            return $logged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -743,29 +743,20 @@ class BaseDriver extends AbstractPaymentDriver
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoices_string = str_replace(["*","<",">","'",'"'], "-", $invoices_string);
 | 
					        $invoices_string = str_replace(["*","<",">","'",'"'], "-", $invoices_string);
 | 
				
			||||||
        // $invoices_string = "I-".$invoices_string;
 | 
					 | 
				
			||||||
        // $invoices_string = substr($invoices_string, 0, 22);
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
// 2023-11-02 - improve the statement descriptor for string
 | 
					// 2023-11-02 - improve the statement descriptor for string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$company_name = $this->client->company->present()->name();
 | 
					$company_name = $this->client->company->present()->name();
 | 
				
			||||||
 | 
					$company_name = str_replace(["*","<",">","'",'"'], "-", $company_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(ctype_digit(substr($company_name, 0, 1)))
 | 
					if(ctype_digit(substr($company_name, 0, 1))) {
 | 
				
			||||||
    $company_name = "X" . $company_name;
 | 
					    $company_name = "I" . $company_name;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
$suffix = strlen($invoices_string) + 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$length = 22 - $suffix;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$company_name = substr($company_name, 0, $length);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$company_name = substr($company_name, 0, 11);
 | 
				
			||||||
$descriptor = "{$company_name} {$invoices_string}";
 | 
					$descriptor = "{$company_name} {$invoices_string}";
 | 
				
			||||||
 | 
					$descriptor = substr($descriptor, 0, 22);
 | 
				
			||||||
$invoices_string = str_pad($descriptor, 5, ctrans('texts.invoice'), STR_PAD_RIGHT);
 | 
					return $descriptor;
 | 
				
			||||||
$invoices_string = substr($invoices_string, 0, 22);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $invoices_string = str_pad($invoices_string, 5, ctrans('texts.invoice'), STR_PAD_LEFT);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $invoices_string;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ class ClientContactRepository extends BaseRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function save(array $data, Client $client) : void
 | 
					    public function save(array $data, Client $client) : void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //06-09-2022 sometimes users pass a contact object instead of a nested array, this sequence handles this scenario
 | 
					
 | 
				
			||||||
        if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
 | 
					        if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
 | 
				
			||||||
            $contacts = collect($data['contacts']);
 | 
					            $contacts = collect($data['contacts']);
 | 
				
			||||||
        } elseif (isset($data['contacts'])) {
 | 
					        } elseif (isset($data['contacts'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,12 @@ class VendorContactRepository extends BaseRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function save(array $data, Vendor $vendor) : void
 | 
					    public function save(array $data, Vendor $vendor) : void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($data['contacts'])) {
 | 
					
 | 
				
			||||||
 | 
					        if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
 | 
				
			||||||
            $contacts = collect($data['contacts']);
 | 
					            $contacts = collect($data['contacts']);
 | 
				
			||||||
 | 
					        } elseif (isset($data['contacts'])) {
 | 
				
			||||||
 | 
					            $temp_array[] = $data['contacts'];
 | 
				
			||||||
 | 
					            $contacts = collect($temp_array);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $contacts = collect();
 | 
					            $contacts = collect();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -80,10 +84,10 @@ class VendorContactRepository extends BaseRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vendor->load('contacts');
 | 
					        $vendor->fresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //always made sure we have one blank contact to maintain state
 | 
					        //always made sure we have one blank contact to maintain state
 | 
				
			||||||
        if ($vendor->contacts->count() == 0) {
 | 
					        if ($vendor->contacts()->count() == 0) {
 | 
				
			||||||
            $new_contact = new VendorContact;
 | 
					            $new_contact = new VendorContact;
 | 
				
			||||||
            $new_contact->vendor_id = $vendor->id;
 | 
					            $new_contact->vendor_id = $vendor->id;
 | 
				
			||||||
            $new_contact->company_id = $vendor->company_id;
 | 
					            $new_contact->company_id = $vendor->company_id;
 | 
				
			||||||
 | 
				
			|||||||
@ -55,19 +55,15 @@ class VendorRepository extends BaseRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if ($vendor->number == '' || ! $vendor->number) {
 | 
					        if ($vendor->number == '' || ! $vendor->number) {
 | 
				
			||||||
            $vendor->number = $this->getNextVendorNumber($vendor);
 | 
					            $vendor->number = $this->getNextVendorNumber($vendor);
 | 
				
			||||||
        } //todo write tests for this and make sure that custom vendor numbers also works as expected from here
 | 
					        } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vendor->saveQuietly();
 | 
					        $vendor->saveQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isset($data['contacts'])) {
 | 
					        if (isset($data['contacts']) || $vendor->contacts()->count() == 0) {
 | 
				
			||||||
            $this->contact_repo->save($data, $vendor);
 | 
					            $this->contact_repo->save($data, $vendor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (empty($data['name'])) {
 | 
					        if (array_key_exists('documents', $data) && count($data['documents']) >= 1) {
 | 
				
			||||||
            $data['name'] = $vendor->present()->name();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (array_key_exists('documents', $data)) {
 | 
					 | 
				
			||||||
            $this->saveDocuments($data['documents'], $vendor);
 | 
					            $this->saveDocuments($data['documents'], $vendor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -83,6 +83,8 @@ class InstantPayment
 | 
				
			|||||||
                ->with(['message' => 'No payable invoices selected.']);
 | 
					                ->with(['message' => 'No payable invoices selected.']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoices = Invoice::query()->whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->withTrashed()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client = $invoices->first()->client;
 | 
					        $client = $invoices->first()->client;
 | 
				
			||||||
        $settings = $client->getMergedSettings();
 | 
					        $settings = $client->getMergedSettings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -272,11 +272,27 @@ class Email implements ShouldQueue
 | 
				
			|||||||
            nlog("Mailer failed with {$e->getMessage()}");
 | 
					            nlog("Mailer failed with {$e->getMessage()}");
 | 
				
			||||||
            $message = $e->getMessage();
 | 
					            $message = $e->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (stripos($e->getMessage(), 'code 406') || stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
 | 
					
 | 
				
			||||||
                $message = "Either Attachment too large, or recipient has been suppressed.";
 | 
					        if (stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
 | 
				
			||||||
 | 
					            $message = "Either Attachment too large, or recipient has been suppressed.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->fail();
 | 
				
			||||||
 | 
					            $this->logMailError($e->getMessage(), $this->company->clients()->first());
 | 
				
			||||||
 | 
					            $this->cleanUpMailers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (stripos($e->getMessage(), 'code 406')) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $address_object = reset($this->email_object->to);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $email = $address_object->address ?? '';
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                $message = "Recipient {$email} has been suppressed and cannot receive emails from you.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $this->fail();
 | 
					                $this->fail();
 | 
				
			||||||
                $this->logMailError($e->getMessage(), $this->company->clients()->first());
 | 
					                $this->logMailError($message, $this->company->clients()->first());
 | 
				
			||||||
                $this->cleanUpMailers();
 | 
					                $this->cleanUpMailers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,7 @@ class MarkPaid extends AbstractService
 | 
				
			|||||||
            'amount' => $this->payable_balance,
 | 
					            'amount' => $this->payable_balance,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($payment->company->getSetting('send_email_on_mark_paid')) {
 | 
					        if ($payment->client->getSetting('send_email_on_mark_paid')) {
 | 
				
			||||||
            $payment->service()->sendEmail();
 | 
					            $payment->service()->sendEmail();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -96,6 +96,7 @@ class TemplateAction implements ShouldQueue
 | 
				
			|||||||
            Project::class => $resource->with('client'),
 | 
					            Project::class => $resource->with('client'),
 | 
				
			||||||
            Expense::class => $resource->with('client'),
 | 
					            Expense::class => $resource->with('client'),
 | 
				
			||||||
            Payment::class => $resource->with('invoices', 'client'),
 | 
					            Payment::class => $resource->with('invoices', 'client'),
 | 
				
			||||||
 | 
					            Client::class => $resource,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $result = $resource->withTrashed()
 | 
					        $result = $resource->withTrashed()
 | 
				
			||||||
@ -103,13 +104,14 @@ class TemplateAction implements ShouldQueue
 | 
				
			|||||||
            ->where('company_id', $this->company->id)
 | 
					            ->where('company_id', $this->company->id)
 | 
				
			||||||
            ->get();
 | 
					            ->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // nlog($result->toArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($result->count() <= 1) {
 | 
					        if($result->count() <= 1) {
 | 
				
			||||||
            $data[$key] = collect($result);
 | 
					            $data[$key] = collect($result);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $data[$key] = $result;
 | 
					            $data[$key] = $result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        $ts = $template_service
 | 
					        $ts = $template_service
 | 
				
			||||||
                    ->setCompany($this->company)
 | 
					                    ->setCompany($this->company)
 | 
				
			||||||
                    ->build($data);
 | 
					                    ->build($data);
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -11,31 +11,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Services\Template;
 | 
					namespace App\Services\Template;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use App\Models\Quote;
 | 
				
			||||||
 | 
					use App\Utils\Number;
 | 
				
			||||||
 | 
					use Twig\Error\Error;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Models\Credit;
 | 
					use App\Models\Credit;
 | 
				
			||||||
use App\Models\Design;
 | 
					use App\Models\Design;
 | 
				
			||||||
 | 
					use App\Models\Vendor;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Models\Project;
 | 
					use App\Models\Project;
 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					 | 
				
			||||||
use App\Models\Quote;
 | 
					 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					 | 
				
			||||||
use App\Models\Vendor;
 | 
					 | 
				
			||||||
use App\Utils\HostedPDF\NinjaPdf;
 | 
					 | 
				
			||||||
use App\Utils\HtmlEngine;
 | 
					use App\Utils\HtmlEngine;
 | 
				
			||||||
use App\Utils\Number;
 | 
					use Twig\Error\LoaderError;
 | 
				
			||||||
 | 
					use Twig\Error\SyntaxError;
 | 
				
			||||||
 | 
					use Twig\Error\RuntimeError;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Utils\VendorHtmlEngine;
 | 
				
			||||||
 | 
					use Twig\Sandbox\SecurityError;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Utils\PaymentHtmlEngine;
 | 
					use App\Utils\PaymentHtmlEngine;
 | 
				
			||||||
use App\Utils\Traits\MakesDates;
 | 
					use App\Utils\Traits\MakesDates;
 | 
				
			||||||
 | 
					use App\Utils\HostedPDF\NinjaPdf;
 | 
				
			||||||
use App\Utils\Traits\Pdf\PdfMaker;
 | 
					use App\Utils\Traits\Pdf\PdfMaker;
 | 
				
			||||||
use App\Utils\VendorHtmlEngine;
 | 
					 | 
				
			||||||
use League\CommonMark\CommonMarkConverter;
 | 
					 | 
				
			||||||
use Twig\Error\Error;
 | 
					 | 
				
			||||||
use Twig\Error\LoaderError;
 | 
					 | 
				
			||||||
use Twig\Error\RuntimeError;
 | 
					 | 
				
			||||||
use Twig\Error\SyntaxError;
 | 
					 | 
				
			||||||
use Twig\Extra\Intl\IntlExtension;
 | 
					use Twig\Extra\Intl\IntlExtension;
 | 
				
			||||||
use Twig\Sandbox\SecurityError;
 | 
					use League\CommonMark\CommonMarkConverter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TemplateService
 | 
					class TemplateService
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -616,7 +617,7 @@ class TemplateService
 | 
				
			|||||||
            'paymentables' => $pivot,
 | 
					            'paymentables' => $pivot,
 | 
				
			||||||
            'refund_activity' => $this->getPaymentRefundActivity($payment),
 | 
					            'refund_activity' => $this->getPaymentRefundActivity($payment),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return $data;
 | 
					        return $data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -826,11 +827,11 @@ class TemplateService
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function processPayments($payments): array
 | 
					    public function processPayments($payments): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					nlog("processing payments");
 | 
				
			||||||
        $payments = collect($payments)->map(function ($payment) {
 | 
					        $payments = collect($payments)->map(function ($payment) {
 | 
				
			||||||
            return $this->transformPayment($payment);
 | 
					            return $this->transformPayment($payment);
 | 
				
			||||||
        })->toArray();
 | 
					        })->toArray();
 | 
				
			||||||
 | 
					nlog($payments);
 | 
				
			||||||
        return $payments;
 | 
					        return $payments;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -849,7 +850,7 @@ class TemplateService
 | 
				
			|||||||
            return [
 | 
					            return [
 | 
				
			||||||
                'number' => (string) $task->number ?: '',
 | 
					                'number' => (string) $task->number ?: '',
 | 
				
			||||||
                'description' => (string) $task->description ?: '',
 | 
					                'description' => (string) $task->description ?: '',
 | 
				
			||||||
                'duration' => $task->duration ?: 0,
 | 
					                'duration' => $task->calcDuration() ?: 0,
 | 
				
			||||||
                'rate' => Number::formatMoney($task->rate ?? 0, $task->client ?? $task->company),
 | 
					                'rate' => Number::formatMoney($task->rate ?? 0, $task->client ?? $task->company),
 | 
				
			||||||
                'rate_raw' => $task->rate ?? 0,
 | 
					                'rate_raw' => $task->rate ?? 0,
 | 
				
			||||||
                'created_at' => $this->translateDate($task->created_at, $task->client ? $task->client->date_format() : $task->company->date_format(), $task->client ? $task->client->locale() : $task->company->locale()),
 | 
					                'created_at' => $this->translateDate($task->created_at, $task->client ? $task->client->date_format() : $task->company->date_format(), $task->client ? $task->client->locale() : $task->company->locale()),
 | 
				
			||||||
@ -863,6 +864,7 @@ class TemplateService
 | 
				
			|||||||
                'custom_value3' => $task->custom_value3 ?: '',
 | 
					                'custom_value3' => $task->custom_value3 ?: '',
 | 
				
			||||||
                'custom_value4' => $task->custom_value4 ?: '',
 | 
					                'custom_value4' => $task->custom_value4 ?: '',
 | 
				
			||||||
                'status' => $task->status ? $task->status->name : '',
 | 
					                'status' => $task->status ? $task->status->name : '',
 | 
				
			||||||
 | 
					                'user' => $this->userInfo($task->user),
 | 
				
			||||||
                'client' => $task->client ? [
 | 
					                'client' => $task->client ? [
 | 
				
			||||||
                            'name' => $task->client->present()->name(),
 | 
					                            'name' => $task->client->present()->name(),
 | 
				
			||||||
                            'balance' => $task->client->balance,
 | 
					                            'balance' => $task->client->balance,
 | 
				
			||||||
@ -894,6 +896,14 @@ class TemplateService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function userInfo(User $user): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'name' => $user->present()->name(),
 | 
				
			||||||
 | 
					            'email' => $user->email,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function transformProject(Project $project, bool $nested = false): array
 | 
					    private function transformProject(Project $project, bool $nested = false): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -921,7 +931,7 @@ class TemplateService
 | 
				
			|||||||
                    'payment_balance' => $project->client->payment_balance,
 | 
					                    'payment_balance' => $project->client->payment_balance,
 | 
				
			||||||
                    'credit_balance' => $project->client->credit_balance,
 | 
					                    'credit_balance' => $project->client->credit_balance,
 | 
				
			||||||
                ] : [],
 | 
					                ] : [],
 | 
				
			||||||
 | 
					            'user' => $this->userInfo($project->user)
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -136,7 +136,7 @@ class CompanyTransformer extends EntityTransformer
 | 
				
			|||||||
            'custom_fields' =>  (object) $company->custom_fields ?? $std,
 | 
					            'custom_fields' =>  (object) $company->custom_fields ?? $std,
 | 
				
			||||||
            'size_id' => (string) $company->size_id ?: '',
 | 
					            'size_id' => (string) $company->size_id ?: '',
 | 
				
			||||||
            'industry_id' => (string) $company->industry_id ?: '',
 | 
					            'industry_id' => (string) $company->industry_id ?: '',
 | 
				
			||||||
            'first_month_of_year' => (string) $company->first_month_of_year ?: '',
 | 
					            'first_month_of_year' => (string) $company->first_month_of_year ?: '1',
 | 
				
			||||||
            'first_day_of_week' => (string) $company->first_day_of_week ?: '',
 | 
					            'first_day_of_week' => (string) $company->first_day_of_week ?: '',
 | 
				
			||||||
            'subdomain' => (string) $company->subdomain ?: '',
 | 
					            'subdomain' => (string) $company->subdomain ?: '',
 | 
				
			||||||
            'portal_mode' => (string) $company->portal_mode ?: '',
 | 
					            'portal_mode' => (string) $company->portal_mode ?: '',
 | 
				
			||||||
 | 
				
			|||||||
@ -326,7 +326,7 @@ class HtmlEngine
 | 
				
			|||||||
            $data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
 | 
					            $data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
 | 
				
			||||||
            $data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
 | 
					            $data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if ($this->entity->status_id == 1) {
 | 
					            if ($this->entity->status_id == 1 || $this->entity_string == 'recurring_invoice') {
 | 
				
			||||||
                $data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->client) ?: ' ', 'label' => ctrans('texts.balance_due')];
 | 
					                $data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->client) ?: ' ', 'label' => ctrans('texts.balance_due')];
 | 
				
			||||||
                $data['$balance_due_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.balance_due')];
 | 
					                $data['$balance_due_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.balance_due')];
 | 
				
			||||||
                $data['$amount_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.amount')];
 | 
					                $data['$amount_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.amount')];
 | 
				
			||||||
 | 
				
			|||||||
@ -142,8 +142,7 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "scripts": {
 | 
					    "scripts": {
 | 
				
			||||||
        "post-install-cmd": [
 | 
					        "post-install-cmd": [],
 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "post-update-cmd": [
 | 
					        "post-update-cmd": [
 | 
				
			||||||
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
 | 
					            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
@ -173,4 +172,4 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "minimum-stability": "dev",
 | 
					    "minimum-stability": "dev",
 | 
				
			||||||
    "prefer-stable": true
 | 
					    "prefer-stable": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -5189,6 +5189,30 @@ $LANG = array(
 | 
				
			|||||||
    'payment_receipt' => 'Payment Receipt # :number',
 | 
					    'payment_receipt' => 'Payment Receipt # :number',
 | 
				
			||||||
    'load_template_description' => 'The template will be applied to following:',
 | 
					    'load_template_description' => 'The template will be applied to following:',
 | 
				
			||||||
    'run_template' => 'Run template',
 | 
					    'run_template' => 'Run template',
 | 
				
			||||||
 | 
					    'statement_design' => 'Statement Design',
 | 
				
			||||||
 | 
					    'delivery_note_design' => 'Delivery Note Design',
 | 
				
			||||||
 | 
					    'payment_receipt_design' => 'Payment Receipt Design',
 | 
				
			||||||
 | 
					    'payment_refund_design' => 'Payment Refund Design',
 | 
				
			||||||
 | 
					    'task_extension_banner' => 'Add the Chrome extension to manage your tasks',
 | 
				
			||||||
 | 
					    'watch_video' => 'Watch Video',
 | 
				
			||||||
 | 
					    'view_extension' => 'View Extension',
 | 
				
			||||||
 | 
					    'reactivate_email' => 'Reactivate Email',
 | 
				
			||||||
 | 
					    'email_reactivated' => 'Successfully reactivated email',
 | 
				
			||||||
 | 
					    'template_help' => 'Enable using the design as a template',
 | 
				
			||||||
 | 
					    'quarter' => 'Quarter',
 | 
				
			||||||
 | 
					    'item_description' => 'Item Description',
 | 
				
			||||||
 | 
					    'task_item' => 'Task Item',
 | 
				
			||||||
 | 
					    'record_state' => 'Record State',
 | 
				
			||||||
 | 
					    'save_files_to_this_folder' => 'Save files to this folder',
 | 
				
			||||||
 | 
					    'downloads_folder' => 'Downloads Folder',
 | 
				
			||||||
 | 
					    'total_invoiced_quotes' => 'Invoiced Quotes',
 | 
				
			||||||
 | 
					    'total_invoice_paid_quotes' => 'Invoice Paid Quotes',
 | 
				
			||||||
 | 
					    'downloads_folder_does_not_exist' => 'The downloads folder does not exist :value',
 | 
				
			||||||
 | 
					    'user_logged_in_notification' => 'User Logged in Notification',
 | 
				
			||||||
 | 
					    'user_logged_in_notification_help' => 'Send an email when logging in from a new location',
 | 
				
			||||||
 | 
					    'payment_email_all_contacts' => 'Payment Email To All Contacts',
 | 
				
			||||||
 | 
					    'payment_email_all_contacts_help' => 'Sends the payment email to all contacts when enabled',
 | 
				
			||||||
 | 
					    'add_line' => 'Add Line',
 | 
				
			||||||
); 
 | 
					); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return $LANG;
 | 
					return $LANG;
 | 
				
			||||||
 | 
				
			|||||||
@ -2387,6 +2387,9 @@ $LANG = array(
 | 
				
			|||||||
    'currency_libyan_dinar' => 'Libyan Dinar',
 | 
					    'currency_libyan_dinar' => 'Libyan Dinar',
 | 
				
			||||||
    'currency_silver_troy_ounce' => 'Silver Troy Ounce',
 | 
					    'currency_silver_troy_ounce' => 'Silver Troy Ounce',
 | 
				
			||||||
    'currency_gold_troy_ounce' => 'Gold Troy Ounce',
 | 
					    'currency_gold_troy_ounce' => 'Gold Troy Ounce',
 | 
				
			||||||
 | 
					    'currency_nicaraguan_córdoba' => 'Nicaraguan Córdoba',
 | 
				
			||||||
 | 
					    'currency_malagasy_ariary' => 'Malagasy ariary',
 | 
				
			||||||
 | 
					    "currency_tongan_pa_anga" => "Tongan Pa'anga",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'review_app_help' => 'Ci auguriamo che ti piaccia usare l'app.<br/> Se prendessi in considerazione :link lo apprezzeremmo molto!',
 | 
					    'review_app_help' => 'Ci auguriamo che ti piaccia usare l'app.<br/> Se prendessi in considerazione :link lo apprezzeremmo molto!',
 | 
				
			||||||
    'writing_a_review' => 'scrivendo una recensione',
 | 
					    'writing_a_review' => 'scrivendo una recensione',
 | 
				
			||||||
@ -2498,8 +2501,8 @@ $LANG = array(
 | 
				
			|||||||
    'partial_due_date' => 'Data di scadenza parziale',
 | 
					    'partial_due_date' => 'Data di scadenza parziale',
 | 
				
			||||||
    'task_fields' => 'Campi Attività',
 | 
					    'task_fields' => 'Campi Attività',
 | 
				
			||||||
    'product_fields_help' => 'Trascina e rilascia i campi per modificarne l'ordine',
 | 
					    'product_fields_help' => 'Trascina e rilascia i campi per modificarne l'ordine',
 | 
				
			||||||
    'custom_value1' => 'Custom Value 1',
 | 
					    'custom_value1' => 'Valore Personalizzato 1',
 | 
				
			||||||
    'custom_value2' => 'Custom Value 2',
 | 
					    'custom_value2' => 'Valore Personalizzato 2',
 | 
				
			||||||
    'enable_two_factor' => 'Autenticazione a due fattori',
 | 
					    'enable_two_factor' => 'Autenticazione a due fattori',
 | 
				
			||||||
    'enable_two_factor_help' => 'Usa il tuo telefono per confermare la tua identità quando accedi',
 | 
					    'enable_two_factor_help' => 'Usa il tuo telefono per confermare la tua identità quando accedi',
 | 
				
			||||||
    'two_factor_setup' => 'Impostazione autenticazione a due fattori',
 | 
					    'two_factor_setup' => 'Impostazione autenticazione a due fattori',
 | 
				
			||||||
@ -3322,9 +3325,9 @@ $LANG = array(
 | 
				
			|||||||
    'freq_three_years' => 'Tre anni',
 | 
					    'freq_three_years' => 'Tre anni',
 | 
				
			||||||
    'military_time_help' => 'Formato 24 ore',
 | 
					    'military_time_help' => 'Formato 24 ore',
 | 
				
			||||||
    'click_here_capital' => 'Clicca qui',
 | 
					    'click_here_capital' => 'Clicca qui',
 | 
				
			||||||
    'marked_invoice_as_paid' => 'Successfully marked invoice as paid',
 | 
					    'marked_invoice_as_paid' => 'Fattura contrassegnata con successo come inviata',
 | 
				
			||||||
    'marked_invoices_as_sent' => 'Fatture contrassegnate con successo come inviate',
 | 
					    'marked_invoices_as_sent' => 'Fatture contrassegnate con successo come inviate',
 | 
				
			||||||
    'marked_invoices_as_paid' => 'Successfully marked invoices as paid',
 | 
					    'marked_invoices_as_paid' => 'Fatture contrassegnate con successo come inviate',
 | 
				
			||||||
    'activity_57' => 'Il sistema non è riuscito a inviare la fattura :invoice via e-mail',
 | 
					    'activity_57' => 'Il sistema non è riuscito a inviare la fattura :invoice via e-mail',
 | 
				
			||||||
    'custom_value3' => 'Valore Personalizzato 3',
 | 
					    'custom_value3' => 'Valore Personalizzato 3',
 | 
				
			||||||
    'custom_value4' => 'Valore Personalizzato 4',
 | 
					    'custom_value4' => 'Valore Personalizzato 4',
 | 
				
			||||||
@ -3664,9 +3667,9 @@ $LANG = array(
 | 
				
			|||||||
    'send_date' => 'Data di invio',
 | 
					    'send_date' => 'Data di invio',
 | 
				
			||||||
    'auto_bill_on' => 'Fattura automatica attiva',
 | 
					    'auto_bill_on' => 'Fattura automatica attiva',
 | 
				
			||||||
    'minimum_under_payment_amount' => 'Importo minimo sotto pagamento',
 | 
					    'minimum_under_payment_amount' => 'Importo minimo sotto pagamento',
 | 
				
			||||||
    'allow_over_payment' => 'Consenti pagamento in eccesso',
 | 
					    'allow_over_payment' => 'Allow Overpayment',
 | 
				
			||||||
    'allow_over_payment_help' => 'Accetta il pagamento di un extra',
 | 
					    'allow_over_payment_help' => 'Accetta il pagamento di un extra',
 | 
				
			||||||
    'allow_under_payment' => 'Consenti pagamento ridotto',
 | 
					    'allow_under_payment' => 'Allow Underpayment',
 | 
				
			||||||
    'allow_under_payment_help' => 'Accetta il pagamento parziale o di cauzione',
 | 
					    'allow_under_payment_help' => 'Accetta il pagamento parziale o di cauzione',
 | 
				
			||||||
    'test_mode' => 'Modalità di test',
 | 
					    'test_mode' => 'Modalità di test',
 | 
				
			||||||
    'calculated_rate' => 'Tariffa calcolata',
 | 
					    'calculated_rate' => 'Tariffa calcolata',
 | 
				
			||||||
@ -3846,7 +3849,7 @@ $LANG = array(
 | 
				
			|||||||
     'notification_credit_viewed' => 'Il cliente :client ha visualizzato il credito :credit per :amount.',
 | 
					     'notification_credit_viewed' => 'Il cliente :client ha visualizzato il credito :credit per :amount.',
 | 
				
			||||||
     'reset_password_text' => 'Inserire la mail per resettare la password.',
 | 
					     'reset_password_text' => 'Inserire la mail per resettare la password.',
 | 
				
			||||||
     'password_reset' => 'Reset password',
 | 
					     'password_reset' => 'Reset password',
 | 
				
			||||||
     'account_login_text' => 'Welcome! Glad to see you.',
 | 
					     'account_login_text' => 'Benvenuto! Felice di vederti.',
 | 
				
			||||||
     'request_cancellation' => 'Richiedi Cancellazione',
 | 
					     'request_cancellation' => 'Richiedi Cancellazione',
 | 
				
			||||||
     'delete_payment_method' => 'Elimina il metodo di pagamento',
 | 
					     'delete_payment_method' => 'Elimina il metodo di pagamento',
 | 
				
			||||||
     'about_to_delete_payment_method' => 'Stai per eliminare il metodo di pagamento.',
 | 
					     'about_to_delete_payment_method' => 'Stai per eliminare il metodo di pagamento.',
 | 
				
			||||||
@ -3960,11 +3963,11 @@ $LANG = array(
 | 
				
			|||||||
     'add_payment_method_first' => 'aggiungi metodo di pagamento',
 | 
					     'add_payment_method_first' => 'aggiungi metodo di pagamento',
 | 
				
			||||||
     'no_items_selected' => 'Nessun articolo selezionato',
 | 
					     'no_items_selected' => 'Nessun articolo selezionato',
 | 
				
			||||||
     'payment_due' => 'Pagamento dovuto',
 | 
					     'payment_due' => 'Pagamento dovuto',
 | 
				
			||||||
     'account_balance' => 'Account Balance',
 | 
					     'account_balance' => 'Bilancio Account',
 | 
				
			||||||
     'thanks' => 'Grazie',
 | 
					     'thanks' => 'Grazie',
 | 
				
			||||||
     'minimum_required_payment' => 'Il pagamento minimo richiesto è :amount',
 | 
					     'minimum_required_payment' => 'Il pagamento minimo richiesto è :amount',
 | 
				
			||||||
     'under_payments_disabled' => 'L\'azienda non supporta i sotto-pagamenti',
 | 
					     'under_payments_disabled' => 'Company doesn\'t support underpayments.',
 | 
				
			||||||
     'over_payments_disabled' => 'L\'azienda non supporta i sovra-pagamenti',
 | 
					     'over_payments_disabled' => 'Company doesn\'t support overpayments.',
 | 
				
			||||||
     'saved_at' => 'Salvato alle :time',
 | 
					     'saved_at' => 'Salvato alle :time',
 | 
				
			||||||
     'credit_payment' => 'Credito applicato alla fattura :invoice_number',
 | 
					     'credit_payment' => 'Credito applicato alla fattura :invoice_number',
 | 
				
			||||||
     'credit_subject' => 'Nuovo credito :number da :account',
 | 
					     'credit_subject' => 'Nuovo credito :number da :account',
 | 
				
			||||||
@ -4639,8 +4642,8 @@ $LANG = array(
 | 
				
			|||||||
    'search_purchase_order' => 'Cerca ordine d'acquisto',
 | 
					    'search_purchase_order' => 'Cerca ordine d'acquisto',
 | 
				
			||||||
    'search_purchase_orders' => 'Cerca ordini di acquisto',
 | 
					    'search_purchase_orders' => 'Cerca ordini di acquisto',
 | 
				
			||||||
    'login_url' => 'URL di accesso',
 | 
					    'login_url' => 'URL di accesso',
 | 
				
			||||||
    'enable_applying_payments' => 'Abilita l'applicazione dei pagamenti',
 | 
					    'enable_applying_payments' => 'Manual Overpayments',
 | 
				
			||||||
    'enable_applying_payments_help' => 'Supporta la creazione e l'applicazione separate dei pagamenti',
 | 
					    'enable_applying_payments_help' => 'Support adding an overpayment amount manually on a payment',
 | 
				
			||||||
    'stock_quantity' => 'Quantità in magazzino',
 | 
					    'stock_quantity' => 'Quantità in magazzino',
 | 
				
			||||||
    'notification_threshold' => 'Soglia di notifica',
 | 
					    'notification_threshold' => 'Soglia di notifica',
 | 
				
			||||||
    'track_inventory' => 'Tieni traccia dell'inventario',
 | 
					    'track_inventory' => 'Tieni traccia dell'inventario',
 | 
				
			||||||
@ -5151,7 +5154,26 @@ $LANG = array(
 | 
				
			|||||||
    'government' => 'Government',
 | 
					    'government' => 'Government',
 | 
				
			||||||
    'in_stock_quantity' => 'Stock quantity',
 | 
					    'in_stock_quantity' => 'Stock quantity',
 | 
				
			||||||
    'vendor_contact' => 'Vendor Contact',
 | 
					    'vendor_contact' => 'Vendor Contact',
 | 
				
			||||||
 | 
					    'expense_status_4' => 'Unpaid',
 | 
				
			||||||
 | 
					    'expense_status_5' => 'Paid',
 | 
				
			||||||
 | 
					    'ziptax_help' => 'Note: this feature requires a Zip-Tax API key to lookup US sales tax by address',
 | 
				
			||||||
 | 
					    'cache_data' => 'Cache Data',
 | 
				
			||||||
 | 
					    'unknown' => 'Unknown',
 | 
				
			||||||
 | 
					    'webhook_failure' => 'Webhook Failure',
 | 
				
			||||||
 | 
					    'email_opened' => 'Email Opened',
 | 
				
			||||||
 | 
					    'email_delivered' => 'Email Delivered',
 | 
				
			||||||
 | 
					    'log' => 'Log',
 | 
				
			||||||
 | 
					    'classification' => 'Classification',
 | 
				
			||||||
 | 
					    'stock_quantity_number' => 'Stock :quantity',
 | 
				
			||||||
 | 
					    'upcoming' => 'Upcoming',
 | 
				
			||||||
 | 
					    'client_contact' => 'Client Contact',
 | 
				
			||||||
 | 
					    'uncategorized' => 'Uncategorized',
 | 
				
			||||||
 | 
					    'login_notification' => 'Login Notification',
 | 
				
			||||||
 | 
					    'login_notification_help' => 'Sends an email notifying that a login has taken place.',
 | 
				
			||||||
 | 
					    'payment_refund_receipt' => 'Payment Refund Receipt # :number',
 | 
				
			||||||
 | 
					    'payment_receipt' => 'Payment Receipt # :number',
 | 
				
			||||||
 | 
					    'load_template_description' => 'The template will be applied to following:',
 | 
				
			||||||
 | 
					    'run_template' => 'Run template',
 | 
				
			||||||
); 
 | 
					); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return $LANG;
 | 
					return $LANG;
 | 
				
			||||||
 | 
				
			|||||||
@ -17855,18 +17855,22 @@ components:
 | 
				
			|||||||
          description: 'The hashed if of the contact'
 | 
					          description: 'The hashed if of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        user_id:
 | 
					        user_id:
 | 
				
			||||||
          description: 'The hashed id of the user who created the contact'
 | 
					          description: 'The hashed id of the user who created the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        company_id:
 | 
					        company_id:
 | 
				
			||||||
          description: 'The hashed id of the company'
 | 
					          description: 'The hashed id of the company'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        client_id:
 | 
					        client_id:
 | 
				
			||||||
          description: 'The hashed id of the client'
 | 
					          description: 'The hashed id of the client'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        first_name:
 | 
					        first_name:
 | 
				
			||||||
          description: 'The first name of the contact'
 | 
					          description: 'The first name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -17903,18 +17907,26 @@ components:
 | 
				
			|||||||
          description: 'The terms of service which the contact has accpeted'
 | 
					          description: 'The terms of service which the contact has accpeted'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 'A long set of ToS'
 | 
					          example: 'A long set of ToS'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        password:
 | 
					        password:
 | 
				
			||||||
          description: 'The hashed password of the contact'
 | 
					          description: 'The hashed password of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: '*****'
 | 
					          example: '*****'
 | 
				
			||||||
        confirmation-code:
 | 
					        confirmation_code:
 | 
				
			||||||
          description: 'The confirmation code used to authenticate the contacts email address'
 | 
					          description: 'The confirmation code used to authenticate the contacts email address'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 333-sdjkh34gbasd
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        token:
 | 
					        token:
 | 
				
			||||||
          description: 'A uuid based token.'
 | 
					          description: 'A uuid based token.'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 333-sdjkh34gbasd
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        contact_key:
 | 
				
			||||||
 | 
					          description: 'A unique identifier for the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        is_primary:
 | 
					        is_primary:
 | 
				
			||||||
          description: 'Defines is this contact is the primary contact for the client'
 | 
					          description: 'Defines is this contact is the primary contact for the client'
 | 
				
			||||||
          type: boolean
 | 
					          type: boolean
 | 
				
			||||||
@ -17936,31 +17948,37 @@ components:
 | 
				
			|||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '3'
 | 
					          example: '3'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        email_verified_at:
 | 
					        email_verified_at:
 | 
				
			||||||
          description: 'The date which the contact confirmed their email'
 | 
					          description: 'The date which the contact confirmed their email'
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        last_login:
 | 
					        last_login:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        created_at:
 | 
					        created_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        updated_at:
 | 
					        updated_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        deleted_at:
 | 
					        deleted_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
    ClientContactRequest:
 | 
					    ClientContactRequest:
 | 
				
			||||||
      properties:
 | 
					      properties:
 | 
				
			||||||
@ -18021,14 +18039,17 @@ components:
 | 
				
			|||||||
          description: 'The hashed id of the user id'
 | 
					          description: 'The hashed id of the user id'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        company_id:
 | 
					        company_id:
 | 
				
			||||||
          description: 'The hashed id of the company'
 | 
					          description: 'The hashed id of the company'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        vendor_id:
 | 
					        vendor_id:
 | 
				
			||||||
          description: 'The hashed id of the vendor'
 | 
					          description: 'The hashed id of the vendor'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        first_name:
 | 
					        first_name:
 | 
				
			||||||
          description: 'The first name of the contact'
 | 
					          description: 'The first name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -18037,6 +18058,16 @@ components:
 | 
				
			|||||||
          description: 'The last name of the contact'
 | 
					          description: 'The last name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Windsor
 | 
					          example: Windsor
 | 
				
			||||||
 | 
					        contact_key:
 | 
				
			||||||
 | 
					          description: 'A unique identifier for the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        confirmation_code:
 | 
				
			||||||
 | 
					          description: 'The confirmation code used to authenticate the contacts email address'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        phone:
 | 
					        phone:
 | 
				
			||||||
          description: 'The contacts phone number'
 | 
					          description: 'The contacts phone number'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -18061,6 +18092,16 @@ components:
 | 
				
			|||||||
          description: 'The contact email address'
 | 
					          description: 'The contact email address'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: harry@windsor.com
 | 
					          example: harry@windsor.com
 | 
				
			||||||
 | 
					        email_verified_at:
 | 
				
			||||||
 | 
					          description: 'The date which the contact confirmed their email'
 | 
				
			||||||
 | 
					          type: number
 | 
				
			||||||
 | 
					          format: integer
 | 
				
			||||||
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        password:
 | 
				
			||||||
 | 
					          description: 'The hashed password of the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: '*****'
 | 
				
			||||||
        is_primary:
 | 
					        is_primary:
 | 
				
			||||||
          description: 'Boolean flag determining if the contact is the primary contact for the vendor'
 | 
					          description: 'Boolean flag determining if the contact is the primary contact for the vendor'
 | 
				
			||||||
          type: boolean
 | 
					          type: boolean
 | 
				
			||||||
@ -19392,10 +19433,6 @@ components:
 | 
				
			|||||||
          description: 'The hashed id of the company. This is a unique identifier for the company.'
 | 
					          description: 'The hashed id of the company. This is a unique identifier for the company.'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
        client_id:
 | 
					 | 
				
			||||||
          description: 'The hashed id of the client. This is a unique identifier for the client.'
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          example: Opnel5aKBz
 | 
					 | 
				
			||||||
        contacts:
 | 
					        contacts:
 | 
				
			||||||
          type: array
 | 
					          type: array
 | 
				
			||||||
          items:
 | 
					          items:
 | 
				
			||||||
@ -19525,8 +19562,6 @@ components:
 | 
				
			|||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 'Bob the vendor'
 | 
					          example: 'Bob the vendor'
 | 
				
			||||||
          readOnly: true
 | 
					          readOnly: true
 | 
				
			||||||
        settings:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/CompanySettings'
 | 
					 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
    ClientSettings:
 | 
					    ClientSettings:
 | 
				
			||||||
      required:
 | 
					      required:
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,22 @@
 | 
				
			|||||||
          description: 'The hashed if of the contact'
 | 
					          description: 'The hashed if of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        user_id:
 | 
					        user_id:
 | 
				
			||||||
          description: 'The hashed id of the user who created the contact'
 | 
					          description: 'The hashed id of the user who created the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        company_id:
 | 
					        company_id:
 | 
				
			||||||
          description: 'The hashed id of the company'
 | 
					          description: 'The hashed id of the company'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        client_id:
 | 
					        client_id:
 | 
				
			||||||
          description: 'The hashed id of the client'
 | 
					          description: 'The hashed id of the client'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        first_name:
 | 
					        first_name:
 | 
				
			||||||
          description: 'The first name of the contact'
 | 
					          description: 'The first name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -52,18 +56,26 @@
 | 
				
			|||||||
          description: 'The terms of service which the contact has accpeted'
 | 
					          description: 'The terms of service which the contact has accpeted'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 'A long set of ToS'
 | 
					          example: 'A long set of ToS'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        password:
 | 
					        password:
 | 
				
			||||||
          description: 'The hashed password of the contact'
 | 
					          description: 'The hashed password of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: '*****'
 | 
					          example: '*****'
 | 
				
			||||||
        confirmation-code:
 | 
					        confirmation_code:
 | 
				
			||||||
          description: 'The confirmation code used to authenticate the contacts email address'
 | 
					          description: 'The confirmation code used to authenticate the contacts email address'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 333-sdjkh34gbasd
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        token:
 | 
					        token:
 | 
				
			||||||
          description: 'A uuid based token.'
 | 
					          description: 'A uuid based token.'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 333-sdjkh34gbasd
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        contact_key:
 | 
				
			||||||
 | 
					          description: 'A unique identifier for the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        is_primary:
 | 
					        is_primary:
 | 
				
			||||||
          description: 'Defines is this contact is the primary contact for the client'
 | 
					          description: 'Defines is this contact is the primary contact for the client'
 | 
				
			||||||
          type: boolean
 | 
					          type: boolean
 | 
				
			||||||
@ -85,29 +97,35 @@
 | 
				
			|||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '3'
 | 
					          example: '3'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        email_verified_at:
 | 
					        email_verified_at:
 | 
				
			||||||
          description: 'The date which the contact confirmed their email'
 | 
					          description: 'The date which the contact confirmed their email'
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        last_login:
 | 
					        last_login:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        created_at:
 | 
					        created_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        updated_at:
 | 
					        updated_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        deleted_at:
 | 
					        deleted_at:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
          format: integer
 | 
					          format: integer
 | 
				
			||||||
          example: '134341234234'
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
@ -17,10 +17,6 @@
 | 
				
			|||||||
          description: 'The hashed id of the company. This is a unique identifier for the company.'
 | 
					          description: 'The hashed id of the company. This is a unique identifier for the company.'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
        client_id:
 | 
					 | 
				
			||||||
          description: 'The hashed id of the client. This is a unique identifier for the client.'
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          example: Opnel5aKBz
 | 
					 | 
				
			||||||
        contacts:
 | 
					        contacts:
 | 
				
			||||||
          type: array
 | 
					          type: array
 | 
				
			||||||
          items:
 | 
					          items:
 | 
				
			||||||
@ -150,6 +146,4 @@
 | 
				
			|||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: 'Bob the vendor'
 | 
					          example: 'Bob the vendor'
 | 
				
			||||||
          readOnly: true
 | 
					          readOnly: true
 | 
				
			||||||
        settings:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/CompanySettings'
 | 
					 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
@ -9,14 +9,17 @@
 | 
				
			|||||||
          description: 'The hashed id of the user id'
 | 
					          description: 'The hashed id of the user id'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        company_id:
 | 
					        company_id:
 | 
				
			||||||
          description: 'The hashed id of the company'
 | 
					          description: 'The hashed id of the company'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        vendor_id:
 | 
					        vendor_id:
 | 
				
			||||||
          description: 'The hashed id of the vendor'
 | 
					          description: 'The hashed id of the vendor'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Opnel5aKBz
 | 
					          example: Opnel5aKBz
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        first_name:
 | 
					        first_name:
 | 
				
			||||||
          description: 'The first name of the contact'
 | 
					          description: 'The first name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -25,6 +28,16 @@
 | 
				
			|||||||
          description: 'The last name of the contact'
 | 
					          description: 'The last name of the contact'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: Windsor
 | 
					          example: Windsor
 | 
				
			||||||
 | 
					        contact_key:
 | 
				
			||||||
 | 
					          description: 'A unique identifier for the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        confirmation_code:
 | 
				
			||||||
 | 
					          description: 'The confirmation code used to authenticate the contacts email address'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: 333-sdjkh34gbasd
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
        phone:
 | 
					        phone:
 | 
				
			||||||
          description: 'The contacts phone number'
 | 
					          description: 'The contacts phone number'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
@ -49,6 +62,16 @@
 | 
				
			|||||||
          description: 'The contact email address'
 | 
					          description: 'The contact email address'
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          example: harry@windsor.com
 | 
					          example: harry@windsor.com
 | 
				
			||||||
 | 
					        email_verified_at:
 | 
				
			||||||
 | 
					          description: 'The date which the contact confirmed their email'
 | 
				
			||||||
 | 
					          type: number
 | 
				
			||||||
 | 
					          format: integer
 | 
				
			||||||
 | 
					          example: '134341234234'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        password:
 | 
				
			||||||
 | 
					          description: 'The hashed password of the contact'
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					          example: '*****'
 | 
				
			||||||
        is_primary:
 | 
					        is_primary:
 | 
				
			||||||
          description: 'Boolean flag determining if the contact is the primary contact for the vendor'
 | 
					          description: 'Boolean flag determining if the contact is the primary contact for the vendor'
 | 
				
			||||||
          type: boolean
 | 
					          type: boolean
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,24 @@ class VendorApiTest extends TestCase
 | 
				
			|||||||
        Model::reguard();
 | 
					        Model::reguard();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testVendorContactCreation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'name' => 'hewwo',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					        ])->postJson('/api/v1/vendors', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals('hewwo', $arr['data']['name']);
 | 
				
			||||||
 | 
					        $this->assertEquals(1, count($arr['data']['contacts']));
 | 
				
			||||||
 | 
					    }   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testVendorLoggedInEvents()
 | 
					    public function testVendorLoggedInEvents()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $v = \App\Models\Vendor::factory()->create([
 | 
					        $v = \App\Models\Vendor::factory()->create([
 | 
				
			||||||
@ -69,12 +87,6 @@ class VendorApiTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Event::assertDispatched(VendorContactLoggedIn::class);
 | 
					        Event::assertDispatched(VendorContactLoggedIn::class);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // $vc->fresh();
 | 
					 | 
				
			||||||
        // $v->fresh();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $this->assertNotNull($vc->fresh()->last_login);
 | 
					 | 
				
			||||||
        // $this->assertNotNull($v->fresh()->last_login);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testVendorLocale()
 | 
					    public function testVendorLocale()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user