mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 06:20:21 +00:00
Merge branch 'main' of bitbucket.org:studiotem/jandl-taskmanager-app
This commit is contained in:
commit
44d315c961
4 files changed
+157
-50
No files matched your search
@@ -92,4 +92,4 @@ export default {
|
|||||||
|
|
||||||
.gif-loader
|
.gif-loader
|
||||||
height: 30px
|
height: 30px
|
||||||
</style>
|
</style>
|
||||||
@@ -11,6 +11,8 @@ use App\Models\SubTask;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class SubTaskController extends Controller
|
class SubTaskController extends Controller
|
||||||
@@ -412,8 +414,9 @@ class SubTaskController extends Controller
|
|||||||
$subtask->syncTimesheets($data['data']['timesheets']);
|
$subtask->syncTimesheets($data['data']['timesheets']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// syncnutie timeblocks
|
// syncnutie timeblocks - PRE DRAFTY s viacerými zamestnancami NIE!
|
||||||
if (isset($data['data']['timeblocks'])) {
|
// Timeblocks pre drafty s employees sú uložené v draft_data, nie v tabuľke timeblocks
|
||||||
|
if (isset($data['data']['timeblocks']) && ! $isDraftWithMultipleEmployees) {
|
||||||
$subtask->syncTimeblocks($data['data']['timeblocks']);
|
$subtask->syncTimeblocks($data['data']['timeblocks']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +433,8 @@ class SubTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function publishDraftWithMultipleEmployees(SubTask $draft, Request $request)
|
private function publishDraftWithMultipleEmployees(SubTask $draft, Request $request)
|
||||||
{
|
{
|
||||||
$employees = $draft->draft_data;
|
// Použij employees z requestu ak existujú, inak fallback na draft_data z DB
|
||||||
|
$employees = $request->all()['data']['employees'] ?? $draft->draft_data;
|
||||||
|
|
||||||
// Ak je employees pole prázdne, zlyhaj
|
// Ak je employees pole prázdne, zlyhaj
|
||||||
if (empty($employees)) {
|
if (empty($employees)) {
|
||||||
@@ -450,15 +454,16 @@ class SubTaskController extends Controller
|
|||||||
// Ak duration nie je nastavený, vypočítaj ho z timeblocks
|
// Ak duration nie je nastavený, vypočítaj ho z timeblocks
|
||||||
if (! isset($employee['duration']) || $employee['duration'] === null) {
|
if (! isset($employee['duration']) || $employee['duration'] === null) {
|
||||||
if (isset($employee['timeblocks']) && ! empty($employee['timeblocks'])) {
|
if (isset($employee['timeblocks']) && ! empty($employee['timeblocks'])) {
|
||||||
$totalDuration = 0;
|
$totalDurationMinutes = 0;
|
||||||
foreach ($employee['timeblocks'] as $timeblock) {
|
foreach ($employee['timeblocks'] as $timeblock) {
|
||||||
if (isset($timeblock['start']) && isset($timeblock['end'])) {
|
if (isset($timeblock['start']) && isset($timeblock['end'])) {
|
||||||
$start = Carbon::parse($timeblock['start']);
|
$start = Carbon::parse($timeblock['start']);
|
||||||
$end = Carbon::parse($timeblock['end']);
|
$end = Carbon::parse($timeblock['end']);
|
||||||
$totalDuration += $end->diffInMinutes($start);
|
$totalDurationMinutes += $end->diffInMinutes($start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$employees[$key]['duration'] = $totalDuration;
|
// Konvertuj na hodiny (frontend očakáva hodiny)
|
||||||
|
$employees[$key]['duration'] = $totalDurationMinutes / 60;
|
||||||
} else {
|
} else {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Draft cannot be published. Each employee must have duration or timeblocks.',
|
'message' => 'Draft cannot be published. Each employee must have duration or timeblocks.',
|
||||||
@@ -470,48 +475,80 @@ class SubTaskController extends Controller
|
|||||||
$mastertask = $draft->mastertask;
|
$mastertask = $draft->mastertask;
|
||||||
$createdSubtasks = [];
|
$createdSubtasks = [];
|
||||||
|
|
||||||
// Vytvoríme subtask pre každého zamestnanca
|
// Použijeme transakciu pre atomicitu operácie
|
||||||
foreach ($employees as $employee) {
|
try {
|
||||||
$subtaskData = [
|
DB::beginTransaction();
|
||||||
'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);
|
// Získame aktuálne hodnoty z requestu (ak existujú), inak fallback na draft
|
||||||
|
$requestData = $request->all()['data'] ?? [];
|
||||||
|
$title = $requestData['title'] ?? $draft->title;
|
||||||
|
$description = $requestData['description'] ?? $draft->description;
|
||||||
|
$deadline = $requestData['deadline'] ?? $draft->deadline;
|
||||||
|
|
||||||
// Sync timeblocks ak existujú
|
// Vytvoríme subtask pre každého zamestnanca
|
||||||
if (isset($employee['timeblocks']) && ! empty($employee['timeblocks'])) {
|
foreach ($employees as $employee) {
|
||||||
$newSubtask->syncTimeblocks($employee['timeblocks']);
|
$subtaskData = [
|
||||||
|
'user_id' => $employee['id'],
|
||||||
|
'title' => $title,
|
||||||
|
'description' => $description,
|
||||||
|
'deadline' => $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ú - DÔLEŽITÉ: odstránime ID aby sa vytvorili nové záznamy
|
||||||
|
if (isset($employee['timeblocks']) && ! empty($employee['timeblocks'])) {
|
||||||
|
$cleanTimeblocks = array_map(function ($timeblock) {
|
||||||
|
// Odstránime ID a sub_task_id, aby sa vytvorili nové záznamy
|
||||||
|
unset($timeblock['id']);
|
||||||
|
unset($timeblock['sub_task_id']);
|
||||||
|
return $timeblock;
|
||||||
|
}, $employee['timeblocks']);
|
||||||
|
$newSubtask->createTimeblocks($cleanTimeblocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skopírujeme attachmenty z pôvodného draftu
|
// Zmažeme pôvodný draft
|
||||||
foreach ($draft->attachments as $attachment) {
|
$draft->timeblocks()->delete();
|
||||||
$newSubtask->attachments()->create([
|
$draft->attachments()->delete(); // attachmenty sú už skopírované
|
||||||
'name' => $attachment->name,
|
$draft->delete();
|
||||||
'path' => $attachment->path,
|
|
||||||
'size' => $attachment->size,
|
|
||||||
'type' => $attachment->type,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$createdSubtasks[] = $newSubtask;
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Draft published successfully',
|
||||||
|
'subtasks' => SubTaskResource::collection($createdSubtasks),
|
||||||
|
], 201);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
Log::error('Failed to publish draft: ' . $e->getMessage(), [
|
||||||
|
'draft_id' => $draft->id,
|
||||||
|
'employees' => $employees,
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Failed to publish draft. Please try again.',
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
public function delete($id)
|
||||||
|
|||||||
@@ -44,6 +44,22 @@ class SubTaskResource extends JsonResource
|
|||||||
// Pre drafty pridáme employees dáta
|
// Pre drafty pridáme employees dáta
|
||||||
if ($this->is_draft && $this->draft_data) {
|
if ($this->is_draft && $this->draft_data) {
|
||||||
$data['employees'] = $this->draft_data;
|
$data['employees'] = $this->draft_data;
|
||||||
|
|
||||||
|
// Agregované timeblocks zo všetkých zamestnancov pre kalendárne zobrazenie
|
||||||
|
$allDraftTimeblocks = [];
|
||||||
|
foreach ($this->draft_data as $employee) {
|
||||||
|
if (isset($employee['timeblocks']) && is_array($employee['timeblocks'])) {
|
||||||
|
foreach ($employee['timeblocks'] as $timeblock) {
|
||||||
|
$allDraftTimeblocks[] = [
|
||||||
|
'employee_id' => $employee['id'],
|
||||||
|
'start' => $timeblock['start'] ?? null,
|
||||||
|
'end' => $timeblock['end'] ?? null,
|
||||||
|
'is_finished' => $timeblock['is_finished'] ?? false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$data['all_draft_timeblocks'] = $allDraftTimeblocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|||||||
@@ -84,21 +84,75 @@ class SubTask extends Model
|
|||||||
$this->touch();
|
$this->touch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronizácia timeblocks - aktualizuje existujúce, vytvorí nové, zmaže nepoužité
|
||||||
|
*/
|
||||||
public function syncTimeblocks(Array $timeblocks)
|
public function syncTimeblocks(Array $timeblocks)
|
||||||
{
|
{
|
||||||
if (empty($timeblocks)) {
|
if (empty($timeblocks)) {
|
||||||
return $this->timeblocks()->delete();
|
return $this->timeblocks()->delete();
|
||||||
}
|
}
|
||||||
// pripravenie array na upsert
|
|
||||||
$timeblocks = array_map(function($item) {
|
// Získame ID existujúcich timeblocks tohto subtasku
|
||||||
|
$existingIds = $this->timeblocks()->pluck('id')->toArray();
|
||||||
|
|
||||||
|
// Rozdelíme na existujúce (s ID) a nové (bez ID alebo s neexistujúcim ID)
|
||||||
|
$timeblocksToUpdate = [];
|
||||||
|
$timeblocksToCreate = [];
|
||||||
|
$receivedIds = [];
|
||||||
|
|
||||||
|
foreach ($timeblocks as $item) {
|
||||||
$item['sub_task_id'] = $this->id;
|
$item['sub_task_id'] = $this->id;
|
||||||
return $item;
|
|
||||||
|
// Ak má ID a toto ID existuje v našich timeblocks, aktualizujeme
|
||||||
|
if (isset($item['id']) && in_array($item['id'], $existingIds)) {
|
||||||
|
$timeblocksToUpdate[] = $item;
|
||||||
|
$receivedIds[] = $item['id'];
|
||||||
|
} else {
|
||||||
|
// Nový timeblock - odstránime ID aby sa vytvoril nový záznam
|
||||||
|
unset($item['id']);
|
||||||
|
$timeblocksToCreate[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zmažeme timeblocks, ktoré neboli poslané z frontendu
|
||||||
|
$this->timeblocks()->whereNotIn('id', $receivedIds)->delete();
|
||||||
|
|
||||||
|
// Aktualizujeme existujúce
|
||||||
|
foreach ($timeblocksToUpdate as $timeblock) {
|
||||||
|
$this->timeblocks()->where('id', $timeblock['id'])->update([
|
||||||
|
'start' => $timeblock['start'],
|
||||||
|
'end' => $timeblock['end'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vytvoríme nové
|
||||||
|
if (! empty($timeblocksToCreate)) {
|
||||||
|
$this->timeblocks()->createMany($timeblocksToCreate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vytvorenie nových timeblocks - pre použitie pri publikovaní draftu
|
||||||
|
*/
|
||||||
|
public function createTimeblocks(Array $timeblocks)
|
||||||
|
{
|
||||||
|
if (empty($timeblocks)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$timeblocksToCreate = array_map(function($item) {
|
||||||
|
// Odstránime ID a sub_task_id pre istotu
|
||||||
|
unset($item['id']);
|
||||||
|
unset($item['sub_task_id']);
|
||||||
|
return [
|
||||||
|
'start' => $item['start'],
|
||||||
|
'end' => $item['end'],
|
||||||
|
'is_finished' => $item['is_finished'] ?? false,
|
||||||
|
];
|
||||||
}, $timeblocks);
|
}, $timeblocks);
|
||||||
|
|
||||||
// zmazanie vykazov, ktore neboli poslane z frontendu
|
$this->timeblocks()->createMany($timeblocksToCreate);
|
||||||
$this->timeblocks()->whereNotIn('id', collect($timeblocks)->pluck('id')->filter())->delete();
|
|
||||||
|
|
||||||
$this->timeblocks()->upsert($timeblocks, ['id']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteAttachments()
|
public function deleteAttachments()
|
||||||
|
|||||||
Reference in new issue
Block a user