Updates for task time log parsing

This commit is contained in:
David Bomba 2023-11-10 10:09:27 +11:00
parent c8408bfa36
commit 4cbf10096b
6 changed files with 171 additions and 21 deletions

View File

@ -54,7 +54,13 @@ class StoreTaskRequest extends Request
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0'; $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
} }
$rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) { $rules['time_log'] = ['bail',function ($attribute, $values, $fail) {
if(!is_array(json_decode($values, true))) {
$fail('The '.$attribute.' must be a valid array.');
return;
}
foreach ($values as $k) { foreach ($values as $k) {
if (!is_int($k[0]) || !is_int($k[1])) { if (!is_int($k[0]) || !is_int($k[1])) {
$fail('The '.$attribute.' - '.print_r($k, 1).' is invalid. Unix timestamps only.'); $fail('The '.$attribute.' - '.print_r($k, 1).' is invalid. Unix timestamps only.');
@ -110,6 +116,10 @@ class StoreTaskRequest extends Request
} }
} }
if(!isset($input['time_log']) || empty($input['time_log']) || $input['time_log'] == '{}'){
$input['time_log'] = json_encode([]);
}
$this->replace($input); $this->replace($input);
} }
} }

View File

@ -35,26 +35,38 @@ class UpdateTaskRequest extends Request
return false; return false;
} }
return auth()->user()->can('edit', $this->task); /** @var \App\Models\User $user */
$user = auth()->user();
return $user->can('edit', $this->task);
} }
public function rules() public function rules()
{ {
/** @var \App\Models\User $user */
$user = auth()->user();
$rules = []; $rules = [];
if (isset($this->number)) { if (isset($this->number)) {
$rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id)->ignore($this->task->id); $rules['number'] = Rule::unique('tasks')->where('company_id', $user->company()->id)->ignore($this->task->id);
} }
if (isset($this->client_id)) { if (isset($this->client_id)) {
$rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; $rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.$user->company()->id.',is_deleted,0';
} }
if (isset($this->project_id)) { if (isset($this->project_id)) {
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
}
$rules['time_log'] = ['bail', function ($attribute, $values, $fail) {
if(!is_array(json_decode($values, true))) {
$fail('The '.$attribute.' must be a valid array.');
return;
} }
$rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) {
foreach ($values as $k) { foreach ($values as $k) {
if (!is_int($k[0]) || !is_int($k[1])) { if (!is_int($k[0]) || !is_int($k[1])) {
$fail('The '.$attribute.' - '.print_r($k, 1).' is invalid. Unix timestamps only.'); $fail('The '.$attribute.' - '.print_r($k, 1).' is invalid. Unix timestamps only.');
@ -113,6 +125,10 @@ class UpdateTaskRequest extends Request
} }
if(!isset($input['time_log']) || empty($input['time_log']) || $input['time_log'] == '{}') {
$input['time_log'] = json_encode([]);
}
$this->replace($input); $this->replace($input);
} }

View File

@ -241,7 +241,7 @@ class Task extends BaseModel
public function processLogs() public function processLogs()
{ {
return return
collect($this->timelog)->map(function ($log){ collect($this->time_log)->map(function ($log){
$parent_entity = $this->client ?? $this->company; $parent_entity = $this->client ?? $this->company;

View File

@ -136,7 +136,7 @@ class TemplateService
/** /**
* Initialized a set of HTMLEngine variables * Initialized a set of HTMLEngine variables
* *
* @param array | Collection $data * @param array | \Illuminate\Support\Collection $data
* @return self * @return self
*/ */
private function processVariables($data): self private function processVariables($data): self
@ -209,7 +209,7 @@ class TemplateService
/** /**
* Process data variables * Process data variables
* *
* @param array | Collection $data * @param array | \Illuminate\Support\Collection $data
* @return self * @return self
*/ */
public function processData($data): self public function processData($data): self
@ -392,7 +392,7 @@ class TemplateService
* Pre Processes the Data Blocks into * Pre Processes the Data Blocks into
* Twig consumables * Twig consumables
* *
* @param array | Collection $data * @param array | \Illuminate\Support\Collection $data
* @return array * @return array
*/ */
private function preProcessDataBlocks($data): array private function preProcessDataBlocks($data): array
@ -421,7 +421,7 @@ class TemplateService
/** /**
* Process Invoices into consumable form for Twig templates * Process Invoices into consumable form for Twig templates
* *
* @param array | Collection $invoices * @param array | \Illuminate\Support\Collection $invoices
* @return array * @return array
*/ */
public function processInvoices($invoices): array public function processInvoices($invoices): array
@ -506,7 +506,7 @@ class TemplateService
* Pads Line Items with raw and formatted content * Pads Line Items with raw and formatted content
* *
* @param array $items * @param array $items
* @param mixed $client * @param Client $client
* @return array * @return array
*/ */
public function padLineItems(array $items, Client $client): array public function padLineItems(array $items, Client $client): array
@ -698,7 +698,7 @@ class TemplateService
* Pushes credits through the appropriate transformer * Pushes credits through the appropriate transformer
* and builds any required relationships * and builds any required relationships
* *
* @param array | Collection $credits * @param array | \Illuminate\Support\Collection $credits
* @return array * @return array
*/ */
public function processCredits($credits): array public function processCredits($credits): array
@ -775,7 +775,7 @@ class TemplateService
/** /**
* Pushes payments through the appropriate transformer * Pushes payments through the appropriate transformer
* *
* @param array | Collection $payments * @param array | \Illuminate\Support\Collection $payments
* @return array * @return array
*/ */
public function processPayments($payments): array public function processPayments($payments): array
@ -832,7 +832,7 @@ class TemplateService
/** /**
* @todo refactor * @todo refactor
* *
* @param array | Collection $projects * @param array | \Illuminate\Support\Collection $projects
* @return array * @return array
*/ */
public function processProjects($projects): array public function processProjects($projects): array
@ -900,7 +900,7 @@ class TemplateService
/** /**
* Set Company * Set Company
* *
* @param mixed $company * @param Company $company
* @return self * @return self
*/ */
public function setCompany(Company $company): self public function setCompany(Company $company): self
@ -955,7 +955,6 @@ class TemplateService
}) })
->map(function ($stack){ ->map(function ($stack){
$node = $this->document->getElementById($stack); $node = $this->document->getElementById($stack);
nlog(['stack' => $stack, 'labels' => $node->getAttribute('labels')]);
return ['stack' => $stack, 'labels' => $node->getAttribute('labels')]; return ['stack' => $stack, 'labels' => $node->getAttribute('labels')];
}) })
->each(function ($stack) { ->each(function ($stack) {
@ -976,7 +975,7 @@ class TemplateService
{ {
match($stack['stack']) { match($stack['stack']) {
'entity-details' => $this->entityDetails($stack['labels'] == 'true'), 'entity-details' => $this->entityDetails(),
'client-details' => $this->clientDetails($stack['labels'] == 'true'), 'client-details' => $this->clientDetails($stack['labels'] == 'true'),
'vendor-details' => $this->vendorDetails($stack['labels'] == 'true'), 'vendor-details' => $this->vendorDetails($stack['labels'] == 'true'),
'company-details' => $this->companyDetails($stack['labels'] == 'true'), 'company-details' => $this->companyDetails($stack['labels'] == 'true'),
@ -1010,11 +1009,11 @@ class TemplateService
}); });
})->toArray(); })->toArray();
nlog($company_details); // nlog($company_details);
$company_details = $include_labels ? $this->labelledFieldStack($company_details, 'company_details-') : $company_details; $company_details = $include_labels ? $this->labelledFieldStack($company_details, 'company_details-') : $company_details;
nlog($company_details); // nlog($company_details);
$this->updateElementProperties('company-details', $company_details); $this->updateElementProperties('company-details', $company_details);

View File

@ -104,6 +104,90 @@ class TaskApiTest extends TestCase
} }
} }
public function testEmptyTimeLogArray()
{
$data = [
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'description' => 'Test Task',
'time_log' => null,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/tasks", $data);
$response->assertStatus(200);
$data = [
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'description' => 'Test Task',
'time_log' => '',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/tasks", $data);
$response->assertStatus(200);
$data = [
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'description' => 'Test Task',
'time_log' => '[]',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/tasks", $data);
$response->assertStatus(200);
$data = [
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'description' => 'Test Task',
'time_log' => '{}',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/tasks", $data);
$response->assertStatus(200);
}
public function testFaultyTimeLogArray()
{
$data = [
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'description' => 'Test Task',
'time_log' => 'ABBA is the best band in the world',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/tasks", $data);
$response->assertStatus(422);
}
public function testTaskClientRateSet() public function testTaskClientRateSet()
{ {
$settings = ClientSettings::defaults(); $settings = ClientSettings::defaults();
@ -262,6 +346,45 @@ class TaskApiTest extends TestCase
$response->assertStatus(200); $response->assertStatus(200);
$task->time_log = 'A very strange place';
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/tasks/{$task->hashed_id}?stop=true", $task->toArray());
$response->assertStatus(422);
$task->time_log = null;
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/tasks/{$task->hashed_id}?stop=true", $task->toArray());
$response->assertStatus(200);
$task->time_log = '';
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/tasks/{$task->hashed_id}?stop=true", $task->toArray());
$response->assertStatus(200);
$task->time_log = '{}';
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/tasks/{$task->hashed_id}?stop=true", $task->toArray());
$response->assertStatus(200);
} }
public function testStoppingTaskWithDescription() public function testStoppingTaskWithDescription()

View File

@ -191,8 +191,10 @@ class TemplateTest extends TestCase
'client_id' => $this->client->id, 'client_id' => $this->client->id,
]); ]);
$data['projects'][] = $p;
$ts = new TemplateService(); $ts = new TemplateService();
$ts->processData($data['projects'][$p]); $ts->processData($data);
$this->assertNotNull($ts); $this->assertNotNull($ts);
} }