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['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) {
if (!is_int($k[0]) || !is_int($k[1])) {
$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);
}
}

View File

@ -35,26 +35,38 @@ class UpdateTaskRequest extends Request
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()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$rules = [];
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)) {
$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)) {
$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['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) {
if (!is_int($k[0]) || !is_int($k[1])) {
$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);
}

View File

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

View File

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

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()
{
$settings = ClientSettings::defaults();
@ -262,6 +346,45 @@ class TaskApiTest extends TestCase
$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()

View File

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