input('date', date('Y-m-d')); $tenantId = session('selected_tenant_id', 1); $log = DailyWorkLog::where('log_date', $date)->first(); if (! $log) { return response()->json([ 'success' => true, 'data' => null, ]); } $items = $log->items()->get()->map(fn ($item) => [ 'id' => $item->id, 'sort_order' => $item->sort_order, 'category' => $item->category ?? '', 'task' => $item->task, 'priority' => $item->priority ?? '', 'is_completed' => $item->is_completed, 'note' => $item->note ?? '', 'highlight' => $item->getOption('highlight', ''), ]); $total = $items->count(); $completed = $items->where('is_completed', true)->count(); return response()->json([ 'success' => true, 'data' => [ 'id' => $log->id, 'log_date' => $log->log_date->format('Y-m-d'), 'memo' => $log->memo ?? '', 'reflection' => $log->reflection ?? '', 'items' => $items->values(), 'achievement_rate' => $total > 0 ? round(($completed / $total) * 100, 2) : 0, ], ]); } /** * 업무일지 저장 (일지 + 항목 일괄) */ public function store(Request $request): JsonResponse { $request->validate([ 'log_date' => 'required|date', 'memo' => 'nullable|string', 'reflection' => 'nullable|string', 'items' => 'nullable|array', 'items.*.category' => 'nullable|string|max:100', 'items.*.task' => 'required|string|max:500', 'items.*.priority' => 'nullable|string|max:50', 'items.*.is_completed' => 'boolean', 'items.*.note' => 'nullable|string|max:500', 'items.*.highlight' => 'nullable|string|max:20', ]); $tenantId = session('selected_tenant_id', 1); $log = DailyWorkLog::updateOrCreate( ['tenant_id' => $tenantId, 'log_date' => $request->input('log_date')], [ 'memo' => $request->input('memo', ''), 'reflection' => $request->input('reflection', ''), 'created_by' => auth()->id(), ] ); // 기존 항목 삭제 후 재생성 $log->items()->forceDelete(); $items = $request->input('items', []); foreach ($items as $i => $itemData) { DailyWorkLogItem::create([ 'tenant_id' => $tenantId, 'daily_work_log_id' => $log->id, 'sort_order' => $i + 1, 'category' => $itemData['category'] ?? '', 'task' => $itemData['task'], 'priority' => $itemData['priority'] ?? '', 'is_completed' => $itemData['is_completed'] ?? false, 'note' => $itemData['note'] ?? '', 'options' => $itemData['highlight'] ? ['highlight' => $itemData['highlight']] : null, ]); } return response()->json([ 'success' => true, 'message' => '저장되었습니다.', ]); } /** * 업무 항목 완료 토글 */ public function toggleItem(int $id): JsonResponse { $item = DailyWorkLogItem::findOrFail($id); $item->update(['is_completed' => ! $item->is_completed]); return response()->json([ 'success' => true, 'is_completed' => $item->is_completed, ]); } /** * 업무일지 삭제 */ public function destroy(int $id): JsonResponse { $log = DailyWorkLog::findOrFail($id); $log->items()->delete(); $log->delete(); return response()->json([ 'success' => true, 'message' => '삭제되었습니다.', ]); } /** * 이전 날짜의 항목 복사 */ public function copyFromPrevious(Request $request): JsonResponse { $request->validate(['date' => 'required|date']); $tenantId = session('selected_tenant_id', 1); $date = $request->input('date'); $prevLog = DailyWorkLog::where('log_date', '<', $date) ->orderByDesc('log_date') ->first(); if (! $prevLog) { return response()->json([ 'success' => false, 'message' => '이전 업무일지가 없습니다.', ]); } $items = $prevLog->items()->get()->map(fn ($item) => [ 'category' => $item->category ?? '', 'task' => $item->task, 'priority' => $item->priority ?? '', 'is_completed' => false, 'note' => '', 'highlight' => $item->getOption('highlight', ''), ]); return response()->json([ 'success' => true, 'data' => [ 'source_date' => $prevLog->log_date->format('Y-m-d'), 'items' => $items->values(), ], ]); } }