feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use App\Models\Admin\AdminPmDailyLogEntry;
|
2025-12-09 21:48:48 +09:00
|
|
|
use App\Models\Admin\AdminPmIssue;
|
|
|
|
|
use App\Models\Admin\AdminPmTask;
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
use App\Services\ProjectManagement\DailyLogService;
|
|
|
|
|
use App\Services\ProjectManagement\ProjectService;
|
|
|
|
|
use Illuminate\View\View;
|
|
|
|
|
|
|
|
|
|
class DailyLogController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function __construct(
|
|
|
|
|
private readonly DailyLogService $dailyLogService,
|
|
|
|
|
private readonly ProjectService $projectService
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 일일 로그 목록 화면
|
|
|
|
|
*/
|
|
|
|
|
public function index(): View
|
|
|
|
|
{
|
|
|
|
|
$tenantId = session('current_tenant_id', 1);
|
|
|
|
|
|
|
|
|
|
$projects = $this->projectService->getActiveProjects();
|
|
|
|
|
$stats = $this->dailyLogService->getStats($tenantId);
|
|
|
|
|
$weeklyTimeline = $this->dailyLogService->getWeeklyTimeline($tenantId);
|
2025-12-04 22:25:50 +09:00
|
|
|
$pendingEntries = $this->dailyLogService->getPendingEntries($tenantId);
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
$assigneeTypes = AdminPmDailyLogEntry::getAssigneeTypes();
|
|
|
|
|
$entryStatuses = AdminPmDailyLogEntry::getStatuses();
|
|
|
|
|
$assignees = $this->dailyLogService->getAssigneeList($tenantId);
|
|
|
|
|
|
2025-12-09 21:48:48 +09:00
|
|
|
// 주의 필요 이슈 조회 (마감초과, 마감임박, 긴급)
|
|
|
|
|
$attentionIssues = $this->getAttentionIssues();
|
|
|
|
|
|
|
|
|
|
// 주의 필요 태스크 조회 (마감초과, 마감임박, 긴급)
|
|
|
|
|
$attentionTasks = $this->getAttentionTasks();
|
|
|
|
|
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
return view('daily-logs.index', compact(
|
|
|
|
|
'projects',
|
|
|
|
|
'stats',
|
|
|
|
|
'weeklyTimeline',
|
2025-12-04 22:25:50 +09:00
|
|
|
'pendingEntries',
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
'assigneeTypes',
|
|
|
|
|
'entryStatuses',
|
2025-12-09 21:48:48 +09:00
|
|
|
'assignees',
|
|
|
|
|
'attentionIssues',
|
|
|
|
|
'attentionTasks'
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-09 21:48:48 +09:00
|
|
|
/**
|
|
|
|
|
* 주의 필요 이슈 조회
|
|
|
|
|
* - 마감일 지난 것 (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(),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원
파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial
라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00
|
|
|
/**
|
|
|
|
|
* 일일 로그 상세 화면
|
|
|
|
|
*/
|
|
|
|
|
public function show(int $id): View
|
|
|
|
|
{
|
|
|
|
|
$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(): View
|
|
|
|
|
{
|
|
|
|
|
$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'
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
}
|