mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 05:47:34 -05:00 
			
		
		
		
	
						commit
						cd0dce3816
					
				
							
								
								
									
										49
									
								
								app/DataMapper/Analytics/AccountCreated.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/DataMapper/Analytics/AccountCreated.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper\Analytics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccountCreated
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type of Sample.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Monotonically incrementing counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 	- counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $type = 'counter';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the counter.
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $name = 'account.created';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The datetime of the counter measurement.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * date("Y-m-d H:i:s")
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var DateTime
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The increment amount... should always be
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $metric = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								app/DataMapper/Analytics/AccountDeleted.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/DataMapper/Analytics/AccountDeleted.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper\Analytics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccountDeleted
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type of Sample.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Monotonically incrementing counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 	- counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $type = 'counter';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the counter.
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $name = 'account.deleted';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The datetime of the counter measurement.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * date("Y-m-d H:i:s")
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var DateTime
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The increment amount... should always be
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $metric = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								app/DataMapper/Analytics/EmailInvoiceFailure.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/DataMapper/Analytics/EmailInvoiceFailure.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper\Analytics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EmailInvoiceFailure
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type of Sample.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Monotonically incrementing counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 	- counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $type = 'mixed_metric';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the counter.
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $name = 'job.failure.email_invoice';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The datetime of the counter measurement.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * date("Y-m-d H:i:s")
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var DateTime
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The Class failure name
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric5 = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The exception string
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric6 = '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								app/DataMapper/Analytics/MigrationFailure.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/DataMapper/Analytics/MigrationFailure.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper\Analytics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MigrationFailure
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type of Sample.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Monotonically incrementing counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 	- counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $type = 'mixed_metric';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the counter.
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $name = 'job.failure.migration';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The datetime of the counter measurement.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * date("Y-m-d H:i:s")
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var DateTime
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The Class failure name
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric5 = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The exception string
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric6 = '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								app/DataMapper/Analytics/SendRecurringFailure.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/DataMapper/Analytics/SendRecurringFailure.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper\Analytics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SendRecurringFailure
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type of Sample.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Monotonically incrementing counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 	- counter
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $type = 'mixed_metric';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the counter.
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $name = 'job.failure.send_recurring';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The datetime of the counter measurement.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * date("Y-m-d H:i:s")
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var DateTime
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The Class failure name
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric5 = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The exception string
 | 
				
			||||||
 | 
					     * set to 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $string_metric6 = '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								app/Factory/ProjectFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Factory/ProjectFactory.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProjectFactory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static function create(int $company_id, int $user_id) :Project
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $project = new Project;
 | 
				
			||||||
 | 
					        $project->company_id = $company_id;
 | 
				
			||||||
 | 
					        $project->user_id = $user_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $project->public_notes = '';
 | 
				
			||||||
 | 
					        $project->private_notes = '';
 | 
				
			||||||
 | 
					        $project->budgeted_hours = 0;
 | 
				
			||||||
 | 
					        $project->task_rate = 0;
 | 
				
			||||||
 | 
					        $project->name = '';
 | 
				
			||||||
 | 
					        $project->custom_value1 = '';
 | 
				
			||||||
 | 
					        $project->custom_value2 = '';
 | 
				
			||||||
 | 
					        $project->custom_value3 = '';
 | 
				
			||||||
 | 
					        $project->custom_value4 = '';
 | 
				
			||||||
 | 
					        $project->is_deleted = 0;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $project;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -30,7 +30,7 @@ class RecurringInvoiceToInvoiceFactory
 | 
				
			|||||||
        $invoice->terms = $recurring_invoice->terms;
 | 
					        $invoice->terms = $recurring_invoice->terms;
 | 
				
			||||||
        $invoice->public_notes = $recurring_invoice->public_notes;
 | 
					        $invoice->public_notes = $recurring_invoice->public_notes;
 | 
				
			||||||
        $invoice->private_notes = $recurring_invoice->private_notes;
 | 
					        $invoice->private_notes = $recurring_invoice->private_notes;
 | 
				
			||||||
        $invoice->date = date_create()->format($client->date_format());
 | 
					        //$invoice->date = now()->format($client->date_format());
 | 
				
			||||||
        $invoice->due_date = $recurring_invoice->calculateDueDate($recurring_invoice->next_send_date);
 | 
					        $invoice->due_date = $recurring_invoice->calculateDueDate($recurring_invoice->next_send_date);
 | 
				
			||||||
        $invoice->is_deleted = $recurring_invoice->is_deleted;
 | 
					        $invoice->is_deleted = $recurring_invoice->is_deleted;
 | 
				
			||||||
        $invoice->line_items = $recurring_invoice->line_items;
 | 
					        $invoice->line_items = $recurring_invoice->line_items;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										145
									
								
								app/Filters/ProjectFilters.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								app/Filters/ProjectFilters.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Filters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Gate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ProjectFilters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ProjectFilters extends QueryFilters
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filter based on search text.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string query filter
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function filter(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return  $this->builder->where(function ($query) use ($filter) {
 | 
				
			||||||
 | 
					            $query->where('projects.name', 'like', '%'.$filter.'%')
 | 
				
			||||||
 | 
					                  ->orWhere('projects.public_notes', 'like', '%'.$filter.'%')
 | 
				
			||||||
 | 
					                  ->orWhere('projects.private_notes', 'like', '%'.$filter.'%');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the list based on the status
 | 
				
			||||||
 | 
					     * archived, active, deleted.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string filter
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function status(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $table = 'projects';
 | 
				
			||||||
 | 
					        $filters = explode(',', $filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->where(function ($query) use ($filters, $table) {
 | 
				
			||||||
 | 
					            $query->whereNull($table.'.id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ACTIVE, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhereNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ARCHIVED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query) use ($table) {
 | 
				
			||||||
 | 
					                    $query->whereNotNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (! in_array($table, ['users'])) {
 | 
				
			||||||
 | 
					                        $query->where($table.'.is_deleted', '=', 0);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_DELETED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere($table.'.is_deleted', '=', 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Sorts the list based on $sort.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string sort formatted as column|asc
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sort(string $sort) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $sort_col = explode('|', $sort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the base query.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int company_id
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function baseQuery(int $company_id, User $user) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = DB::table('projects')
 | 
				
			||||||
 | 
					            ->join('companies', 'companies.id', '=', 'projects.company_id')
 | 
				
			||||||
 | 
					            ->where('projects.company_id', '=', $company_id)
 | 
				
			||||||
 | 
					            //->whereRaw('(projects.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
				
			||||||
 | 
					            ->select(
 | 
				
			||||||
 | 
					                'projects.id',
 | 
				
			||||||
 | 
					                'projects.name',
 | 
				
			||||||
 | 
					                'projects.public_notes',
 | 
				
			||||||
 | 
					                'projects.private_notes',
 | 
				
			||||||
 | 
					                'projects.created_at',
 | 
				
			||||||
 | 
					                'projects.created_at as project_created_at',
 | 
				
			||||||
 | 
					                'projects.deleted_at',
 | 
				
			||||||
 | 
					                'projects.is_deleted',
 | 
				
			||||||
 | 
					                'projects.user_id',
 | 
				
			||||||
 | 
					                'projects.assigned_user_id',
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * If the user does not have permissions to view all invoices
 | 
				
			||||||
 | 
					         * limit the user to only the invoices they have created
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (Gate::denies('view-list', Project::class)) {
 | 
				
			||||||
 | 
					            $query->where('projects.user_id', '=', $user->id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the query by the users company ID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param $company_id The company Id
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function entityFilter()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //return $this->builder->whereCompanyId(auth()->user()->company()->id);
 | 
				
			||||||
 | 
					        return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -230,7 +230,10 @@ class InvoiceItemSum
 | 
				
			|||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
					            //$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
				
			||||||
 | 
					            $amount = ( $this->sub_total > 0 ) ? $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total)) : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
 | 
					            $item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $item_tax += $item_tax_rate1_total;
 | 
					            $item_tax += $item_tax_rate1_total;
 | 
				
			||||||
@ -260,7 +263,8 @@ class InvoiceItemSum
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Sets default values for the line_items.
 | 
					     * Sets default casts for the values in the line_items.
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
     * @return $this
 | 
					     * @return $this
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private function cleanLineItem()
 | 
					    private function cleanLineItem()
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\AccountDeleted;
 | 
				
			||||||
use App\DataMapper\CompanySettings;
 | 
					use App\DataMapper\CompanySettings;
 | 
				
			||||||
use App\DataMapper\DefaultSettings;
 | 
					use App\DataMapper\DefaultSettings;
 | 
				
			||||||
use App\Http\Requests\Company\CreateCompanyRequest;
 | 
					use App\Http\Requests\Company\CreateCompanyRequest;
 | 
				
			||||||
@ -40,6 +41,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
 | 
				
			|||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Illuminate\Support\Facades\Auth;
 | 
					use Illuminate\Support\Facades\Auth;
 | 
				
			||||||
use Illuminate\Support\Facades\Hash;
 | 
					use Illuminate\Support\Facades\Hash;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class CompanyController.
 | 
					 * Class CompanyController.
 | 
				
			||||||
@ -471,6 +473,11 @@ class CompanyController extends BaseController
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $account->delete();
 | 
					            $account->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LightLogs::create(new AccountDeleted())
 | 
				
			||||||
 | 
					                     ->increment()
 | 
				
			||||||
 | 
					                     ->batch();
 | 
				
			||||||
 | 
					                 
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $company_id = $company->id;
 | 
					            $company_id = $company->id;
 | 
				
			||||||
            $company->delete();
 | 
					            $company->delete();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										485
									
								
								app/Http/Controllers/ProjectController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										485
									
								
								app/Http/Controllers/ProjectController.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,485 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Factory\ProjectFactory;
 | 
				
			||||||
 | 
					use App\Filters\ProjectFilters;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\CreateProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\DestroyProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\EditProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\ShowProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\StoreProjectRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Project\UpdateProjectRequest;
 | 
				
			||||||
 | 
					use App\Jobs\Entity\ActionEntity;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Repositories\ProjectRepository;
 | 
				
			||||||
 | 
					use App\Transformers\ProjectTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Traits\BulkOptions;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class ProjectController.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ProjectController extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $entity_type = Project::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $entity_transformer = ProjectTransformer::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $project_repo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * ProjectController constructor.
 | 
				
			||||||
 | 
					     * @param ProjectRepository $projectRepo
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(ProjectRepository $project_repo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::__construct();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->project_repo = $project_repo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *      @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects",
 | 
				
			||||||
 | 
					     *      operationId="getProjects",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Gets a list of projects",
 | 
				
			||||||
 | 
					     *      description="Lists projects",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/index"),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="A list of projects",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index(ProjectFilters $filters)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $projects = Project::filter($filters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->listResponse($projects);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Display the specified resource.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/{id}",
 | 
				
			||||||
 | 
					     *      operationId="showProject",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Shows a project",
 | 
				
			||||||
 | 
					     *      description="Displays a project by id",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="id",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Project Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns the expense object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function show(ShowProjectRequest $request, Project $project)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->itemResponse($project);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Show the form for editing the specified resource.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/{id}/edit",
 | 
				
			||||||
 | 
					     *      operationId="editProject",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Shows a project for editting",
 | 
				
			||||||
 | 
					     *      description="Displays a project by id",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="id",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Project Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns the project object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit(EditProjectRequest $request, Project $project)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->itemResponse($project);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Update the specified resource in storage.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  \Illuminate\Http\Request  $request
 | 
				
			||||||
 | 
					     * @param  App\Models\Project $project
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Put(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/{id}",
 | 
				
			||||||
 | 
					     *      operationId="updateProject",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Updates a project",
 | 
				
			||||||
 | 
					     *      description="Handles the updating of a project by id",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="id",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Project Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns the project object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function update(UpdateProjectRequest $request, Project $project)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($request->entityIsDeleted($project)) {
 | 
				
			||||||
 | 
					            return $request->disallowUpdate();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $project->fill($request->all());
 | 
				
			||||||
 | 
					        $project->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->itemResponse($project->fresh());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Show the form for creating a new resource.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/create",
 | 
				
			||||||
 | 
					     *      operationId="getProjectsCreate",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Gets a new blank project object",
 | 
				
			||||||
 | 
					     *      description="Returns a blank object with default values",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="A blank project object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function create(CreateProjectRequest $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $project = ProjectFactory::create(auth()->user()->company()->id, auth()->user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->itemResponse($project);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Store a newly created resource in storage.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  \Illuminate\Http\Request  $request
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects",
 | 
				
			||||||
 | 
					     *      operationId="storeProject",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Adds a project",
 | 
				
			||||||
 | 
					     *      description="Adds an project to a company",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns the saved project object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function store(StoreProjectRequest $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $project = ProjectFactory::create(auth()->user()->company()->id, auth()->user()->id);
 | 
				
			||||||
 | 
					        $project->fill($request->all());
 | 
				
			||||||
 | 
					        $project->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->itemResponse($project->fresh());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Remove the specified resource from storage.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Delete(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/{id}",
 | 
				
			||||||
 | 
					     *      operationId="deleteProject",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Deletes a project",
 | 
				
			||||||
 | 
					     *      description="Handles the deletion of a project by id",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="id",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Project Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns a HTTP status",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function destroy(DestroyProjectRequest $request, Project $project)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //may not need these destroy routes as we are using actions to 'archive/delete'
 | 
				
			||||||
 | 
					        $project->is_deleted = true;
 | 
				
			||||||
 | 
					        $project->delete();
 | 
				
			||||||
 | 
					        $project->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response()->json([], 200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Perform bulk actions on the list view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param BulkProjectRequest $request
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/projects/bulk",
 | 
				
			||||||
 | 
					     *      operationId="bulkProjects",
 | 
				
			||||||
 | 
					     *      tags={"projects"},
 | 
				
			||||||
 | 
					     *      summary="Performs bulk actions on an array of projects",
 | 
				
			||||||
 | 
					     *      description="",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/index"),
 | 
				
			||||||
 | 
					     *      @OA\RequestBody(
 | 
				
			||||||
 | 
					     *         description="User credentials",
 | 
				
			||||||
 | 
					     *         required=true,
 | 
				
			||||||
 | 
					     *         @OA\MediaType(
 | 
				
			||||||
 | 
					     *             mediaType="application/json",
 | 
				
			||||||
 | 
					     *             @OA\Schema(
 | 
				
			||||||
 | 
					     *                 type="array",
 | 
				
			||||||
 | 
					     *                 @OA\Items(
 | 
				
			||||||
 | 
					     *                     type="integer",
 | 
				
			||||||
 | 
					     *                     description="Array of hashed IDs to be bulk 'actioned",
 | 
				
			||||||
 | 
					     *                     example="[0,1,2,3]",
 | 
				
			||||||
 | 
					     *                 ),
 | 
				
			||||||
 | 
					     *             )
 | 
				
			||||||
 | 
					     *         )
 | 
				
			||||||
 | 
					     *     ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="The Project User response",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/Project"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function bulk()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $action = request()->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = request()->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $projects = Project::withTrashed()->find($this->transformKeys($ids));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $projects->each(function ($project, $key) use ($action) {
 | 
				
			||||||
 | 
					            if (auth()->user()->can('edit', $project)) {
 | 
				
			||||||
 | 
					                $this->project_repo->{$action}($project);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->listResponse(Project::withTrashed()->whereIn('id', $this->transformKeys($ids)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,47 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Http\Requests\Client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Utils\Traits\BulkOptions;
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Http\FormRequest;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BulkClientRequest extends FormRequest
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    use BulkOptions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determine if the user is authorized to make this request.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function authorize()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (! $this->has('action')) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! in_array($this->action, $this->getBulkOptions(), true)) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return auth()->user()->can(auth()->user()->isAdmin(), Client::class);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Get the validation rules that apply to the request.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function rules()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $rules = $this->getGlobalRules();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* We don't require IDs on bulk storing. */
 | 
					 | 
				
			||||||
        if ($this->action !== self::$STORE_METHOD) {
 | 
					 | 
				
			||||||
            $rules['ids'] = ['required'];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $rules;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								app/Http/Requests/Project/CreateProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Http/Requests/Project/CreateProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/Http/Requests/Project/DestroyProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/Http/Requests/Project/DestroyProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DestroyProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								app/Http/Requests/Project/EditProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Http/Requests/Project/EditProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EditProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the validation rules that apply to the request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								app/Http/Requests/Project/ShowProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Http/Requests/Project/ShowProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShowProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the validation rules that apply to the request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								app/Http/Requests/Project/StoreProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/Http/Requests/Project/StoreProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StoreProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->can('create', Project::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $rules = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $rules['name'] ='required|unique:projects,name,null,null,company_id,'.auth()->user()->companyId();
 | 
				
			||||||
 | 
					            $rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $rules;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function prepareForValidation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
 | 
				
			||||||
 | 
					            $input['client_id'] = $this->decodePrimaryKey($input['client_id']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $this->replace($input);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								app/Http/Requests/Project/UpdateProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Http/Requests/Project/UpdateProjectRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Utils\Traits\ChecksEntityStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UpdateProjectRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use ChecksEntityStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->can('edit', $this->project);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function prepareForValidation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->replace($input);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -54,7 +54,7 @@ class UpdateRecurringInvoiceRequest extends Request
 | 
				
			|||||||
    protected function prepareForValidation()
 | 
					    protected function prepareForValidation()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
        info($input);
 | 
					
 | 
				
			||||||
        if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
 | 
					        if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
 | 
				
			||||||
            $input['design_id'] = $this->decodePrimaryKey($input['design_id']);
 | 
					            $input['design_id'] = $this->decodePrimaryKey($input['design_id']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -91,16 +91,27 @@ class UpdateRecurringInvoiceRequest extends Request
 | 
				
			|||||||
        $this->replace($input);
 | 
					        $this->replace($input);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function setAutoBillFlag($auto_bill)
 | 
					    /**
 | 
				
			||||||
 | 
					     * if($auto_bill == '')
 | 
				
			||||||
 | 
					     * off / optin / optout will reset the status of this field to off to allow 
 | 
				
			||||||
 | 
					     * the client to choose whether to auto_bill or not.
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param enum $auto_bill off/always/optin/optout
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function setAutoBillFlag($auto_bill) :bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($auto_bill == 'always')
 | 
					        if($auto_bill == 'always')
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($auto_bill == 'off')
 | 
					        // if($auto_bill == '')
 | 
				
			||||||
 | 
					        // off / optin / optout will reset the status of this field to off to allow 
 | 
				
			||||||
 | 
					        // the client to choose whether to auto_bill or not.
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //todo do we need to handle optin / optout here?
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,9 @@ class UniqueInvoiceNumberRule implements Rule
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private function checkIfInvoiceNumberUnique() : bool
 | 
					    private function checkIfInvoiceNumberUnique() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        if(empty($this->input['number']))
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice = Invoice::where('client_id', $this->input['client_id'])
 | 
					        $invoice = Invoice::where('client_id', $this->input['client_id'])
 | 
				
			||||||
                        ->where('number', $this->input['number'])
 | 
					                        ->where('number', $this->input['number'])
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,17 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\Account;
 | 
					namespace App\Jobs\Account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\AccountCreated as AnalyticsAccountCreated;
 | 
				
			||||||
use App\Events\Account\AccountCreated;
 | 
					use App\Events\Account\AccountCreated;
 | 
				
			||||||
use App\Jobs\Company\CreateCompany;
 | 
					use App\Jobs\Company\CreateCompany;
 | 
				
			||||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
 | 
					use App\Jobs\Company\CreateCompanyPaymentTerms;
 | 
				
			||||||
@ -19,6 +29,7 @@ use Illuminate\Support\Facades\Log;
 | 
				
			|||||||
use Illuminate\Support\Facades\Notification;
 | 
					use Illuminate\Support\Facades\Notification;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
use Symfony\Component\HttpFoundation\Response;
 | 
					use Symfony\Component\HttpFoundation\Response;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CreateAccount
 | 
					class CreateAccount
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -80,6 +91,10 @@ class CreateAccount
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $sp035a66->notification(new NewAccountCreated($spaa9f78, $sp035a66))->ninja();
 | 
					        $sp035a66->notification(new NewAccountCreated($spaa9f78, $sp035a66))->ninja();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LightLogs::create(new AnalyticsAccountCreated())
 | 
				
			||||||
 | 
					                 ->increment()
 | 
				
			||||||
 | 
					                 ->batch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $sp794f3f;
 | 
					        return $sp794f3f;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\Invoice;
 | 
					namespace App\Jobs\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\EmailInvoiceFailure;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasEmailed;
 | 
					use App\Events\Invoice\InvoiceWasEmailed;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
 | 
					use App\Events\Invoice\InvoiceWasEmailedAndFailed;
 | 
				
			||||||
use App\Helpers\Email\InvoiceEmail;
 | 
					use App\Helpers\Email\InvoiceEmail;
 | 
				
			||||||
@ -30,6 +31,7 @@ use Illuminate\Queue\InteractsWithQueue;
 | 
				
			|||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Illuminate\Support\Facades\Mail;
 | 
					use Illuminate\Support\Facades\Mail;
 | 
				
			||||||
use Symfony\Component\Mime\Test\Constraint\EmailTextBodyContains;
 | 
					use Symfony\Component\Mime\Test\Constraint\EmailTextBodyContains;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*Multi Mailer implemented*/
 | 
					/*Multi Mailer implemented*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -95,4 +97,17 @@ class EmailInvoice extends BaseMailerJob implements ShouldQueue
 | 
				
			|||||||
        /* Mark invoice sent */
 | 
					        /* Mark invoice sent */
 | 
				
			||||||
        $this->invoice_invitation->invoice->service()->markSent()->save();
 | 
					        $this->invoice_invitation->invoice->service()->markSent()->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function failed($exception = null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        info('the job failed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $job_failure = new EmailInvoiceFailure();
 | 
				
			||||||
 | 
					        $job_failure->string_metric5 = get_class($this);
 | 
				
			||||||
 | 
					        $job_failure->string_metric6 = $exception->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LightLogs::create($job_failure)
 | 
				
			||||||
 | 
					                 ->batch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\RecurringInvoice;
 | 
					namespace App\Jobs\RecurringInvoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\SendRecurringFailure;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasEmailed;
 | 
					use App\Events\Invoice\InvoiceWasEmailed;
 | 
				
			||||||
use App\Factory\RecurringInvoiceToInvoiceFactory;
 | 
					use App\Factory\RecurringInvoiceToInvoiceFactory;
 | 
				
			||||||
use App\Helpers\Email\InvoiceEmail;
 | 
					use App\Helpers\Email\InvoiceEmail;
 | 
				
			||||||
@ -26,6 +27,7 @@ use Illuminate\Http\Request;
 | 
				
			|||||||
use Illuminate\Queue\InteractsWithQueue;
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SendRecurring implements ShouldQueue
 | 
					class SendRecurring implements ShouldQueue
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -59,6 +61,8 @@ class SendRecurring implements ShouldQueue
 | 
				
			|||||||
        // Generate Standard Invoice
 | 
					        // Generate Standard Invoice
 | 
				
			||||||
        $invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
 | 
					        $invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoice->date = now()->format('Y-m-d');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice = $invoice->service()
 | 
					        $invoice = $invoice->service()
 | 
				
			||||||
                           ->markSent()
 | 
					                           ->markSent()
 | 
				
			||||||
                           ->applyNumber()
 | 
					                           ->applyNumber()
 | 
				
			||||||
@ -71,9 +75,10 @@ class SendRecurring implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            $email_builder = (new InvoiceEmail())->build($invitation);
 | 
					            $email_builder = (new InvoiceEmail())->build($invitation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($invitation->contact && strlen($invitation->contact->email) >=1){
 | 
				
			||||||
                EmailInvoice::dispatch($email_builder, $invitation, $invoice->company);
 | 
					                EmailInvoice::dispatch($email_builder, $invitation, $invoice->company);
 | 
				
			||||||
 | 
					 | 
				
			||||||
                info("Firing email for invoice {$invoice->number}");
 | 
					                info("Firing email for invoice {$invoice->number}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -101,4 +106,18 @@ class SendRecurring implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function failed($exception = null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        info('the job failed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $job_failure = new SendRecurringFailure();
 | 
				
			||||||
 | 
					        $job_failure->string_metric5 = get_class($this);
 | 
				
			||||||
 | 
					        $job_failure->string_metric6 = $exception->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LightLogs::create($job_failure)
 | 
				
			||||||
 | 
					                 ->batch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        info(print_r($exception->getMessage(), 1));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\Util;
 | 
					namespace App\Jobs\Util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\MigrationFailure;
 | 
				
			||||||
use App\DataMapper\CompanySettings;
 | 
					use App\DataMapper\CompanySettings;
 | 
				
			||||||
use App\Exceptions\MigrationValidatorFailed;
 | 
					use App\Exceptions\MigrationValidatorFailed;
 | 
				
			||||||
use App\Exceptions\ResourceDependencyMissing;
 | 
					use App\Exceptions\ResourceDependencyMissing;
 | 
				
			||||||
@ -72,6 +73,7 @@ use Illuminate\Queue\SerializesModels;
 | 
				
			|||||||
use Illuminate\Support\Facades\Mail;
 | 
					use Illuminate\Support\Facades\Mail;
 | 
				
			||||||
use Illuminate\Support\Facades\Validator;
 | 
					use Illuminate\Support\Facades\Validator;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Import implements ShouldQueue
 | 
					class Import implements ShouldQueue
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -966,6 +968,15 @@ class Import implements ShouldQueue
 | 
				
			|||||||
    public function failed($exception = null)
 | 
					    public function failed($exception = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        info('the job failed');
 | 
					        info('the job failed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $job_failure = new MigrationFailure();
 | 
				
			||||||
 | 
					        $job_failure->string_metric5 = get_class($this);
 | 
				
			||||||
 | 
					        $job_failure->string_metric6 = $exception->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LightLogs::create($job_failure)
 | 
				
			||||||
 | 
					                 ->batch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        info(print_r($exception->getMessage(), 1));
 | 
					        info(print_r($exception->getMessage(), 1));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -156,6 +156,11 @@ class Client extends BaseModel implements HasLocalePreference
 | 
				
			|||||||
                    ->first();
 | 
					                    ->first();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function credits()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(Credit::class)->withTrashed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function activities()
 | 
					    public function activities()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->hasMany(Activity::class)->orderBy('id', 'desc');
 | 
					        return $this->hasMany(Activity::class)->orderBy('id', 'desc');
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ class Gateway extends StaticModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @return mixed
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     * @deprecated 5.0.17 No longer needs as we are removing omnipay dependence
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getFields()
 | 
					    public function getFields()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -116,7 +117,7 @@ class Gateway extends StaticModel
 | 
				
			|||||||
                return ['methods' => [GatewayType::CREDIT_CARD], 'refund' => true, 'token_billing' => true  ]; //Checkout
 | 
					                return ['methods' => [GatewayType::CREDIT_CARD], 'refund' => true, 'token_billing' => true  ]; //Checkout
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return [];
 | 
					                return ['methods' => [], 'refund' => false, 'token_billing' => false];
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Models;
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Filterable;
 | 
				
			||||||
use Illuminate\Database\Eloquent\SoftDeletes;
 | 
					use Illuminate\Database\Eloquent\SoftDeletes;
 | 
				
			||||||
use Laracasts\Presenter\PresentableTrait;
 | 
					use Laracasts\Presenter\PresentableTrait;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,6 +14,7 @@ class Project extends BaseModel
 | 
				
			|||||||
    // Expense Categories
 | 
					    // Expense Categories
 | 
				
			||||||
    use SoftDeletes;
 | 
					    use SoftDeletes;
 | 
				
			||||||
    use PresentableTrait;
 | 
					    use PresentableTrait;
 | 
				
			||||||
 | 
					    use Filterable;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @var array
 | 
					     * @var array
 | 
				
			||||||
@ -24,17 +26,16 @@ class Project extends BaseModel
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    protected $fillable = [
 | 
					    protected $fillable = [
 | 
				
			||||||
        'name',
 | 
					        'name',
 | 
				
			||||||
 | 
					        'client_id',
 | 
				
			||||||
        'task_rate',
 | 
					        'task_rate',
 | 
				
			||||||
        'private_notes',
 | 
					        'private_notes',
 | 
				
			||||||
 | 
					        'public_notes',
 | 
				
			||||||
        'due_date',
 | 
					        'due_date',
 | 
				
			||||||
        'budgeted_hours',
 | 
					        'budgeted_hours',
 | 
				
			||||||
        'custom_value1',
 | 
					        'custom_value1',
 | 
				
			||||||
        'custom_value2',
 | 
					        'custom_value2',
 | 
				
			||||||
    ];
 | 
					        'custom_value3',
 | 
				
			||||||
 | 
					        'custom_value4',
 | 
				
			||||||
    protected $casts = [
 | 
					 | 
				
			||||||
        'updated_at' => 'timestamp',
 | 
					 | 
				
			||||||
        'created_at' => 'timestamp',
 | 
					 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getEntityType()
 | 
					    public function getEntityType()
 | 
				
			||||||
 | 
				
			|||||||
@ -44,20 +44,8 @@ class RecurringInvoice extends BaseModel
 | 
				
			|||||||
    const STATUS_PENDING = -1;
 | 
					    const STATUS_PENDING = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Recurring intervals //todo MAP WHEN WE MIGRATE.
 | 
					     * Invoice Frequencies.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Make sure we support overflow!!!!!!!!!!
 | 
					 | 
				
			||||||
    $start = Carbon::today();
 | 
					 | 
				
			||||||
    $subscription = Carbon::parse('2017-12-31');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    foreach (range(1, 12) as $month) {
 | 
					 | 
				
			||||||
        $day = $start->addMonthNoOverflow()->thisDayOrLast($subscription->day);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        echo "You will be billed on {$day} in month {$month}\n";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const FREQUENCY_DAILY = 1;
 | 
					    const FREQUENCY_DAILY = 1;
 | 
				
			||||||
    const FREQUENCY_WEEKLY = 2;
 | 
					    const FREQUENCY_WEEKLY = 2;
 | 
				
			||||||
    const FREQUENCY_TWO_WEEKS = 3;
 | 
					    const FREQUENCY_TWO_WEEKS = 3;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										41
									
								
								app/Policies/ProjectPolicy.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Policies/ProjectPolicy.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Policies;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use Illuminate\Auth\Access\HandlesAuthorization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProjectPolicy extends EntityPolicy
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use HandlesAuthorization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new policy instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Checks if the user has create permissions.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  User $user
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function create(User $user) : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->isAdmin() || $user->hasPermission('create_project') || $user->hasPermission('create_all');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -25,6 +25,7 @@ use App\Models\Invoice;
 | 
				
			|||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Models\PaymentTerm;
 | 
					use App\Models\PaymentTerm;
 | 
				
			||||||
use App\Models\Product;
 | 
					use App\Models\Product;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Models\RecurringQuote;
 | 
					use App\Models\RecurringQuote;
 | 
				
			||||||
@ -46,6 +47,7 @@ use App\Policies\InvoicePolicy;
 | 
				
			|||||||
use App\Policies\PaymentPolicy;
 | 
					use App\Policies\PaymentPolicy;
 | 
				
			||||||
use App\Policies\PaymentTermPolicy;
 | 
					use App\Policies\PaymentTermPolicy;
 | 
				
			||||||
use App\Policies\ProductPolicy;
 | 
					use App\Policies\ProductPolicy;
 | 
				
			||||||
 | 
					use App\Policies\ProjectPolicy;
 | 
				
			||||||
use App\Policies\QuotePolicy;
 | 
					use App\Policies\QuotePolicy;
 | 
				
			||||||
use App\Policies\RecurringInvoicePolicy;
 | 
					use App\Policies\RecurringInvoicePolicy;
 | 
				
			||||||
use App\Policies\RecurringQuotePolicy;
 | 
					use App\Policies\RecurringQuotePolicy;
 | 
				
			||||||
@ -79,6 +81,7 @@ class AuthServiceProvider extends ServiceProvider
 | 
				
			|||||||
        Payment::class => PaymentPolicy::class,
 | 
					        Payment::class => PaymentPolicy::class,
 | 
				
			||||||
        PaymentTerm::class => PaymentTermPolicy::class,
 | 
					        PaymentTerm::class => PaymentTermPolicy::class,
 | 
				
			||||||
        Product::class => ProductPolicy::class,
 | 
					        Product::class => ProductPolicy::class,
 | 
				
			||||||
 | 
					        Project::class => ProjectPolicy::class,
 | 
				
			||||||
        Quote::class => QuotePolicy::class,
 | 
					        Quote::class => QuotePolicy::class,
 | 
				
			||||||
        RecurringInvoice::class => RecurringInvoicePolicy::class,
 | 
					        RecurringInvoice::class => RecurringInvoicePolicy::class,
 | 
				
			||||||
        RecurringQuote::class => RecurringQuotePolicy::class,
 | 
					        RecurringQuote::class => RecurringQuotePolicy::class,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								app/Repositories/ProjectRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Repositories/ProjectRepository.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Repositories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class for project repository.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ProjectRepository extends BaseRepository
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the class name.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return     string The class name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getClassName()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return Project::class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -44,11 +44,11 @@ class ApplyNumber extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        switch ($this->client->getSetting('counter_number_applied')) {
 | 
					        switch ($this->client->getSetting('counter_number_applied')) {
 | 
				
			||||||
            case 'when_saved':
 | 
					            case 'when_saved':
 | 
				
			||||||
                $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					                $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'when_sent':
 | 
					            case 'when_sent':
 | 
				
			||||||
                if ($this->invoice->status_id == Invoice::STATUS_SENT) {
 | 
					                if ($this->invoice->status_id == Invoice::STATUS_SENT) {
 | 
				
			||||||
                    $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					                    $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,8 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private $client;
 | 
					    private $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private $payment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(Invoice $invoice)
 | 
					    public function __construct(Invoice $invoice)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->invoice = $invoice;
 | 
					        $this->invoice = $invoice;
 | 
				
			||||||
@ -39,32 +41,37 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function run()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (! $this->invoice->isPayable()) {
 | 
					        /* Is the invoice payable? */
 | 
				
			||||||
 | 
					        if (! $this->invoice->isPayable()) 
 | 
				
			||||||
            return $this->invoice;
 | 
					            return $this->invoice;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /* Mark the invoice as sent */
 | 
				
			||||||
        $this->invoice = $this->invoice->service()->markSent()->save();
 | 
					        $this->invoice = $this->invoice->service()->markSent()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->invoice->balance > 0) {
 | 
					        /* Mark the invoice as paid if there is no balance */
 | 
				
			||||||
            $gateway_token = $this->getGateway($this->invoice->balance); //todo what if it is only a partial amount?
 | 
					        if ((int)$this->invoice->balance == 0) 
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return $this->invoice->service()->markPaid()->save();
 | 
					            return $this->invoice->service()->markPaid()->save();
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $gateway_token || ! $gateway_token->gateway->driver($this->client)->token_billing) {
 | 
					        $this->applyCreditPayment();
 | 
				
			||||||
            return $this->invoice;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->invoice->partial > 0) {
 | 
					        /* Determine $amount */
 | 
				
			||||||
            $fee = $gateway_token->gateway->calcGatewayFee($this->invoice->partial);
 | 
					        if ($this->invoice->partial > 0) 
 | 
				
			||||||
            // $amount = $this->invoice->partial + $fee;
 | 
					 | 
				
			||||||
            $amount = $this->invoice->partial;
 | 
					            $amount = $this->invoice->partial;
 | 
				
			||||||
        } else {
 | 
					        elseif($this->invoice->balance >0)
 | 
				
			||||||
            $fee = $gateway_token->gateway->calcGatewayFee($this->invoice->balance);
 | 
					 | 
				
			||||||
            // $amount = $this->invoice->balance + $fee;
 | 
					 | 
				
			||||||
            $amount = $this->invoice->balance;
 | 
					            $amount = $this->invoice->balance;
 | 
				
			||||||
        }
 | 
					        else
 | 
				
			||||||
 | 
					            return $this->invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $gateway_token = $this->getGateway($amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Bail out if no payment methods available */
 | 
				
			||||||
 | 
					        if (! $gateway_token || ! $gateway_token->gateway->driver($this->client)->token_billing) 
 | 
				
			||||||
 | 
					            return $this->invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* $gateway fee */
 | 
				
			||||||
 | 
					        $fee = $gateway_token->gateway->calcGatewayFee($this->invoice->partial);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Build payment hash */
 | 
				
			||||||
        $payment_hash = PaymentHash::create([
 | 
					        $payment_hash = PaymentHash::create([
 | 
				
			||||||
            'hash' => Str::random(128),
 | 
					            'hash' => Str::random(128),
 | 
				
			||||||
            'data' => ['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount],
 | 
					            'data' => ['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount],
 | 
				
			||||||
@ -72,11 +79,103 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
            'fee_invoice_id' => $this->invoice->id,
 | 
					            'fee_invoice_id' => $this->invoice->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payment = $gateway_token->gateway->driver($this->client)->tokenBilling($gateway_token, $payment_hash);
 | 
					        $payment = $gateway_token->gateway
 | 
				
			||||||
 | 
					                                 ->driver($this->client)
 | 
				
			||||||
 | 
					                                 ->tokenBilling($gateway_token, $payment_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->invoice;
 | 
					        return $this->invoice;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Applies credits to a payment prior to push
 | 
				
			||||||
 | 
					     * to the payment gateway
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return $this
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function applyCreditPayment() 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $available_credits = $this->client
 | 
				
			||||||
 | 
					                                  ->credits
 | 
				
			||||||
 | 
					                                  ->where('is_deleted', false)
 | 
				
			||||||
 | 
					                                  ->where('balance', '>', 0)
 | 
				
			||||||
 | 
					                                  ->sortBy('created_at');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $available_credit_balance = $available_credits->sum('balance');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if((int)$available_credit_balance == 0)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $is_partial_amount = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->invoice->partial > 0) {
 | 
				
			||||||
 | 
					            $is_partial_amount = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->payment = PaymentFactory::create($this->client->company_id, $this->client->user_id);
 | 
				
			||||||
 | 
					        $this->payment->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $available_credits->each(function($credit) use($is_partial_amount){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //todo need to iterate until the partial or balance is completely consumed 
 | 
				
			||||||
 | 
					            //by the credit, any remaining balance is then dealt with by
 | 
				
			||||||
 | 
					            //the gateway
 | 
				
			||||||
 | 
					            //each time a credit is applied SAVE the invoice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // if($credit->balance >= $amount){
 | 
				
			||||||
 | 
					            //     //current credit covers the total amount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // }
 | 
				
			||||||
 | 
					                //return false to exit each loop
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function buildPayment($credit, $is_partial_amount)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if($is_partial_amount) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($this->invoice->partial >= $credit->balance) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $amount = $this->invoice->partial - $credit->balance;
 | 
				
			||||||
 | 
					                $this->invoice->partial -= $amount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->payment->credits()->attach([
 | 
				
			||||||
 | 
					                    $credit->id => ['amount' => $amount]
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->payment->invoice()->attach([
 | 
				
			||||||
 | 
					                    $this->invoice->id => ['amount' => $amount]
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->applyPaymentToCredit($credit, $amount);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function applyPaymentToCredit($credit, $amount)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $credit_item = new InvoiceItem;
 | 
				
			||||||
 | 
					        $credit_item->type_id = '1';
 | 
				
			||||||
 | 
					        $credit_item->product_key = ctrans('texts.credit');
 | 
				
			||||||
 | 
					        $credit_item->notes = ctrans('texts.credit_payment', ['invoice_number' => $this->invoice->number]);
 | 
				
			||||||
 | 
					        $credit_item->quantity = 1;
 | 
				
			||||||
 | 
					        $credit_item->cost = $amount * -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $credit_items = $credit->line_items;
 | 
				
			||||||
 | 
					        $credit_items[] = $credit_item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $credit->line_items = $credit_items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $credit = $credit->calc()->getCredit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Harvests a client gateway token which passes the
 | 
					     * Harvests a client gateway token which passes the
 | 
				
			||||||
     * necessary filters for an $amount.
 | 
					     * necessary filters for an $amount.
 | 
				
			||||||
 | 
				
			|||||||
@ -49,7 +49,10 @@ class RecurringService
 | 
				
			|||||||
    public function start()
 | 
					    public function start()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    	//make sure next_send_date is either now or in the future else return.
 | 
					    	//make sure next_send_date is either now or in the future else return.
 | 
				
			||||||
    	if(Carbon::parse($this->recurring_entity->next_send_date)->lt(now()))
 | 
					    	// if(Carbon::parse($this->recurring_entity->next_send_date)->lt(now()))
 | 
				
			||||||
 | 
					    	// 	return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($this->recurring_entity->remaining_cycles == 0)
 | 
				
			||||||
            return $this;
 | 
					            return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    	$this->recurring_entity->status_id = RecurringInvoice::STATUS_ACTIVE;
 | 
					    	$this->recurring_entity->status_id = RecurringInvoice::STATUS_ACTIVE;
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ class GatewayTransformer extends EntityTransformer
 | 
				
			|||||||
            'fields' => (string) $gateway->fields ?: '',
 | 
					            'fields' => (string) $gateway->fields ?: '',
 | 
				
			||||||
            'updated_at' => (int) $gateway->updated_at,
 | 
					            'updated_at' => (int) $gateway->updated_at,
 | 
				
			||||||
            'created_at' => (int) $gateway->created_at,
 | 
					            'created_at' => (int) $gateway->created_at,
 | 
				
			||||||
 | 
					            'options' => $gateway->getMethods(),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -34,20 +34,23 @@ class ProjectTransformer extends EntityTransformer
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'id' => (string) $this->encodePrimaryKey($project->id),
 | 
					            'id' => (string) $this->encodePrimaryKey($project->id),
 | 
				
			||||||
            'name' => $project->name ?: '',
 | 
					            'user_id' => (string) $this->encodePrimaryKey($project->user_id),
 | 
				
			||||||
 | 
					            'assigned_user_id' => (string) $this->encodePrimaryKey($project->assigned_user_id),
 | 
				
			||||||
            'client_id' => (string) $this->encodePrimaryKey($project->client_id),
 | 
					            'client_id' => (string) $this->encodePrimaryKey($project->client_id),
 | 
				
			||||||
 | 
					            'name' => $project->name ?: '',
 | 
				
			||||||
            'created_at' => (int) $project->created_at,
 | 
					            'created_at' => (int) $project->created_at,
 | 
				
			||||||
            'updated_at' => (int) $project->updated_at,
 | 
					            'updated_at' => (int) $project->updated_at,
 | 
				
			||||||
            'archived_at' => (int) $project->deleted_at,
 | 
					            'archived_at' => (int) $project->deleted_at,
 | 
				
			||||||
            'is_deleted' => (bool) $project->is_deleted,
 | 
					            'is_deleted' => (bool) $project->is_deleted,
 | 
				
			||||||
            'task_rate' => (float) $project->task_rate,
 | 
					            'task_rate' => (float) $project->task_rate,
 | 
				
			||||||
            'due_date' => $project->due_date ?: '',
 | 
					            'due_date' => $project->due_date ?: '',
 | 
				
			||||||
            'private_notes' => $project->private_notes ?: '',
 | 
					            'private_notes' => (string) $project->private_notes ?: '',
 | 
				
			||||||
 | 
					            'public_notes' => (string) $project->public_notes ?: '',
 | 
				
			||||||
            'budgeted_hours' => (float) $project->budgeted_hours,
 | 
					            'budgeted_hours' => (float) $project->budgeted_hours,
 | 
				
			||||||
            'custom_value1' => $project->custom_value1 ?: '',
 | 
					            'custom_value1' => (string) $project->custom_value1 ?: '',
 | 
				
			||||||
            'custom_value2' => $project->custom_value2 ?: '',
 | 
					            'custom_value2' => (string) $project->custom_value2 ?: '',
 | 
				
			||||||
            'custom_value3' => $project->custom_value3 ?: '',
 | 
					            'custom_value3' => (string) $project->custom_value3 ?: '',
 | 
				
			||||||
            'custom_value4' => $project->custom_value4 ?: '',
 | 
					            'custom_value4' => (string) $project->custom_value4 ?: '',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@ trait GeneratesCounter
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return     string              The next invoice number.
 | 
					     * @return     string              The next invoice number.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getNextInvoiceNumber(Client $client) :string
 | 
					    public function getNextInvoiceNumber(Client $client, ?Invoice $invoice) :string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //Reset counters if enabled
 | 
					        //Reset counters if enabled
 | 
				
			||||||
        $this->resetCounters($client);
 | 
					        $this->resetCounters($client);
 | 
				
			||||||
@ -64,8 +64,12 @@ trait GeneratesCounter
 | 
				
			|||||||
        //Return a valid counter
 | 
					        //Return a valid counter
 | 
				
			||||||
        $pattern = $client->getSetting('invoice_number_pattern');
 | 
					        $pattern = $client->getSetting('invoice_number_pattern');
 | 
				
			||||||
        $padding = $client->getSetting('counter_padding');
 | 
					        $padding = $client->getSetting('counter_padding');
 | 
				
			||||||
 | 
					        $prefix = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $pattern);
 | 
					        if($invoice && $invoice->recurring_id)
 | 
				
			||||||
 | 
					            $prefix = $client->getSetting('recurring_number_prefix');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $pattern, $prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->incrementCounter($counter_entity, 'invoice_number_counter');
 | 
					        $this->incrementCounter($counter_entity, 'invoice_number_counter');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -140,6 +144,9 @@ trait GeneratesCounter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $quote_number = $this->checkEntityNumber(Quote::class, $client, $counter, $padding, $pattern);
 | 
					        $quote_number = $this->checkEntityNumber(Quote::class, $client, $counter, $padding, $pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // if($this->recurring_id)
 | 
				
			||||||
 | 
					        //     $quote_number = $this->prefixCounter($quote_number, $client->getSetting('recurring_number_prefix'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->incrementCounter($counter_entity, $used_counter);
 | 
					        $this->incrementCounter($counter_entity, $used_counter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $quote_number;
 | 
					        return $quote_number;
 | 
				
			||||||
@ -168,7 +175,7 @@ trait GeneratesCounter
 | 
				
			|||||||
        $pattern = '';
 | 
					        $pattern = '';
 | 
				
			||||||
        $padding = $client->getSetting('counter_padding');
 | 
					        $padding = $client->getSetting('counter_padding');
 | 
				
			||||||
        $invoice_number = $this->checkEntityNumber(RecurringInvoice::class, $client, $counter, $padding, $pattern);
 | 
					        $invoice_number = $this->checkEntityNumber(RecurringInvoice::class, $client, $counter, $padding, $pattern);
 | 
				
			||||||
        $invoice_number = $this->prefixCounter($invoice_number, $client->getSetting('recurring_number_prefix'));
 | 
					        //$invoice_number = $this->prefixCounter($invoice_number, $client->getSetting('recurring_number_prefix'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //increment the correct invoice_number Counter (company vs client)
 | 
					        //increment the correct invoice_number Counter (company vs client)
 | 
				
			||||||
        if ($is_client_counter) {
 | 
					        if ($is_client_counter) {
 | 
				
			||||||
@ -283,7 +290,7 @@ trait GeneratesCounter
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return     string   The padded and prefixed entity number
 | 
					     * @return     string   The padded and prefixed entity number
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private function checkEntityNumber($class, $entity, $counter, $padding, $pattern)
 | 
					    private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = '')
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $check = false;
 | 
					        $check = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -292,6 +299,8 @@ trait GeneratesCounter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            $number = $this->applyNumberPattern($entity, $number, $pattern);
 | 
					            $number = $this->applyNumberPattern($entity, $number, $pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $number = $this->prefixCounter($number, $prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ($class == Invoice::class || $class == RecurringInvoice::class) 
 | 
					            if ($class == Invoice::class || $class == RecurringInvoice::class) 
 | 
				
			||||||
                $check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first();
 | 
					                $check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first();
 | 
				
			||||||
            elseif ($class == Client::class || $class == Vendor::class) 
 | 
					            elseif ($class == Client::class || $class == Vendor::class) 
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										38
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@ -108,16 +108,16 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "aws/aws-sdk-php",
 | 
					            "name": "aws/aws-sdk-php",
 | 
				
			||||||
            "version": "3.158.2",
 | 
					            "version": "3.158.4",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/aws/aws-sdk-php.git",
 | 
					                "url": "https://github.com/aws/aws-sdk-php.git",
 | 
				
			||||||
                "reference": "b80957465d94c127254e36061dd3d0c3ccc94cc1"
 | 
					                "reference": "c0c0df79edc0a646a7ccd6b2e8d1723ff4ba88e2"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/b80957465d94c127254e36061dd3d0c3ccc94cc1",
 | 
					                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c0c0df79edc0a646a7ccd6b2e8d1723ff4ba88e2",
 | 
				
			||||||
                "reference": "b80957465d94c127254e36061dd3d0c3ccc94cc1",
 | 
					                "reference": "c0c0df79edc0a646a7ccd6b2e8d1723ff4ba88e2",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@ -189,7 +189,7 @@
 | 
				
			|||||||
                "s3",
 | 
					                "s3",
 | 
				
			||||||
                "sdk"
 | 
					                "sdk"
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2020-10-05T18:13:27+00:00"
 | 
					            "time": "2020-10-07T18:12:22+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "brick/math",
 | 
					            "name": "brick/math",
 | 
				
			||||||
@ -1814,16 +1814,16 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "google/auth",
 | 
					            "name": "google/auth",
 | 
				
			||||||
            "version": "v1.14.0",
 | 
					            "version": "v1.14.1",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/googleapis/google-auth-library-php.git",
 | 
					                "url": "https://github.com/googleapis/google-auth-library-php.git",
 | 
				
			||||||
                "reference": "95c23ebd89a0a4d1b511aed81426f57388ab7268"
 | 
					                "reference": "2df57c61c2fd739a15a81f792b1ccedc3e06d2b6"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/95c23ebd89a0a4d1b511aed81426f57388ab7268",
 | 
					                "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/2df57c61c2fd739a15a81f792b1ccedc3e06d2b6",
 | 
				
			||||||
                "reference": "95c23ebd89a0a4d1b511aed81426f57388ab7268",
 | 
					                "reference": "2df57c61c2fd739a15a81f792b1ccedc3e06d2b6",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@ -1862,7 +1862,7 @@
 | 
				
			|||||||
                "google",
 | 
					                "google",
 | 
				
			||||||
                "oauth2"
 | 
					                "oauth2"
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2020-10-02T22:20:36+00:00"
 | 
					            "time": "2020-10-06T18:10:43+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "graham-campbell/result-type",
 | 
					            "name": "graham-campbell/result-type",
 | 
				
			||||||
@ -2497,16 +2497,16 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "laravel/framework",
 | 
					            "name": "laravel/framework",
 | 
				
			||||||
            "version": "v8.8.0",
 | 
					            "version": "v8.9.0",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/laravel/framework.git",
 | 
					                "url": "https://github.com/laravel/framework.git",
 | 
				
			||||||
                "reference": "0bdd5c6f12cb7cb6644e484169656245af417735"
 | 
					                "reference": "8a6bf870bcfa1597e514a9c7ee6df44db98abb54"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/laravel/framework/zipball/0bdd5c6f12cb7cb6644e484169656245af417735",
 | 
					                "url": "https://api.github.com/repos/laravel/framework/zipball/8a6bf870bcfa1597e514a9c7ee6df44db98abb54",
 | 
				
			||||||
                "reference": "0bdd5c6f12cb7cb6644e484169656245af417735",
 | 
					                "reference": "8a6bf870bcfa1597e514a9c7ee6df44db98abb54",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@ -2656,7 +2656,7 @@
 | 
				
			|||||||
                "framework",
 | 
					                "framework",
 | 
				
			||||||
                "laravel"
 | 
					                "laravel"
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2020-10-02T14:33:08+00:00"
 | 
					            "time": "2020-10-06T14:22:36+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "laravel/slack-notification-channel",
 | 
					            "name": "laravel/slack-notification-channel",
 | 
				
			||||||
@ -6504,12 +6504,12 @@
 | 
				
			|||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/symfony/console.git",
 | 
					                "url": "https://github.com/symfony/console.git",
 | 
				
			||||||
                "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00"
 | 
					                "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/symfony/console/zipball/04c3a31fe8ea94b42c9e2d1acc93d19782133b00",
 | 
					                "url": "https://api.github.com/repos/symfony/console/zipball/ae789a8a2ad189ce7e8216942cdb9b77319f5eb8",
 | 
				
			||||||
                "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00",
 | 
					                "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@ -6589,7 +6589,7 @@
 | 
				
			|||||||
                    "type": "tidelift"
 | 
					                    "type": "tidelift"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2020-09-18T14:27:32+00:00"
 | 
					            "time": "2020-10-07T15:23:00+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "symfony/css-selector",
 | 
					            "name": "symfony/css-selector",
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ class CompanyFactory extends Factory
 | 
				
			|||||||
            'db' => config('database.default'),
 | 
					            'db' => config('database.default'),
 | 
				
			||||||
            'settings' => CompanySettings::defaults(),
 | 
					            'settings' => CompanySettings::defaults(),
 | 
				
			||||||
            'is_large' => false,
 | 
					            'is_large' => false,
 | 
				
			||||||
 | 
					            'enabled_modules' => config('ninja.enabled_modules'),
 | 
				
			||||||
            'custom_fields' => (object) [
 | 
					            'custom_fields' => (object) [
 | 
				
			||||||
                //'invoice1' => 'Custom Date|date',
 | 
					                //'invoice1' => 'Custom Date|date',
 | 
				
			||||||
                // 'invoice2' => '2|switch',
 | 
					                // 'invoice2' => '2|switch',
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,7 @@ class UpdateGatewayTableVisibleColumn extends Migration
 | 
				
			|||||||
            $t->text('public_notes')->nullable();
 | 
					            $t->text('public_notes')->nullable();
 | 
				
			||||||
            $t->dropColumn('description');
 | 
					            $t->dropColumn('description');
 | 
				
			||||||
            $t->decimal('budgeted_hours', 12,2)->change();
 | 
					            $t->decimal('budgeted_hours', 12,2)->change();
 | 
				
			||||||
 | 
					            $t->boolean('is_deleted')->default(0);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -214,7 +214,7 @@ class RandomDataSeeder extends Seeder
 | 
				
			|||||||
            $invoice->ledger()->updateInvoiceBalance($invoice->balance);
 | 
					            $invoice->ledger()->updateInvoiceBalance($invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (rand(0, 1)) {
 | 
					            if (rand(0, 1)) {
 | 
				
			||||||
                $payment = App\Models\Payment::create([
 | 
					                $payment = Payment::create([
 | 
				
			||||||
                    'date' => now(),
 | 
					                    'date' => now(),
 | 
				
			||||||
                    'user_id' => $user->id,
 | 
					                    'user_id' => $user->id,
 | 
				
			||||||
                    'company_id' => $company->id,
 | 
					                    'company_id' => $company->id,
 | 
				
			||||||
 | 
				
			|||||||
@ -3281,4 +3281,7 @@ return [
 | 
				
			|||||||
    'paused' => 'Paused',
 | 
					    'paused' => 'Paused',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'saved_at' => 'Saved at :time',
 | 
					    'saved_at' => 'Saved at :time',
 | 
				
			||||||
 | 
					    'credit_payment' => 'Credit applied to Invoice :invoice_number',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,11 @@ if(!isset($design)) $design = 'light';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<style>
 | 
					<style>
 | 
				
			||||||
  :root {
 | 
					  :root {
 | 
				
			||||||
 | 
					    @if($settings)
 | 
				
			||||||
    --primary-color: {{ $settings->primary_color }};
 | 
					    --primary-color: {{ $settings->primary_color }};
 | 
				
			||||||
 | 
					    @else
 | 
				
			||||||
 | 
					    --primary-color: #4caf50;
 | 
				
			||||||
 | 
					    @endif
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .border-primary {
 | 
					  .border-primary {
 | 
				
			||||||
 | 
				
			|||||||
@ -69,6 +69,9 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
 | 
					    Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Route::resource('projects', 'ProjectController'); // name = (projects. index / create / show / update / destroy / edit
 | 
				
			||||||
 | 
					    Route::post('projects/bulk', 'ProjectController@bulk')->name('projects.bulk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit
 | 
					    Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
 | 
					    Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
 | 
				
			||||||
@ -157,13 +160,6 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
 | 
				
			|||||||
    Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
 | 
					    Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Route::get('settings', 'SettingsController@index')->name('user.settings');
 | 
					    Route::get('settings', 'SettingsController@index')->name('user.settings');
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    Route::get('scheduler', 'SchedulerController@index');
 | 
					    Route::get('scheduler', 'SchedulerController@index');
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,7 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->invoice->date = now();
 | 
					        $this->invoice->date = now();
 | 
				
			||||||
        $this->invoice->due_date = now()->addDays(7);
 | 
					        $this->invoice->due_date = now()->addDays(7);
 | 
				
			||||||
        $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					        $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->client_id = $this->client->id;
 | 
					        $this->invoice->client_id = $this->client->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -90,7 +90,7 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->date = now();
 | 
					        $this->invoice->date = now();
 | 
				
			||||||
        $this->invoice->due_date = now()->addDays(7);
 | 
					        $this->invoice->due_date = now()->addDays(7);
 | 
				
			||||||
        $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					        $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->client_id = $this->client->id;
 | 
					        $this->invoice->client_id = $this->client->id;
 | 
				
			||||||
        $this->invoice->setRelation('client', $this->client);
 | 
					        $this->invoice->setRelation('client', $this->client);
 | 
				
			||||||
@ -115,7 +115,7 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->date = now();
 | 
					        $this->invoice->date = now();
 | 
				
			||||||
        $this->invoice->due_date = now()->addDays(7);
 | 
					        $this->invoice->due_date = now()->addDays(7);
 | 
				
			||||||
        $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					        $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->client_id = $this->client->id;
 | 
					        $this->invoice->client_id = $this->client->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -145,7 +145,7 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->date = now();
 | 
					        $this->invoice->date = now();
 | 
				
			||||||
        $this->invoice->due_date = now()->addDays(7);
 | 
					        $this->invoice->due_date = now()->addDays(7);
 | 
				
			||||||
        $this->invoice->number = $this->getNextInvoiceNumber($this->client);
 | 
					        $this->invoice->number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->client_id = $this->client->id;
 | 
					        $this->invoice->client_id = $this->client->id;
 | 
				
			||||||
        $this->invoice->setRelation('client', $this->client);
 | 
					        $this->invoice->setRelation('client', $this->client);
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,10 @@ class ProductTest extends TestCase
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
            ->assertStatus(200);
 | 
					            ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $product = Product::all()->first();
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					        $product = Product::find($this->decodePrimaryKey($arr['data']['id']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $product_update = [
 | 
					        $product_update = [
 | 
				
			||||||
            'notes' => 'CHANGE',
 | 
					            'notes' => 'CHANGE',
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										155
									
								
								tests/Feature/ProjectApiTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								tests/Feature/ProjectApiTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					namespace Tests\Feature;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\DataMapper\DefaultSettings;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\ProjectContact;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Faker\Factory;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Testing\RefreshDatabase;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Testing\WithFaker;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Log;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Session;
 | 
				
			||||||
 | 
					use Tests\MockAccountData;
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @test
 | 
				
			||||||
 | 
					 * @covers App\Http\Controllers\ProjectController
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ProjectApiTest extends TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					    use DatabaseTransactions;
 | 
				
			||||||
 | 
					    use MockAccountData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function setUp() :void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::setUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->makeTestData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Session::start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->faker = \Faker\Factory::create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Model::reguard();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectGet()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->get('/api/v1/projects/'.$this->encodePrimaryKey($this->project->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectPost()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'name' => $this->faker->firstName,
 | 
				
			||||||
 | 
					            'client_id' => $this->client->hashed_id,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->post('/api/v1/projects', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectPut()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'name' => $this->faker->firstName,
 | 
				
			||||||
 | 
					            'public_notes' => 'Coolio',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->put('/api/v1/projects/'.$this->encodePrimaryKey($this->project->id), $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectNotArchived()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->get('/api/v1/projects/'.$this->encodePrimaryKey($this->project->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals(0, $arr['data']['archived_at']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectArchived()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'ids' => [$this->encodePrimaryKey($this->project->id)],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->post('/api/v1/projects/bulk?action=archive', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertNotNull($arr['data'][0]['archived_at']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectRestored()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'ids' => [$this->encodePrimaryKey($this->project->id)],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->post('/api/v1/projects/bulk?action=restore', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals(0, $arr['data'][0]['archived_at']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testProjectDeleted()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'ids' => [$this->encodePrimaryKey($this->project->id)],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->post('/api/v1/projects/bulk?action=delete', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertTrue($arr['data'][0]['is_deleted']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -35,6 +35,7 @@ use App\Models\Expense;
 | 
				
			|||||||
use App\Models\GroupSetting;
 | 
					use App\Models\GroupSetting;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\InvoiceInvitation;
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Models\QuoteInvitation;
 | 
					use App\Models\QuoteInvitation;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
@ -200,7 +201,10 @@ trait MockAccountData
 | 
				
			|||||||
                'send_email' => true,
 | 
					                'send_email' => true,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->project = Project::factory()->create([
 | 
				
			||||||
 | 
					                'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					                'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->expense = Expense::factory()->create([
 | 
					        $this->expense = Expense::factory()->create([
 | 
				
			||||||
            'user_id' => $this->user->id,
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
@ -356,7 +360,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now();
 | 
					        $recurring_invoice->next_send_date = Carbon::now();
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
					        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
				
			||||||
@ -366,7 +370,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now();
 | 
					        $recurring_invoice->next_send_date = Carbon::now();
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
					        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
				
			||||||
@ -376,7 +380,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now();
 | 
					        $recurring_invoice->next_send_date = Carbon::now();
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
					        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
				
			||||||
@ -386,7 +390,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now();
 | 
					        $recurring_invoice->next_send_date = Carbon::now();
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
					        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
				
			||||||
@ -396,7 +400,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now();
 | 
					        $recurring_invoice->next_send_date = Carbon::now();
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
					        $recurring_invoice = InvoiceToRecurringInvoiceFactory::create($this->invoice);
 | 
				
			||||||
@ -406,7 +410,7 @@ trait MockAccountData
 | 
				
			|||||||
        $recurring_invoice->next_send_date = Carbon::now()->addDays(10);
 | 
					        $recurring_invoice->next_send_date = Carbon::now()->addDays(10);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client);
 | 
					        $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client, $this->invoice);
 | 
				
			||||||
        $recurring_invoice->save();
 | 
					        $recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $gs = new GroupSetting;
 | 
					        $gs = new GroupSetting;
 | 
				
			||||||
 | 
				
			|||||||
@ -79,11 +79,11 @@ class GeneratesCounterTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testInvoiceNumberValue()
 | 
					    public function testInvoiceNumberValue()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($invoice_number, '0008');
 | 
					        $this->assertEquals($invoice_number, '0008');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($invoice_number, '0009');
 | 
					        $this->assertEquals($invoice_number, '0009');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -112,8 +112,8 @@ class GeneratesCounterTest extends TestCase
 | 
				
			|||||||
        $this->client->save();
 | 
					        $this->client->save();
 | 
				
			||||||
        $this->client->fresh();
 | 
					        $this->client->fresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
        $invoice_number2 = $this->getNextInvoiceNumber($this->client);
 | 
					        $invoice_number2 = $this->getNextInvoiceNumber($this->client, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($invoice_number, date('Y').'-0001');
 | 
					        $this->assertEquals($invoice_number, date('Y').'-0001');
 | 
				
			||||||
        $this->assertEquals($invoice_number2, date('Y').'-0002');
 | 
					        $this->assertEquals($invoice_number2, date('Y').'-0002');
 | 
				
			||||||
@ -203,7 +203,7 @@ class GeneratesCounterTest extends TestCase
 | 
				
			|||||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
					        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
				
			||||||
        $cliz->settings = ClientSettings::defaults();
 | 
					        $cliz->settings = ClientSettings::defaults();
 | 
				
			||||||
        $cliz->save();
 | 
					        $cliz->save();
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($cliz, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($cliz->getSetting('counter_padding'), 5);
 | 
					        $this->assertEquals($cliz->getSetting('counter_padding'), 5);
 | 
				
			||||||
        $this->assertEquals($invoice_number, '00007');
 | 
					        $this->assertEquals($invoice_number, '00007');
 | 
				
			||||||
@ -218,7 +218,7 @@ class GeneratesCounterTest extends TestCase
 | 
				
			|||||||
        $cliz->settings = ClientSettings::defaults();
 | 
					        $cliz->settings = ClientSettings::defaults();
 | 
				
			||||||
        $cliz->save();
 | 
					        $cliz->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($cliz, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($cliz->getSetting('counter_padding'), 10);
 | 
					        $this->assertEquals($cliz->getSetting('counter_padding'), 10);
 | 
				
			||||||
        $this->assertEquals(strlen($invoice_number), 10);
 | 
					        $this->assertEquals(strlen($invoice_number), 10);
 | 
				
			||||||
@ -235,11 +235,11 @@ class GeneratesCounterTest extends TestCase
 | 
				
			|||||||
        $cliz->settings = ClientSettings::defaults();
 | 
					        $cliz->settings = ClientSettings::defaults();
 | 
				
			||||||
        $cliz->save();
 | 
					        $cliz->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($cliz, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($invoice_number, '0008');
 | 
					        $this->assertEquals($invoice_number, '0008');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
					        $invoice_number = $this->getNextInvoiceNumber($cliz, $this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals($invoice_number, '0009');
 | 
					        $this->assertEquals($invoice_number, '0009');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user