From c1c8b6c14e89f7e5c4190751ae499e01c997d6a8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 29 Oct 2020 20:40:13 +1100 Subject: [PATCH 1/2] Change start_time datatype --- .../Requests/Invoice/StoreInvoiceRequest.php | 7 +++- app/Http/Requests/Task/StoreTaskRequest.php | 4 ++ app/Models/Expense.php | 1 + app/Models/Task.php | 1 + app/Repositories/TaskRepository.php | 1 - app/Utils/Traits/ClientGroupSettingsSaver.php | 3 +- app/Utils/Traits/GeneratesCounter.php | 40 +++++++++++++++++++ ...9_093836_change_start_time_column_type.php | 30 ++++++++++++++ tests/Feature/TaskApiTest.php | 12 ++++++ 9 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2020_10_29_093836_change_start_time_column_type.php diff --git a/app/Http/Requests/Invoice/StoreInvoiceRequest.php b/app/Http/Requests/Invoice/StoreInvoiceRequest.php index 827f6895d641..893c659251d9 100644 --- a/app/Http/Requests/Invoice/StoreInvoiceRequest.php +++ b/app/Http/Requests/Invoice/StoreInvoiceRequest.php @@ -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); } } diff --git a/app/Http/Requests/Task/StoreTaskRequest.php b/app/Http/Requests/Task/StoreTaskRequest.php index 5a26e729a8eb..6825fe50825f 100644 --- a/app/Http/Requests/Task/StoreTaskRequest.php +++ b/app/Http/Requests/Task/StoreTaskRequest.php @@ -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); } diff --git a/app/Models/Expense.php b/app/Models/Expense.php index 1747164b7769..29ad16e5e918 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -53,6 +53,7 @@ class Expense extends BaseModel 'custom_value2', 'custom_value3', 'custom_value4', + 'number', ]; protected $casts = [ diff --git a/app/Models/Task.php b/app/Models/Task.php index 11f32f6a23a8..461602d52d5f 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -39,6 +39,7 @@ class Task extends BaseModel 'status_sort_order', 'invoice_documents', 'rate', + 'number', ]; protected $touches = []; diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index cf3ea2df3802..e77b5396c3bf 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -45,7 +45,6 @@ class TaskRepository extends BaseRepository * * @return task|null task Object */ - public function save(array $data, Task $task) : ?Task { diff --git a/app/Utils/Traits/ClientGroupSettingsSaver.php b/app/Utils/Traits/ClientGroupSettingsSaver.php index 38b91ddb9953..52878eae3ad7 100644 --- a/app/Utils/Traits/ClientGroupSettingsSaver.php +++ b/app/Utils/Traits/ClientGroupSettingsSaver.php @@ -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': diff --git a/app/Utils/Traits/GeneratesCounter.php b/app/Utils/Traits/GeneratesCounter.php index b559beae5808..089e05403c58 100644 --- a/app/Utils/Traits/GeneratesCounter.php +++ b/app/Utils/Traits/GeneratesCounter.php @@ -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. diff --git a/database/migrations/2020_10_29_093836_change_start_time_column_type.php b/database/migrations/2020_10_29_093836_change_start_time_column_type.php new file mode 100644 index 000000000000..26cde14da1c3 --- /dev/null +++ b/database/migrations/2020_10_29_093836_change_start_time_column_type.php @@ -0,0 +1,30 @@ +unsignedInteger('duration')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/tests/Feature/TaskApiTest.php b/tests/Feature/TaskApiTest.php index b6ed93936754..885007a6e3b2 100644 --- a/tests/Feature/TaskApiTest.php +++ b/tests/Feature/TaskApiTest.php @@ -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([ From 8cf55010c62c3409119e6e1ed1f6b8ba1139afa3 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 29 Oct 2020 20:56:37 +1100 Subject: [PATCH 2/2] Fixes for tasks --- app/Http/Requests/Task/StoreTaskRequest.php | 4 ++ app/Mail/Engine/QuoteEmailEngine.php | 1 + app/Models/Task.php | 4 +- app/Repositories/TaskRepository.php | 42 ++++++++++++++++- .../PaymentDrivers/AuthorizeTest.php | 45 +++++-------------- 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/app/Http/Requests/Task/StoreTaskRequest.php b/app/Http/Requests/Task/StoreTaskRequest.php index 6825fe50825f..ddb30edeaaa1 100644 --- a/app/Http/Requests/Task/StoreTaskRequest.php +++ b/app/Http/Requests/Task/StoreTaskRequest.php @@ -51,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); } diff --git a/app/Mail/Engine/QuoteEmailEngine.php b/app/Mail/Engine/QuoteEmailEngine.php index 6121787c22b5..dc8e92932e5e 100644 --- a/app/Mail/Engine/QuoteEmailEngine.php +++ b/app/Mail/Engine/QuoteEmailEngine.php @@ -11,6 +11,7 @@ namespace App\Mail\Engine; +use App\Utils\HtmlEngine; use App\Utils\Number; class QuoteEmailEngine extends BaseEmailEngine diff --git a/app/Models/Task.php b/app/Models/Task.php index 461602d52d5f..47412d915618 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -98,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; } } diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index e77b5396c3bf..6e9ac946071a 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -49,11 +49,49 @@ class TaskRepository extends BaseRepository { $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)) { diff --git a/tests/Integration/PaymentDrivers/AuthorizeTest.php b/tests/Integration/PaymentDrivers/AuthorizeTest.php index df76e186742e..302661343505 100644 --- a/tests/Integration/PaymentDrivers/AuthorizeTest.php +++ b/tests/Integration/PaymentDrivers/AuthorizeTest.php @@ -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)); } }