mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 22:07:33 -05:00 
			
		
		
		
	
						commit
						75a578ff23
					
				@ -52,7 +52,10 @@ class StoreInvoiceRequest extends Request
 | 
			
		||||
 | 
			
		||||
        $rules['invitations.*.client_contact_id'] = 'distinct';
 | 
			
		||||
 | 
			
		||||
        $rules['number'] = new UniqueInvoiceNumberRule($this->all());
 | 
			
		||||
        if ($this->input('number')) {
 | 
			
		||||
            $rules['number'] = 'unique:invoices,number,'.$this->id.',id,company_id,'.auth()->user()->company()->id;
 | 
			
		||||
        }
 | 
			
		||||
//        $rules['number'] = new UniqueInvoiceNumberRule($this->all());
 | 
			
		||||
 | 
			
		||||
        $rules['project_id'] =  ['bail', 'sometimes', new ValidProjectForClient($this->all())];
 | 
			
		||||
 | 
			
		||||
@ -66,7 +69,7 @@ class StoreInvoiceRequest extends Request
 | 
			
		||||
        $input = $this->decodePrimaryKeys($input);
 | 
			
		||||
 | 
			
		||||
        $input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
 | 
			
		||||
        //$input['line_items'] = json_encode($input['line_items']);
 | 
			
		||||
 | 
			
		||||
        $this->replace($input);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,10 @@ class StoreTaskRequest extends Request
 | 
			
		||||
    {
 | 
			
		||||
        $rules = [];
 | 
			
		||||
        
 | 
			
		||||
        if ($this->input('number')) {
 | 
			
		||||
            $rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.auth()->user()->company()->id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->globalRules($rules);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -47,6 +51,10 @@ class StoreTaskRequest extends Request
 | 
			
		||||
 | 
			
		||||
        $input = $this->decodePrimaryKeys($this->all()); 
 | 
			
		||||
 | 
			
		||||
        if (array_key_exists('status_id', $input) && is_string($input['status_id'])) {
 | 
			
		||||
            $input['status_id'] = $this->decodePrimaryKey($input['status_id']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->replace($input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Mail\Engine;
 | 
			
		||||
 | 
			
		||||
use App\Utils\HtmlEngine;
 | 
			
		||||
use App\Utils\Number;
 | 
			
		||||
 | 
			
		||||
class QuoteEmailEngine extends BaseEmailEngine 
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ class Expense extends BaseModel
 | 
			
		||||
        'custom_value2',
 | 
			
		||||
        'custom_value3',
 | 
			
		||||
        'custom_value4',
 | 
			
		||||
        'number',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    protected $casts = [
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ class Task extends BaseModel
 | 
			
		||||
        'status_sort_order',
 | 
			
		||||
        'invoice_documents',
 | 
			
		||||
        'rate',
 | 
			
		||||
        'number',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    protected $touches = [];
 | 
			
		||||
@ -97,9 +98,9 @@ class Task extends BaseModel
 | 
			
		||||
        $parts = json_decode($this->time_log) ?: [];
 | 
			
		||||
 | 
			
		||||
        if (count($parts)) {
 | 
			
		||||
            return Carbon::createFromTimeStamp($parts[0][0]);
 | 
			
		||||
            return Carbon::createFromTimeStamp($parts[0][0])->timestamp;
 | 
			
		||||
        } else {
 | 
			
		||||
            return '';
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,16 +45,53 @@ class TaskRepository extends BaseRepository
 | 
			
		||||
     *
 | 
			
		||||
     * @return     task|null  task Object
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public function save(array $data, Task $task) : ?Task
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $task->fill($data);
 | 
			
		||||
        $task->save();
 | 
			
		||||
 | 
			
		||||
        if(!$task->start_time)
 | 
			
		||||
            $task->start_time = $task->calcStartTime();
 | 
			
		||||
        $task->start_time = $task->start_time ?: $task->calcStartTime();
 | 
			
		||||
        $task->number = empty($task->number) ? $this->getNextTaskNumber($task) : $task->number;
 | 
			
		||||
 | 
			
		||||
        if (isset($data['description'])) {
 | 
			
		||||
            $task->description = trim($data['description']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($data['status_sort_order'])) {
 | 
			
		||||
            $task->status_sort_order = $data['status_sort_order'];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($data['time_log'])) {
 | 
			
		||||
            $time_log = json_decode($data['time_log']);
 | 
			
		||||
        } elseif ($task->time_log) {
 | 
			
		||||
            $time_log = json_decode($task->time_log);
 | 
			
		||||
        } else {
 | 
			
		||||
            $time_log = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        array_multisort($time_log);
 | 
			
		||||
 | 
			
		||||
        if (isset($data['action'])) {
 | 
			
		||||
            if ($data['action'] == 'start') {
 | 
			
		||||
                $task->is_running = true;
 | 
			
		||||
                $time_log[] = [strtotime('now'), false];
 | 
			
		||||
            } elseif ($data['action'] == 'resume') {
 | 
			
		||||
                $task->is_running = true;
 | 
			
		||||
                $time_log[] = [strtotime('now'), false];
 | 
			
		||||
            } elseif ($data['action'] == 'stop' && $task->is_running) {
 | 
			
		||||
                $time_log[count($time_log) - 1][1] = time();
 | 
			
		||||
                $task->is_running = false;
 | 
			
		||||
            } elseif ($data['action'] == 'offline'){
 | 
			
		||||
                $task->is_running = $data['is_running'] ? 1 : 0;
 | 
			
		||||
            }
 | 
			
		||||
        } elseif (isset($data['is_running'])) {
 | 
			
		||||
            $task->is_running = $data['is_running'] ? 1 : 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $task->time_log = json_encode($time_log);
 | 
			
		||||
        $task->duration = $task->calcDuration();
 | 
			
		||||
 | 
			
		||||
        $task->save();
 | 
			
		||||
 | 
			
		||||
        if (array_key_exists('documents', $data)) {
 | 
			
		||||
 | 
			
		||||
@ -198,7 +198,8 @@ trait ClientGroupSettingsSaver
 | 
			
		||||
        switch ($key) {
 | 
			
		||||
            case 'int':
 | 
			
		||||
            case 'integer':
 | 
			
		||||
                return ctype_digit(strval(abs($value)));
 | 
			
		||||
                // return ctype_digit(strval(abs($value)));
 | 
			
		||||
                return ctype_digit(strval($value));
 | 
			
		||||
            case 'real':
 | 
			
		||||
            case 'float':
 | 
			
		||||
            case 'double':
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ use App\Models\Payment;
 | 
			
		||||
use App\Models\Project;
 | 
			
		||||
use App\Models\Quote;
 | 
			
		||||
use App\Models\RecurringInvoice;
 | 
			
		||||
use App\Models\Task;
 | 
			
		||||
use App\Models\Timezone;
 | 
			
		||||
use App\Models\Vendor;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
@ -312,6 +313,45 @@ trait GeneratesCounter
 | 
			
		||||
        return $vendor_number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the next task number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param   Task    $task    The task
 | 
			
		||||
     * @return  string           The next task number.
 | 
			
		||||
     */
 | 
			
		||||
    public function getNextTaskNumber(Task $task) :string
 | 
			
		||||
    {
 | 
			
		||||
        $this->resetCompanyCounters($task->company);
 | 
			
		||||
 | 
			
		||||
        $counter = $task->company->settings->task_number_counter;
 | 
			
		||||
        $setting_entity = $task->company->settings->task_number_counter;
 | 
			
		||||
 | 
			
		||||
        $task_number = $this->checkEntityNumber(Task::class, $task, $counter, $task->company->settings->counter_padding, $task->company->settings->task_number_pattern);
 | 
			
		||||
 | 
			
		||||
        $this->incrementCounter($task->company, 'task_number_counter');
 | 
			
		||||
 | 
			
		||||
        return $task_number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the next expense number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param   Expense    $expense    The expense
 | 
			
		||||
     * @return  string                 The next expense number.
 | 
			
		||||
     */
 | 
			
		||||
    public function getNextExpenseNumber(Expense $expense) :string
 | 
			
		||||
    {
 | 
			
		||||
        $this->resetCompanyCounters($expense->company);
 | 
			
		||||
 | 
			
		||||
        $counter = $expense->company->settings->expense_number_counter;
 | 
			
		||||
        $setting_entity = $expense->company->settings->expense_number_counter;
 | 
			
		||||
 | 
			
		||||
        $expense_number = $this->checkEntityNumber(Expense::class, $expense, $counter, $expense->company->settings->counter_padding, $expense->company->settings->expense_number_pattern);
 | 
			
		||||
 | 
			
		||||
        $this->incrementCounter($expense->company, 'expense_number_counter');
 | 
			
		||||
 | 
			
		||||
        return $expense_number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determines if it has shared counter.
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
class ChangeStartTimeColumnType extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function up()
 | 
			
		||||
    {
 | 
			
		||||
        Schema::table('tasks', function (Blueprint $table){
 | 
			
		||||
            $table->unsignedInteger('duration')->nullable()->change();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function down()
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -79,6 +79,18 @@ class TaskApiTest extends TestCase
 | 
			
		||||
        $response->assertStatus(200);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function testTasksGet()
 | 
			
		||||
    {
 | 
			
		||||
        $response = $this->withHeaders([
 | 
			
		||||
                'X-API-SECRET' => config('ninja.api_secret'),
 | 
			
		||||
                'X-API-TOKEN' => $this->token,
 | 
			
		||||
            ])->get('/api/v1/tasks');
 | 
			
		||||
 | 
			
		||||
        $response->assertStatus(200);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function testTaskGet()
 | 
			
		||||
    {
 | 
			
		||||
        $response = $this->withHeaders([
 | 
			
		||||
 | 
			
		||||
@ -106,12 +106,12 @@ class AuthorizeTest extends TestCase
 | 
			
		||||
        $controller = new GetCustomerProfileIdsController($request);
 | 
			
		||||
        $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
 | 
			
		||||
        if (($response != null) && ($response->getMessages()->getResultCode() == 'Ok')) {
 | 
			
		||||
            info("GetCustomerProfileId's SUCCESS: "."\n");
 | 
			
		||||
            info(print_r($response->getIds(), 1));
 | 
			
		||||
            // info("GetCustomerProfileId's SUCCESS: "."\n");
 | 
			
		||||
            // info(print_r($response->getIds(), 1));
 | 
			
		||||
        } else {
 | 
			
		||||
            info("GetCustomerProfileId's ERROR :  Invalid response\n");
 | 
			
		||||
            // info("GetCustomerProfileId's ERROR :  Invalid response\n");
 | 
			
		||||
            $errorMessages = $response->getMessages()->getMessage();
 | 
			
		||||
            info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
            // info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($response);
 | 
			
		||||
@ -179,14 +179,14 @@ class AuthorizeTest extends TestCase
 | 
			
		||||
        if (($response != null) && ($response->getMessages()->getResultCode() == 'Ok')) {
 | 
			
		||||
            info('Succesfully created customer profile : '.$response->getCustomerProfileId()."\n");
 | 
			
		||||
            $paymentProfiles = $response->getCustomerPaymentProfileIdList();
 | 
			
		||||
            info(print_r($paymentProfiles, 1));
 | 
			
		||||
            // info(print_r($paymentProfiles, 1));
 | 
			
		||||
        } else {
 | 
			
		||||
            info("ERROR :  Invalid response\n");
 | 
			
		||||
            $errorMessages = $response->getMessages()->getMessage();
 | 
			
		||||
            info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
            // info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        info('the new customer profile id = '.$response->getCustomerProfileId());
 | 
			
		||||
        // info('the new customer profile id = '.$response->getCustomerProfileId());
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($response);
 | 
			
		||||
    }
 | 
			
		||||
@ -208,8 +208,8 @@ class AuthorizeTest extends TestCase
 | 
			
		||||
        $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
 | 
			
		||||
 | 
			
		||||
        if (($response != null) && ($response->getMessages()->getResultCode() == 'Ok')) {
 | 
			
		||||
            info('got profile');
 | 
			
		||||
            info(print_r($response->getProfile(), 1));
 | 
			
		||||
            // info('got profile');
 | 
			
		||||
            // info(print_r($response->getProfile(), 1));
 | 
			
		||||
        } else {
 | 
			
		||||
            info("ERROR :  Invalid response\n");
 | 
			
		||||
        }
 | 
			
		||||
@ -276,11 +276,11 @@ class AuthorizeTest extends TestCase
 | 
			
		||||
        $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
 | 
			
		||||
 | 
			
		||||
        if (($response != null) && ($response->getMessages()->getResultCode() == 'Ok')) {
 | 
			
		||||
            info('Create Customer Payment Profile SUCCESS: '.$response->getCustomerPaymentProfileId()."\n");
 | 
			
		||||
         //   info('Create Customer Payment Profile SUCCESS: '.$response->getCustomerPaymentProfileId()."\n");
 | 
			
		||||
        } else {
 | 
			
		||||
            info("Create Customer Payment Profile: ERROR Invalid response\n");
 | 
			
		||||
        //    info("Create Customer Payment Profile: ERROR Invalid response\n");
 | 
			
		||||
            $errorMessages = $response->getMessages()->getMessage();
 | 
			
		||||
            info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
        //    info('Response : '.$errorMessages[0]->getCode().'  '.$errorMessages[0]->getText()."\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($response);
 | 
			
		||||
@ -354,26 +354,5 @@ class AuthorizeTest extends TestCase
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($tresponse);
 | 
			
		||||
 | 
			
		||||
        /* Testing refunds - need to research more as payments are in a pending state so cannot be 'refunded'*/
 | 
			
		||||
 | 
			
		||||
        // info("transaction reference = " . $tresponse->getTransId());
 | 
			
		||||
 | 
			
		||||
        // $payment = PaymentFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        // $payment->amount = 400;
 | 
			
		||||
        // $payment->client_id = $this->client->id;
 | 
			
		||||
        // $payment->date = now();
 | 
			
		||||
        // $payment->transaction_reference = $tresponse->getTransId();
 | 
			
		||||
        // $payment->company_gateway_id = 1;
 | 
			
		||||
 | 
			
		||||
        // $payment->save();
 | 
			
		||||
 | 
			
		||||
        // $company_gateway = CompanyGateway::where('gateway_key', '3b6621f970ab18887c4f6dca78d3f8bb')->first();
 | 
			
		||||
 | 
			
		||||
        // $authorize_payment_driver = new AuthorizePaymentDriver($company_gateway, $this->client);
 | 
			
		||||
        // $response = $authorize_payment_driver->refund($payment, 350);
 | 
			
		||||
 | 
			
		||||
        // info(print_r($response,1));
 | 
			
		||||
 | 
			
		||||
        // $this->assertTrue(is_array($response));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user