header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('daily-logs.index')); } $tenantId = session('current_tenant_id', 1); $projects = $this->projectService->getActiveProjects(); $stats = $this->dailyLogService->getStats($tenantId); $weeklyTimeline = $this->dailyLogService->getWeeklyTimeline($tenantId); $pendingEntries = $this->dailyLogService->getPendingEntries($tenantId); $assigneeTypes = AdminPmDailyLogEntry::getAssigneeTypes(); $entryStatuses = AdminPmDailyLogEntry::getStatuses(); $assignees = $this->dailyLogService->getAssigneeList($tenantId); // 주의 필요 이슈 조회 (마감초과, 마감임박, 긴급) $attentionIssues = $this->getAttentionIssues(); // 주의 필요 태스크 조회 (마감초과, 마감임박, 긴급) $attentionTasks = $this->getAttentionTasks(); return view('daily-logs.index', compact( 'projects', 'stats', 'weeklyTimeline', 'pendingEntries', 'assigneeTypes', 'entryStatuses', 'assignees', 'attentionIssues', 'attentionTasks' )); } /** * 주의 필요 이슈 조회 * - 마감일 지난 것 (overdue) * - 이번 주 마감 예정 (이번 주 월~일) * - 긴급 표시된 것 */ private function getAttentionIssues(): array { $today = now()->startOfDay(); $weekEnd = now()->endOfWeek(); // 이번 주 일요일 $issues = AdminPmIssue::with(['project', 'assignee', 'department']) ->whereIn('status', [AdminPmIssue::STATUS_OPEN, AdminPmIssue::STATUS_IN_PROGRESS]) ->where(function ($q) use ($today, $weekEnd) { // 마감일 지난 것 (overdue) $q->where(function ($q2) use ($today) { $q2->whereNotNull('due_date') ->where('due_date', '<', $today); }) // 이번 주 마감 예정 ->orWhere(function ($q2) use ($today, $weekEnd) { $q2->whereNotNull('due_date') ->whereBetween('due_date', [$today, $weekEnd]); }) // 긴급 표시 ->orWhere('is_urgent', true); }) ->orderByRaw('CASE WHEN due_date < CURDATE() THEN 0 ELSE 1 END') // 마감초과 우선 ->orderBy('is_urgent', 'desc') ->orderBy('due_date') ->get(); return [ 'items' => $issues, 'overdue_count' => $issues->filter(fn ($i) => $i->due_status === 'overdue')->count(), 'due_soon_count' => $issues->filter(fn ($i) => $i->due_status === 'due_soon' || ($i->due_date && $i->due_date->lte($weekEnd) && $i->due_date->gte($today)))->count(), 'urgent_count' => $issues->filter(fn ($i) => $i->is_urgent)->count(), ]; } /** * 주의 필요 태스크 조회 * - 마감일 지난 것 (overdue) * - 이번 주 마감 예정 (이번 주 월~일) * - 긴급 표시된 것 */ private function getAttentionTasks(): array { $today = now()->startOfDay(); $weekEnd = now()->endOfWeek(); // 이번 주 일요일 $tasks = AdminPmTask::with(['project', 'assignee']) ->where('status', '!=', AdminPmTask::STATUS_DONE) ->where(function ($q) use ($today, $weekEnd) { // 마감일 지난 것 (overdue) $q->where(function ($q2) use ($today) { $q2->whereNotNull('due_date') ->where('due_date', '<', $today); }) // 이번 주 마감 예정 ->orWhere(function ($q2) use ($today, $weekEnd) { $q2->whereNotNull('due_date') ->whereBetween('due_date', [$today, $weekEnd]); }) // 긴급 표시 ->orWhere('is_urgent', true); }) ->orderByRaw('CASE WHEN due_date < CURDATE() THEN 0 ELSE 1 END') ->orderBy('is_urgent', 'desc') ->orderBy('due_date') ->get(); return [ 'items' => $tasks, 'overdue_count' => $tasks->filter(fn ($t) => $t->due_status === 'overdue')->count(), 'due_soon_count' => $tasks->filter(fn ($t) => $t->due_date && $t->due_date->lte($weekEnd) && $t->due_date->gte($today))->count(), 'urgent_count' => $tasks->filter(fn ($t) => $t->is_urgent)->count(), ]; } /** * 일일 로그 상세 화면 */ public function show(Request $request, int $id): View|Response { // HTMX 요청 시 전체 페이지 리로드 if ($request->header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('daily-logs.show', $id)); } $tenantId = session('current_tenant_id', 1); $log = $this->dailyLogService->getDailyLogById($id, true); if (! $log) { abort(404, '일일 로그를 찾을 수 없습니다.'); } $projects = $this->projectService->getActiveProjects(); $assigneeTypes = AdminPmDailyLogEntry::getAssigneeTypes(); $entryStatuses = AdminPmDailyLogEntry::getStatuses(); $assignees = $this->dailyLogService->getAssigneeList($tenantId); return view('daily-logs.show', compact( 'log', 'projects', 'assigneeTypes', 'entryStatuses', 'assignees' )); } /** * 오늘 날짜 로그 화면 (자동 생성) */ public function today(Request $request): View|Response { // HTMX 요청 시 전체 페이지 리로드 if ($request->header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('daily-logs.today')); } $tenantId = session('current_tenant_id', 1); $today = now()->format('Y-m-d'); $log = $this->dailyLogService->getOrCreateByDate($tenantId, $today); $projects = $this->projectService->getActiveProjects(); $assigneeTypes = AdminPmDailyLogEntry::getAssigneeTypes(); $entryStatuses = AdminPmDailyLogEntry::getStatuses(); $assignees = $this->dailyLogService->getAssigneeList($tenantId); return view('daily-logs.show', compact( 'log', 'projects', 'assigneeTypes', 'entryStatuses', 'assignees' )); } }