diff --git a/app/Models/Admin/AdminPmProject.php b/app/Models/Admin/AdminPmProject.php index a129bab2..bd9c9737 100644 --- a/app/Models/Admin/AdminPmProject.php +++ b/app/Models/Admin/AdminPmProject.php @@ -151,4 +151,25 @@ public function getIssueStatsAttribute(): array 'closed' => $this->issues()->where('status', AdminPmIssue::STATUS_CLOSED)->count(), ]; } + + /** + * 상태 라벨 (한글) + */ + public function getStatusLabelAttribute(): string + { + return self::getStatuses()[$this->status] ?? $this->status; + } + + /** + * 상태별 색상 클래스 + */ + public function getStatusColorAttribute(): string + { + return match ($this->status) { + self::STATUS_ACTIVE => 'bg-green-100 text-green-800', + self::STATUS_COMPLETED => 'bg-blue-100 text-blue-800', + self::STATUS_ON_HOLD => 'bg-yellow-100 text-yellow-800', + default => 'bg-gray-100 text-gray-800', + }; + } } diff --git a/app/Services/ProjectManagement/ProjectService.php b/app/Services/ProjectManagement/ProjectService.php index 8cb70f7f..52cfc9e2 100644 --- a/app/Services/ProjectManagement/ProjectService.php +++ b/app/Services/ProjectManagement/ProjectService.php @@ -211,7 +211,7 @@ public function changeStatus(int $id, string $status): AdminPmProject */ public function duplicateProject(int $id, ?string $newName = null): AdminPmProject { - $original = AdminPmProject::with('tasks')->findOrFail($id); + $original = AdminPmProject::with(['tasks.issues'])->findOrFail($id); $newProject = $original->replicate(); $newProject->name = $newName ?? $original->name.' (복사본)'; @@ -223,7 +223,7 @@ public function duplicateProject(int $id, ?string $newName = null): AdminPmProje $newProject->updated_at = now(); $newProject->save(); - // 작업 복제 + // 작업 및 이슈 복제 (task_id 매핑 유지) foreach ($original->tasks as $task) { $newTask = $task->replicate(); $newTask->project_id = $newProject->id; @@ -234,8 +234,22 @@ public function duplicateProject(int $id, ?string $newName = null): AdminPmProje $newTask->created_at = now(); $newTask->updated_at = now(); $newTask->save(); + + // 해당 작업의 이슈들 복제 + foreach ($task->issues as $issue) { + $newIssue = $issue->replicate(); + $newIssue->project_id = $newProject->id; + $newIssue->task_id = $newTask->id; + $newIssue->status = AdminPmIssue::STATUS_OPEN; + $newIssue->created_by = auth()->id(); + $newIssue->updated_by = null; + $newIssue->deleted_by = null; + $newIssue->created_at = now(); + $newIssue->updated_at = now(); + $newIssue->save(); + } } - return $newProject->load('tasks'); + return $newProject->load('tasks.issues'); } } diff --git a/resources/views/project-management/index.blade.php b/resources/views/project-management/index.blade.php index a3044382..c838dec6 100644 --- a/resources/views/project-management/index.blade.php +++ b/resources/views/project-management/index.blade.php @@ -45,12 +45,19 @@
@php $taskTotal = $summary['task_stats']['total'] ?: 1; - $donePercent = round(($summary['task_stats']['done'] / $taskTotal) * 100); + $taskDone = $summary['task_stats']['done'] ?? 0; + $taskInProgress = $summary['task_stats']['in_progress'] ?? 0; + $donePercent = round(($taskDone / $taskTotal) * 100); + $inProgressPercent = round((($taskDone + $taskInProgress) / $taskTotal) * 100); @endphp -
-
+
+
+
+
+
+ 진행률 {{ $inProgressPercent }}% + (완료 {{ $donePercent }}% + 진행 {{ $inProgressPercent - $donePercent }}%)
-

완료율 {{ $donePercent }}%

@@ -115,15 +122,25 @@ + @php + $projTaskStats = $project->task_stats; + $projTaskTotal = $projTaskStats['total'] ?? 0; + $projTaskDone = $projTaskStats['done'] ?? 0; + $projTaskInProgress = $projTaskStats['in_progress'] ?? 0; + $projDonePct = $projTaskTotal > 0 ? round(($projTaskDone / $projTaskTotal) * 100) : 0; + $projInProgressPct = $projTaskTotal > 0 ? round((($projTaskDone + $projTaskInProgress) / $projTaskTotal) * 100) : 0; + @endphp
진행률 - {{ $project->progress }}% + {{ $projInProgressPct }}%
-
-
+
+
+
+
+
+ 완료 {{ $projDonePct }}% + 진행 {{ $projInProgressPct - $projDonePct }}%
@@ -131,24 +148,26 @@
작업: - {{ $project->tasks_count ?? 0 }}개 - @php - $taskStats = $project->task_status_counts; - @endphp - @if(!empty($taskStats)) - - (할일 {{ $taskStats['todo'] ?? 0 }} / 진행 {{ $taskStats['in_progress'] ?? 0 }} / 완료 {{ $taskStats['done'] ?? 0 }}) - - @endif + {{ $projTaskTotal }}개 +
+ {{ $projTaskInProgress }} + {{ $projTaskDone }} +
이슈: @php - $openIssues = $project->issues->filter(fn($i) => in_array($i->status, ['open', 'in_progress']))->count(); + $issueStats = $project->issue_stats; + $openIssues = ($issueStats['open'] ?? 0) + ($issueStats['in_progress'] ?? 0); @endphp {{ $openIssues }}개 열림 +
+ {{ $issueStats['open'] ?? 0 }} + {{ $issueStats['in_progress'] ?? 0 }} + {{ $issueStats['resolved'] ?? 0 }} +
diff --git a/resources/views/project-management/projects/partials/table.blade.php b/resources/views/project-management/projects/partials/table.blade.php index 3dc03c04..1825fbbc 100644 --- a/resources/views/project-management/projects/partials/table.blade.php +++ b/resources/views/project-management/projects/partials/table.blade.php @@ -2,21 +2,30 @@ - + - + @forelse($projects as $project) + @php + $taskStats = $project->task_stats; + $issueStats = $project->issue_stats; + $taskTotal = $taskStats['total'] ?? 0; + $taskDone = $taskStats['done'] ?? 0; + $taskInProgress = $taskStats['in_progress'] ?? 0; + $donePct = $taskTotal > 0 ? round(($taskDone / $taskTotal) * 100) : 0; + $inProgressPct = $taskTotal > 0 ? round((($taskDone + $taskInProgress) / $taskTotal) * 100) : 0; + @endphp - - - -
ID# 프로젝트명 상태 진행률 작업 이슈 기간액션액션
- {{ $project->id }} + + {{ $loop->iteration + (($projects->currentPage() - 1) * $projects->perPage()) }} @@ -32,20 +41,47 @@ -
-
-
+
+
+
+ +
+ +
+
+ {{ $inProgressPct }}% +
+
+ {{ $donePct }}% + + + {{ $inProgressPct - $donePct }}%
- {{ $project->progress }}%
- {{ $project->tasks_count ?? 0 }} + +
+ {{ $taskTotal }} +
+ {{ $taskInProgress }} + {{ $taskDone }} +
+
- {{ $project->issues_count ?? 0 }} + + @php + $issueTotal = $issueStats['total'] ?? 0; + $issueOpen = $issueStats['open'] ?? 0; + $issueInProgress = $issueStats['in_progress'] ?? 0; + $issueResolved = $issueStats['resolved'] ?? 0; + @endphp +
+ {{ $issueTotal }} +
+ {{ $issueOpen }} + {{ $issueInProgress }} + {{ $issueResolved }} +
+
@if($project->start_date || $project->end_date) @@ -54,35 +90,56 @@ - @endif + @if($project->deleted_at) - - - + + @if(auth()->user()?->is_super_admin) +
+ + +
+ @else + 삭제됨 + @endif @else - - 보기 - - - 수정 - - - +
+ + + + + + + + + + + + + +
@endif