query(); // unscheduled tasks if (isset($parameters['type']) && $parameters['type'] == 'unscheduled') { return $this->indexUnscheduled($request); } // ongoing tasks if (isset($parameters['type']) && $parameters['type'] == 'ongoing') { return $this->indexOngoing($request); } $parameters['user_id'] = ( $parameters['employee_id'] ?? null ); $validator = Validator::make($request->all(), [ 'start' => 'required', 'end' => 'required', ]); $validator->after(function ($validator) use ($parameters) { if ( !isset($parameters['employee_id']) && !isset($parameters['team_id'])) { $validator->errors()->add( 'error', 'You must provide either employee_id or team_id.' ); } }); if ($validator->fails()){ return response()->json($validator->errors(), 400); } if (isset($parameters['team_id'])) { $subtasks = SubTask::whereHas('mastertask', function ($query) use ($parameters) { $query->where('team_id', $parameters['team_id']); })->whereHas('timeblocks', function ($query) use ($parameters) { $query->where('start', '>=', $parameters['start']); $query->where('end', '<=', $parameters['end']); })->get(); $userIdArray = User::whereHas('teams', function ($query) use ($parameters) { $query->where('team_id', $parameters['team_id']); })->get()->pluck('id')->toArray(); } else if (isset($parameters['user_id'])) { $subtasks = SubTask::where('user_id', $parameters['user_id'])->whereHas('timeblocks', function ($query) use ($parameters) { $query->where('start', '>=', $parameters['start']); $query->where('end', '<=', $parameters['end']); })->get(); $userIdArray = [$parameters['user_id']]; } $blockers = Blocker::whereIn('user_id', $userIdArray)->where('start', '>=', $parameters['start'])->where('end', '<=', $parameters['end'])->get(); return response()->json([ 'subtasks' => SubTaskResource::collection($subtasks), 'blockers' => BlockerResource::collection($blockers), ], 200); } private function indexUnscheduled(Request $request) { // get query parameter from request $parameters = $request->query(); $validator = Validator::make( $parameters, [ 'employee_id' => 'required', ] ); if ( $validator->fails() ) { return response()->json( $validator->errors(), 400 ); } $parameters['user_id'] = $parameters['employee_id']; $subtasks = SubTask::where('user_id', $parameters['user_id'])->where('is_finished', 0)->whereDoesntHave( 'timeblocks')->get(); return response()->json( [ 'subtasks' => SubTaskResource::collection($subtasks) ], 200 ); } private function indexOngoing(Request $request) { // get query parameter from request $parameters = $request->query(); $validator = Validator::make( $parameters, [ 'employee_id' => 'required', ] ); if ( $validator->fails() ) { return response()->json( $validator->errors(), 400 ); } $parameters['user_id'] = $parameters['employee_id']; $subtasks = SubTask::where('user_id', $parameters['user_id'])->where('is_finished', 0)->get(); return response()->json( [ 'subtasks' => SubTaskResource::collection($subtasks) ], 200 ); } public function store($mastertask_id, Request $request) { $validator = Validator::make($request->all(), [ 'data.employee_id' => 'required', 'data.duration' => 'required', ]); // validacia, ci uz subtask pre tohto usera a mastertask neexistuje $validator->after(function ($validator) use ($mastertask_id, $request) { if (SubTask::where('master_task_id', $mastertask_id)->where('user_id', $request->all()['data']['employee_id'])->exists()) { $validator->errors()->add( 'data.employee_id', 'Sub task already exists for this employee and master task.' ); } }); if ($validator->fails()){ return response()->json($validator->errors(), 400); } // validacia na max 50MB size pre attachmenty. neslo dat do klasickeho laravel validation, tak je to separe if ($files = $request->file('data')) { foreach ( $files['files'] as $file ) { if ($file->getSize() > 52428800) return response()->json([ 'files' => 'File size must be less than 50MB', ], 400); } } // upratanie requestu, pretoze frontend pouziva inu nomenklaturu fieldov ako appka $data['data'] = $request->all()['data']; $data['data']['user_id'] = $request->all()['data']['employee_id']; $data['data']['estimated_time'] = $request->all()['data']['duration']; $data['data']['created_by'] = User::getUserIdFromBearerToken($request->bearerToken()); $request->merge($data); $mastertask = MasterTask::find($mastertask_id); $subtask = $mastertask->subtasks()->create($request->all()['data']); // syncnutie timeblocks $subtask->syncTimeblocks($data['data']['timeblocks']); // upload attachmentu if ($request->file('data')) { $attachments = Attachment::uploadAttachmentsToS3($request->file('data')['files'], $mastertask); $subtask->attachments()->createMany($attachments); } return response()->json([ 'message' => 'Sub Task created successfully', 'subtask' => $subtask ], 201); } // TODO zabezpecit, ze ked sa meni user, tak nech sa dvojmu nevlozia jeho vykazy public function update($id, Request $request) { $subtask = SubTask::find($id); // ak je sub task v stave ukončený, nedovolime update. vynimkou je iba znovuotvorenie mastertasku if ($subtask->is_finished == 1 && isset($request->all()['data']['is_finished']) && $request->all()['data']['is_finished'] == 1) { return response()->json([ 'message' => 'Cannot update subtask with is_finished 1.', ], 400); } // ak chcem ukoncit subtask, ktory nema natrackovany cas, tak to nedovolim if (isset($request->all()['data']['is_finished']) && $request->all()['data']['is_finished'] == 1 && $subtask->timesheets->count() == 0) { return response()->json([ 'message' => 'Cannot finish subtask with untracked time.', ], 400); } $validator = Validator::make($request->all(), [ 'data.employee_id' => 'required', 'data.duration' => 'required', ]); if ($validator->fails()){ return response()->json($validator->errors(), 400); } // validacia na max 50MB size pre attachmenty. neslo dat do klasickeho laravel validation, tak je to separe if ($files = $request->file('data')['files']) { foreach ( $files as $file ) { if ($file->getSize() > 52428800) return response()->json([ 'files' => 'File size must be less than 50MB', ], 400); } } // upratanie requestu, pretoze frontend pouziva inu nomenklaturu fieldov ako appka $data['data'] = $request->all()['data']; $data['data']['user_id'] = $request->all()['data']['employee_id']; $data['data']['estimated_time'] = $request->all()['data']['duration']; $request->merge($data); $subtask->update($request->all()['data']); // syncnutie vykazu $subtask->syncTimesheets($data['data']['timesheets']); // syncnutie timeblocks $subtask->syncTimeblocks($data['data']['timeblocks']); return response()->json([ 'message' => 'Subtask updated successfully', 'subtask' => new SubTaskResource($subtask) ]); } public function delete($id) { $subtask = SubTask::find($id); // ak existuje timesheet k subtasku, nemoze sa zmazat if ($subtask->timesheets()->exists()) { return response()->json([ 'message' => 'Cannot delete subtask with submitted timesheets.', ], 400); } $subtask->timeblocks()->delete(); $subtask->deleteAttachments(); $subtask->delete(); return response()->json([ 'message' => 'Subtask deleted successfully.', 'subtask' => $subtask ]); } public function submitTimesheet($id, Request $request) { $subtask = SubTask::find($id); $validator = Validator::make($request->all(), [ 'data.employee_id' => 'required', 'data.time' => 'required', ]); // validacia, ci dany user moze submitovat timesheet - ci mu patri subtask $validator->after(function ($validator) use ($subtask, $request) { if ($subtask->user_id != $request->all()['data']['employee_id']) { $validator->errors()->add( 'data.employee_id', 'This user cannot submit timesheet for the selected subtask. Subtask is assigned to user with id: ' . $subtask->user_id . '.' ); } }); if ($validator->fails()){ return response()->json($validator->errors(), 400); } $subtask->timesheets()->insert([ 'time' => $request->all()['data']['time'], 'user_id' => $request->all()['data']['employee_id'], 'sub_task_id' => $subtask->id, "created_at" => Carbon::now(), "updated_at" => Carbon::now(), ]); return response()->json([ 'message' => 'Subtask timesheet submitted successfully.', 'subtask' => $subtask ], 201); } }