diff --git a/be/app/Http/Controllers/SubTaskController.php b/be/app/Http/Controllers/SubTaskController.php index 200bdcd..62ef511 100644 --- a/be/app/Http/Controllers/SubTaskController.php +++ b/be/app/Http/Controllers/SubTaskController.php @@ -199,6 +199,43 @@ class SubTaskController extends Controller } } + $mastertask = MasterTask::find($mastertask_id); + $creatorId = User::getUserIdFromBearerToken($request->bearerToken()); + + // Pre drafty vytvoríme iba jeden záznam pod tvorcom s uloženými dátami všetkých zamestnancov + if ($isDraft) { + // Pripravíme dáta pre draft + $draftData = [ + 'user_id' => $creatorId, + 'created_by' => $creatorId, + 'title' => $request->all()['data']['title'] ?? null, + 'description' => $request->all()['data']['description'] ?? null, + 'deadline' => $request->all()['data']['deadline'] ?? null, + 'estimated_time' => 0, // celkový odhadovaný čas sa vypočíta z employees + 'is_draft' => true, + 'draft_data' => $request->all()['data']['employees'], // uložíme všetky employees data + ]; + + // Vypočítame celkový odhadovaný čas + foreach ($request->all()['data']['employees'] as $employee) { + $draftData['estimated_time'] += $employee['duration'] ?? 0; + } + + $subtask = $mastertask->subtasks()->create($draftData); + + // upload attachmentu + if ($request->file('data')) { + $attachments = Attachment::uploadAttachmentsToS3($request->file('data')['files'], $mastertask); + $subtask->attachments()->createMany($attachments); + } + + return response()->json([ + 'message' => 'Draft created successfully', + 'subtasks' => SubTaskResource::collection([$subtask]) + ], 201); + } + + // Pre normálne (nie draft) subtasky - pôvodná logika // upratanie requestu, pretoze frontend pouziva inu nomenklaturu fieldov ako appka $data['data'] = $request->all()['data']; @@ -206,16 +243,15 @@ class SubTaskController extends Controller $data['data']['employees'][$key]['user_id'] = $employee['id']; $data['data']['employees'][$key]['title'] = isset($request->all()['data']['title']) ? $request->all()['data']['title'] : null; $data['data']['employees'][$key]['estimated_time'] = $employee['duration']; - $data['data']['employees'][$key]['created_by'] = User::getUserIdFromBearerToken($request->bearerToken()); + $data['data']['employees'][$key]['created_by'] = $creatorId; $data['data']['employees'][$key]['description'] = $request->all()['data']['description']; $data['data']['employees'][$key]['deadline'] = $request->all()['data']['deadline']; - $data['data']['employees'][$key]['is_draft'] = $isDraft; + $data['data']['employees'][$key]['is_draft'] = false; } $request->merge($data); - $mastertask = MasterTask::find($mastertask_id); - $subtasks = $mastertask->subtasks()->createMany($request->all()['data']['employees']); + $subtasks = $mastertask->subtasks()->createMany($request->all()['data']['employees']); // syncnutie timeblocks foreach ($request->all()['data']['employees'] as $key => $employee) { @@ -240,10 +276,8 @@ class SubTaskController extends Controller } } - $message = $isDraft ? 'Draft created successfully' : 'Sub Task created successfully'; - return response()->json([ - 'message' => $message, + 'message' => 'Sub Task created successfully', 'subtasks' => SubTaskResource::collection($subtasks) ], 201); } @@ -275,6 +309,12 @@ class SubTaskController extends Controller // validácia pri publikovaní draftu (is_draft: false) $isPublishing = $subtask->is_draft && isset($request->all()['data']['is_draft']) && $request->all()['data']['is_draft'] == false; + + // Pri publikovaní draftu s draft_data (viacero zamestnancov) - vytvoríme subtasky pre každého + if ($isPublishing && $subtask->draft_data) { + return $this->publishDraftWithMultipleEmployees($subtask, $request); + } + if ($isPublishing) { $publishValidator = Validator::make([ 'master_task_id' => $subtask->master_task_id, @@ -294,12 +334,21 @@ class SubTaskController extends Controller } } - $validator = Validator::make($request->all(), [ - 'data.duration' => 'required', - ]); + // Pre drafty s employees dátami - aktualizujeme aj draft_data + if ($subtask->is_draft && isset($request->all()['data']['employees'])) { + $subtask->draft_data = $request->all()['data']['employees']; + $subtask->save(); + } - if ($validator->fails()) { - return response()->json($validator->errors(), 400); + // Pre drafty je validácia duration voliteľná + if (!$subtask->is_draft) { + $validator = Validator::make($request->all(), [ + '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 @@ -315,10 +364,10 @@ class SubTaskController extends Controller // 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']['user_id'] = $request->all()['data']['employee_id'] ?? $subtask->user_id; $data['data']['title'] = isset($request->all()['data']['title']) ? $request->all()['data']['title'] : null; $data['data']['deadline'] = isset($request->all()['data']['deadline']) ? $request->all()['data']['deadline'] : null; - $data['data']['estimated_time'] = $request->all()['data']['duration']; + $data['data']['estimated_time'] = $request->all()['data']['duration'] ?? $subtask->estimated_time; $data['data']['updated_by'] = User::getUserIdFromBearerToken($request->bearerToken()); // publikovanie draftu @@ -355,6 +404,76 @@ class SubTaskController extends Controller ]); } + /** + * Publikovanie draftu s viacerými zamestnancami - rozdelí draft na jednotlivé subtasky + */ + private function publishDraftWithMultipleEmployees(SubTask $draft, Request $request) + { + $employees = $draft->draft_data; + + // Ak je employees pole prázdne, zlyhaj + if (empty($employees)) { + return response()->json([ + 'message' => 'Draft cannot be published. No employees data found.', + ], 400); + } + + // Validácia - každý zamestnanec musí mať id a duration + foreach ($employees as $employee) { + if (!isset($employee['id']) || !isset($employee['duration'])) { + return response()->json([ + 'message' => 'Draft cannot be published. Each employee must have id and duration.', + ], 400); + } + } + + $mastertask = $draft->mastertask; + $createdSubtasks = []; + + // Vytvoríme subtask pre každého zamestnanca + foreach ($employees as $employee) { + $subtaskData = [ + 'user_id' => $employee['id'], + 'title' => $draft->title, + 'description' => $draft->description, + 'deadline' => $draft->deadline, + 'estimated_time' => $employee['duration'], + 'created_by' => $draft->created_by, + 'is_draft' => false, + 'draft_data' => null, + ]; + + $newSubtask = $mastertask->subtasks()->create($subtaskData); + + // Sync timeblocks ak existujú + if (isset($employee['timeblocks']) && !empty($employee['timeblocks'])) { + $newSubtask->syncTimeblocks($employee['timeblocks']); + } + + // Skopírujeme attachmenty z pôvodného draftu + foreach ($draft->attachments as $attachment) { + $newSubtask->attachments()->create([ + 'name' => $attachment->name, + 'path' => $attachment->path, + 'size' => $attachment->size, + 'type' => $attachment->type, + ]); + } + + $createdSubtasks[] = $newSubtask; + } + + // Zmažeme pôvodný draft + $draft->timeblocks()->delete(); + $draft->attachments()->delete(); // attachmenty sú už skopírované + $draft->delete(); + + return response()->json([ + 'message' => 'Draft published successfully', + 'subtasks' => SubTaskResource::collection($createdSubtasks) + ], 201); + } + public function delete($id) { $subtask = SubTask::find($id); diff --git a/be/app/Http/Resources/SubTaskResource.php b/be/app/Http/Resources/SubTaskResource.php index b36f8dd..c667db9 100644 --- a/be/app/Http/Resources/SubTaskResource.php +++ b/be/app/Http/Resources/SubTaskResource.php @@ -15,7 +15,7 @@ class SubTaskResource extends JsonResource */ public function toArray($request) { - return [ + $data = [ 'id' => $this->id, 'is_draft' => $this->is_draft, 'type' => $this->type, @@ -40,5 +40,12 @@ class SubTaskResource extends JsonResource 'files' => AttachmentResource::collection($this->attachments->isNotEmpty() ? $this->attachments : $this->mastertask->attachments), 'color' => $this->mastertask->color, ]; + + // Pre drafty pridáme employees dáta + if ($this->is_draft && $this->draft_data) { + $data['employees'] = $this->draft_data; + } + + return $data; } } diff --git a/be/app/Models/SubTask.php b/be/app/Models/SubTask.php index 1df528b..518f379 100644 --- a/be/app/Models/SubTask.php +++ b/be/app/Models/SubTask.php @@ -13,6 +13,10 @@ class SubTask extends Model public $timestamps = true; public $guarded = ['id']; + protected $casts = [ + 'draft_data' => 'array', + ]; + /** * Scope pre koncepty (drafty) - nezverejnené subtasky */ diff --git a/be/database/migrations/2025_12_15_100000_add_draft_data_to_subtasks_table.php b/be/database/migrations/2025_12_15_100000_add_draft_data_to_subtasks_table.php new file mode 100644 index 0000000..43e86b6 --- /dev/null +++ b/be/database/migrations/2025_12_15_100000_add_draft_data_to_subtasks_table.php @@ -0,0 +1,33 @@ +json('draft_data')->nullable()->after('is_draft'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('sub_tasks', function (Blueprint $table) { + $table->dropColumn('draft_data'); + }); + } +}; +