mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 06:20:21 +00:00
643 lines
26 KiB
PHP
643 lines
26 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Resources\BlockerResource;
|
|
use App\Http\Resources\SubTaskResource;
|
|
use App\Models\Attachment;
|
|
use App\Models\Blocker;
|
|
use App\Models\MasterTask;
|
|
use App\Models\SubTask;
|
|
use App\Models\User;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class SubTaskController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
// get query parameter from request
|
|
$parameters = $request->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);
|
|
}
|
|
|
|
// draft tasks (koncepty)
|
|
if (isset($parameters['type']) && $parameters['type'] == 'draft') {
|
|
return $this->indexDrafts($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);
|
|
}
|
|
|
|
$start = Carbon::parse($parameters['start']);
|
|
$end = Carbon::parse($parameters['end'])->addDay();
|
|
|
|
if (isset($parameters['team_id'])) {
|
|
// ak je zadany team, tak najdem vsetkych userov, ktori su v tomto teame. potom najdem vsetky subtasky, ktore su priradene ludom v tomto teame. nevyhladavam na zaklade team_id v master_taskoch, pretoze toto je nepresne. Jandl chce vidiet tasky aj pre jednotlivcov v danom teame aj ked ten task nebol assignuty pod tymto teamom
|
|
|
|
$userIdArray = User::whereHas('teams', function ($query) use ($parameters) {
|
|
$query->where('team_id', $parameters['team_id']);
|
|
})->get()->pluck('id')->toArray();
|
|
|
|
$subtasks = SubTask::published()
|
|
->whereIn('user_id', $userIdArray)
|
|
->whereHas('timeblocks', function ($query) use ($start, $end) {
|
|
$query->where('start', '>=', $start);
|
|
$query->where('end', '<', $end);
|
|
})->get();
|
|
} elseif (isset($parameters['user_id'])) {
|
|
$subtasks = SubTask::published()
|
|
->where('user_id', $parameters['user_id'])->whereHas('timeblocks',
|
|
function ($query) use ($start, $end) {
|
|
$query->where('start', '>', $start);
|
|
$query->where('end', '<', $end);
|
|
})->get();
|
|
|
|
$userIdArray = [$parameters['user_id']];
|
|
}
|
|
$blockers1 = Blocker::whereIn('user_id', $userIdArray)->where('start', '>', $start)->get();
|
|
|
|
// vacation can last more than 7 days what is the date range we use in filter. we need to check also for vacations that started before 7 days and end after 7 days
|
|
$blockers2 = Blocker::whereIn('user_id', $userIdArray)->where('start', '<=', $start)->where('end', '>',
|
|
$start)->get();
|
|
|
|
$blockers = $blockers1->merge($blockers2);
|
|
|
|
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::published()
|
|
->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::published()
|
|
->where('user_id', $parameters['user_id'])
|
|
->where('is_finished', 0)
|
|
->get();
|
|
|
|
return response()->json([
|
|
'subtasks' => SubTaskResource::collection($subtasks),
|
|
], 200);
|
|
}
|
|
|
|
/**
|
|
* Zoznam všetkých konceptov (draftov)
|
|
*/
|
|
private function indexDrafts(Request $request)
|
|
{
|
|
$parameters = $request->query();
|
|
|
|
$query = SubTask::draft()
|
|
->with(['mastertask', 'user', 'timeblocks', 'attachments'])
|
|
->orderBy('created_at', 'desc');
|
|
|
|
// ak je zadané employee_id, filtrovať podľa neho
|
|
// draft sa zobrazuje: 1) creatorovi (user_id) ALEBO 2) zamestnancom v draft_data
|
|
if (isset($parameters['employee_id'])) {
|
|
$employeeId = (int) $parameters['employee_id'];
|
|
$query->where(function ($q) use ($employeeId) {
|
|
// Creator vidí svoje drafty
|
|
$q->where('user_id', $employeeId)
|
|
// Alebo zamestnanec je v draft_data array (hľadáme objekt s daným id)
|
|
->orWhereRaw("JSON_CONTAINS(draft_data, CAST(? AS JSON), '\$')", [json_encode(['id' => $employeeId])]);
|
|
});
|
|
}
|
|
|
|
return response()->json([
|
|
'subtasks' => SubTaskResource::collection($query->get()),
|
|
], 200);
|
|
}
|
|
|
|
public function store($mastertask_id, Request $request)
|
|
{
|
|
// zistenie, či ide o draft
|
|
$isDraft = isset($request->all()['data']['is_draft']) && $request->all()['data']['is_draft'] == true;
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'data.employees' => '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);
|
|
}
|
|
}
|
|
}
|
|
|
|
$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'];
|
|
|
|
foreach ($request->all()['data']['employees'] as $key => $employee) {
|
|
$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'] = $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'] = false;
|
|
}
|
|
|
|
$request->merge($data);
|
|
|
|
$subtasks = $mastertask->subtasks()->createMany($request->all()['data']['employees']);
|
|
|
|
// syncnutie timeblocks
|
|
foreach ($request->all()['data']['employees'] as $key => $employee) {
|
|
if (! isset($data['data']['employees'][$key]['timeblocks']) || $data['data']['employees'][$key]['timeblocks'] == null) {
|
|
continue;
|
|
}
|
|
|
|
if ($data['data']['employees'][$key]['user_id'] == $employee['id']) {
|
|
$subtasks[$key]->syncTimeblocks($data['data']['employees'][$key]['timeblocks']);
|
|
}
|
|
}
|
|
|
|
// upload attachmentu
|
|
if ($request->file('data')) {
|
|
$attachments = Attachment::uploadAttachmentsToS3($request->file('data')['files'], $mastertask);
|
|
}
|
|
|
|
foreach ($subtasks as $subtask) {
|
|
// upload attachmentu
|
|
if ($request->file('data')) {
|
|
$subtask->attachments()->createMany($attachments);
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'Sub Task created successfully',
|
|
'subtasks' => SubTaskResource::collection($subtasks),
|
|
], 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);
|
|
|
|
if (! $subtask) {
|
|
return response()->json([
|
|
'message' => 'Subtask not found.',
|
|
], 404);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// 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,
|
|
'user_id' => $request->all()['data']['employee_id'] ?? $subtask->user_id,
|
|
'estimated_time' => $request->all()['data']['duration'] ?? $subtask->estimated_time,
|
|
], [
|
|
'master_task_id' => 'required',
|
|
'user_id' => 'required',
|
|
'estimated_time' => 'required|numeric|min:0',
|
|
]);
|
|
|
|
if ($publishValidator->fails()) {
|
|
return response()->json([
|
|
'message' => 'Draft cannot be published. Missing required fields.',
|
|
'errors' => $publishValidator->errors(),
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
// Zistíme či ide o draft s viacerými zamestnancami a uložíme employees data pred úpravou requestu
|
|
$employeesData = $request->all()['data']['employees'] ?? null;
|
|
// Draft má viacerých zamestnancov ak: má employees v requeste ALEBO má draft_data v DB
|
|
$hasDraftData = $subtask->is_draft && ($employeesData || $subtask->draft_data);
|
|
$isDraftWithMultipleEmployees = $hasDraftData;
|
|
|
|
// 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
|
|
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'];
|
|
// Pre draft s viacerými zamestnancami: NEMENIME user_id - zostáva na creatorovi
|
|
if ($isDraftWithMultipleEmployees) {
|
|
$data['data']['user_id'] = $subtask->user_id;
|
|
} else {
|
|
$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;
|
|
|
|
// Pre drafty s viacerými zamestnancami: prepočítaj estimated_time zo všetkých employees
|
|
if ($isDraftWithMultipleEmployees && $employeesData) {
|
|
$totalEstimatedTime = 0;
|
|
foreach ($employeesData as $employee) {
|
|
$totalEstimatedTime += $employee['duration'] ?? 0;
|
|
}
|
|
$data['data']['estimated_time'] = $totalEstimatedTime;
|
|
} else {
|
|
$data['data']['estimated_time'] = $request->all()['data']['duration'] ?? $subtask->estimated_time;
|
|
}
|
|
|
|
$data['data']['updated_by'] = User::getUserIdFromBearerToken($request->bearerToken());
|
|
|
|
// publikovanie draftu
|
|
if (isset($request->all()['data']['is_draft'])) {
|
|
$data['data']['is_draft'] = $request->all()['data']['is_draft'];
|
|
}
|
|
|
|
// Odstránime employees z data payloadu aby sa neprepísalo draft_data pri update()
|
|
unset($data['data']['employees']);
|
|
|
|
$request->merge($data);
|
|
|
|
$subtask->update($request->all()['data']);
|
|
|
|
// Pre drafty s employees dátami - aktualizujeme draft_data SEPARÁTNE (po update)
|
|
if ($subtask->is_draft && $employeesData) {
|
|
$subtask->draft_data = $employeesData;
|
|
$subtask->save();
|
|
}
|
|
|
|
// upload attachmentu
|
|
if ($request->file('data')) {
|
|
$attachments = Attachment::uploadAttachmentsToS3($request->file('data')['files'], $subtask->mastertask);
|
|
|
|
$subtask->attachments()->createMany($attachments);
|
|
}
|
|
|
|
// syncnutie vykazu
|
|
if (isset($data['data']['timesheets'])) {
|
|
$subtask->syncTimesheets($data['data']['timesheets']);
|
|
}
|
|
|
|
// syncnutie timeblocks - PRE DRAFTY s viacerými zamestnancami NIE!
|
|
// 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']);
|
|
}
|
|
|
|
$message = $isPublishing ? 'Draft published successfully' : 'Subtask updated successfully';
|
|
|
|
return response()->json([
|
|
'message' => $message,
|
|
'subtask' => new SubTaskResource($subtask),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Publikovanie draftu s viacerými zamestnancami - rozdelí draft na jednotlivé subtasky
|
|
*/
|
|
private function publishDraftWithMultipleEmployees(SubTask $draft, Request $request)
|
|
{
|
|
// 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
|
|
if (empty($employees)) {
|
|
return response()->json([
|
|
'message' => 'Draft cannot be published. No employees data found.',
|
|
], 400);
|
|
}
|
|
|
|
// Validácia a doplnenie duration z timeblocks
|
|
foreach ($employees as $key => $employee) {
|
|
if (! isset($employee['id'])) {
|
|
return response()->json([
|
|
'message' => 'Draft cannot be published. Each employee must have id.',
|
|
], 400);
|
|
}
|
|
|
|
// Ak duration nie je nastavený, vypočítaj ho z timeblocks
|
|
if (! isset($employee['duration']) || $employee['duration'] === null) {
|
|
if (isset($employee['timeblocks']) && ! empty($employee['timeblocks'])) {
|
|
$totalDurationMinutes = 0;
|
|
foreach ($employee['timeblocks'] as $timeblock) {
|
|
if (isset($timeblock['start']) && isset($timeblock['end'])) {
|
|
$start = Carbon::parse($timeblock['start']);
|
|
$end = Carbon::parse($timeblock['end']);
|
|
$totalDurationMinutes += $end->diffInMinutes($start);
|
|
}
|
|
}
|
|
// Konvertuj na hodiny (frontend očakáva hodiny)
|
|
$employees[$key]['duration'] = $totalDurationMinutes / 60;
|
|
} else {
|
|
return response()->json([
|
|
'message' => 'Draft cannot be published. Each employee must have duration or timeblocks.',
|
|
], 400);
|
|
}
|
|
}
|
|
}
|
|
|
|
$mastertask = $draft->mastertask;
|
|
$createdSubtasks = [];
|
|
|
|
// Použijeme transakciu pre atomicitu operácie
|
|
try {
|
|
DB::beginTransaction();
|
|
|
|
// 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;
|
|
|
|
// Najprv nahráme nové súbory z requestu (ak existujú)
|
|
$newAttachments = [];
|
|
if ($request->file('data') && isset($request->file('data')['files'])) {
|
|
$newAttachments = Attachment::uploadAttachmentsToS3($request->file('data')['files'], $mastertask);
|
|
}
|
|
|
|
// Vytvoríme subtask pre každého zamestnanca
|
|
foreach ($employees as $employee) {
|
|
$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([
|
|
'original_name' => $attachment->original_name,
|
|
'disk_name' => $attachment->disk_name,
|
|
'path' => $attachment->path,
|
|
'extension' => $attachment->extension,
|
|
'content_type' => $attachment->content_type,
|
|
'file_size' => $attachment->file_size,
|
|
]);
|
|
}
|
|
|
|
// Pridáme nové attachmenty z requestu
|
|
if (! empty($newAttachments)) {
|
|
$newSubtask->attachments()->createMany($newAttachments);
|
|
}
|
|
|
|
$createdSubtasks[] = $newSubtask;
|
|
}
|
|
|
|
// Zmažeme pôvodný draft
|
|
$draft->timeblocks()->delete();
|
|
$draft->attachments()->delete(); // attachmenty sú už skopírované
|
|
$draft->delete();
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
public function delete($id)
|
|
{
|
|
$subtask = SubTask::find($id);
|
|
|
|
// ak existuje timesheet k subtasku, nemoze sa zmazat (okrem draftov)
|
|
if ($subtask->timesheets()->exists()) {
|
|
if ($subtask->is_draft) {
|
|
// Pre drafty zmazeme timesheety automaticky
|
|
$subtask->timesheets()->delete();
|
|
} else {
|
|
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);
|
|
}
|
|
}
|