diff --git a/sam/docs/plans/attendance-management-plan.md b/sam/docs/plans/attendance-management-plan.md new file mode 100644 index 0000000..c5f8889 --- /dev/null +++ b/sam/docs/plans/attendance-management-plan.md @@ -0,0 +1,284 @@ +# MNG 근태현황 개발 계획서 + +> **작성일**: 2026-02-26 +> **상태**: 계획 수립 + +--- + +## 1. 개요 + +### 1.1 목적 + +MNG 인사관리 > 근태현황 기능을 완성한다. 현재 기본 CRUD가 구현되어 있으나, 미완성 기능과 알려진 버그를 해결하고 실무에 필요한 추가 기능을 구현한다. + +### 1.2 현재 상태 분석 + +#### 구현 완료 + +| 항목 | 상태 | 파일 | +|------|------|------| +| 근태 목록 조회 (HTMX 테이블) | ✅ | `index.blade.php`, `table.blade.php` | +| 월간 통계 카드 (5종) | ✅ | `index.blade.php` | +| 필터 (이름, 부서, 상태, 날짜) | ✅ | `index.blade.php` | +| 등록/수정 모달 | ✅ | `index.blade.php` | +| CRUD API (목록/등록/수정/삭제) | ✅ | `AttendanceController.php` (API) | +| AttendanceService | ✅ | `AttendanceService.php` | +| Attendance 모델 (8개 상태) | ✅ | `Attendance.php` | +| Soft Delete | ✅ | 모델 + 서비스 | + +#### 알려진 문제 (E2E 테스트 결과) + +| 문제 | 심각도 | 설명 | +|------|--------|------| +| 엑셀 다운로드 미구현 | 🟡 중요 | 버튼 없음, API 미연결 | +| 근태 등록 서버 에러 | 🔴 필수 | 모달 submit 시 500 에러 발생 가능 | + +#### 미구현 기능 (API 대비) + +| 기능 | API 지원 | MNG 상태 | +|------|---------|---------| +| 엑셀 내보내기 | ✅ `/v1/attendances/export` | ❌ 미구현 | +| 일괄 삭제 | ✅ `/v1/attendances/bulk-delete` | ❌ 미구현 | +| 개인별 근태 상세 | ✅ `/v1/attendances/{id}` | ❌ 미구현 | +| 월간 요약 통계 | ✅ `/v1/attendances/monthly-stats` | ⚠️ 기본만 구현 | +| 출퇴근 설정 관리 | ✅ `attendance_settings` 테이블 | ❌ 미구현 | + +--- + +## 2. 구현 범위 + +### 2.1 Phase 1: 버그 수정 + 핵심 기능 (우선) + +| # | 작업 | 난이도 | 설명 | +|---|------|--------|------| +| 1-1 | 근태 등록/수정 버그 수정 | 🟢 낮음 | store/update API 요청 오류 점검 및 수정 | +| 1-2 | 엑셀 다운로드 | 🟢 낮음 | API `/v1/attendances/export` 연동, 다운로드 버튼 추가 | +| 1-3 | 일괄 삭제 | 🟡 보통 | 체크박스 선택 → 일괄 삭제 버튼 | +| 1-4 | 월간 통계 기간 선택 | 🟢 낮음 | 현재 당월 고정 → 연/월 선택 가능하게 | + +### 2.2 Phase 2: 확장 기능 + +| # | 작업 | 난이도 | 설명 | +|---|------|--------|------| +| 2-1 | 개인별 근태 상세 페이지 | 🟡 보통 | 사원 클릭 → 월간 달력 + 출퇴근 이력 | +| 2-2 | 출퇴근 설정 관리 | 🟡 보통 | 표준 출근시간, GPS 사용여부, 허용반경 설정 | +| 2-3 | 월간/주간 요약 뷰 | 🟡 보통 | 부서별/사원별 근태 요약 테이블 | +| 2-4 | 근태 일괄 등록 | 🔴 높음 | 날짜 범위 + 대상 사원 → 일괄 근태 등록 | + +--- + +## 3. 상세 설계 + +### 3.1 Phase 1-1: 근태 등록/수정 버그 수정 + +**점검 항목**: +- MNG `AttendanceController::store()` validation 규칙과 실제 폼 데이터 일치 여부 +- `check_in`, `check_out` 포맷 (HH:MM vs HH:MM:SS) 불일치 가능성 +- `user_id` 전달 누락 여부 +- HTMX `hx-headers` CSRF 토큰 전달 확인 + +**수정 대상 파일**: +- `mng/app/Http/Controllers/Api/Admin/HR/AttendanceController.php` +- `mng/resources/views/hr/attendances/index.blade.php` (JS `submitAttendance()`) + +--- + +### 3.2 Phase 1-2: 엑셀 다운로드 + +**방식**: MNG에서 직접 엑셀 생성 (API 서버 미경유) + +**구현**: +1. `AttendanceService::getExportData()` 메서드 추가 +2. `AttendanceController::export()` 메서드 추가 +3. 라우트: `GET /api/admin/hr/attendances/export` +4. 인덱스 페이지에 다운로드 버튼 추가 + +**엑셀 컬럼**: + +| 컬럼 | 값 | +|------|-----| +| 날짜 | `base_date` | +| 사원명 | `user.name` | +| 부서 | `department.name` | +| 상태 | `status_label` | +| 출근 | `check_in` | +| 퇴근 | `check_out` | +| 비고 | `remarks` | + +**수정 대상 파일**: +- `mng/app/Services/HR/AttendanceService.php` +- `mng/app/Http/Controllers/Api/Admin/HR/AttendanceController.php` +- `mng/routes/api.php` +- `mng/resources/views/hr/attendances/index.blade.php` + +--- + +### 3.3 Phase 1-3: 일괄 삭제 + +**UI**: 테이블 각 행에 체크박스 추가, 헤더에 전체선택, 상단에 "선택 삭제" 버튼 + +**구현**: +1. `table.blade.php`에 체크박스 컬럼 추가 +2. Alpine.js 컴포넌트로 선택 상태 관리 +3. `AttendanceController::bulkDestroy()` 메서드 추가 +4. 라우트: `POST /api/admin/hr/attendances/bulk-delete` + +**수정 대상 파일**: +- `mng/resources/views/hr/attendances/partials/table.blade.php` +- `mng/resources/views/hr/attendances/index.blade.php` +- `mng/app/Http/Controllers/Api/Admin/HR/AttendanceController.php` +- `mng/app/Services/HR/AttendanceService.php` +- `mng/routes/api.php` + +--- + +### 3.4 Phase 1-4: 월간 통계 기간 선택 + +**현재**: 당월 통계만 표시 (하드코딩) +**변경**: 연/월 드롭다운 추가 → 선택 시 통계 카드 HTMX 갱신 + +**구현**: +1. 통계 카드 영역을 별도 partial로 분리 (`partials/stats.blade.php`) +2. 연/월 선택 UI 추가 +3. `hx-get` + `hx-vals`로 선택된 연/월 전달 +4. `stats()` API가 `year`, `month` 파라미터 이미 지원 + +**수정 대상 파일**: +- `mng/resources/views/hr/attendances/index.blade.php` +- `mng/resources/views/hr/attendances/partials/stats.blade.php` (신규) + +--- + +### 3.5 Phase 2-1: 개인별 근태 상세 페이지 + +**URL**: `/hr/attendances/{userId}` + +**페이지 구성**: +1. **사원 프로필 카드**: 이름, 부서, 직급, 재직상태 +2. **월간 달력**: 날짜별 근태 상태를 색상 도트로 표시 +3. **월간 통계**: 정시출근 N일, 지각 N일, 결근 N일 등 +4. **출퇴근 이력 테이블**: 해당 월의 상세 출퇴근 기록 + +**수정 대상 파일**: +- `mng/routes/web.php` (라우트 추가) +- `mng/app/Http/Controllers/HR/AttendanceController.php` (`show()` 추가) +- `mng/app/Services/HR/AttendanceService.php` (`getUserMonthlyAttendances()` 추가) +- `mng/resources/views/hr/attendances/show.blade.php` (신규) + +--- + +### 3.6 Phase 2-2: 출퇴근 설정 관리 + +**URL**: `/hr/attendance-settings` + +**설정 항목** (`attendance_settings` 테이블 기반): + +| 항목 | 필드 | 설명 | +|------|------|------| +| GPS 출퇴근 사용 | `use_gps` | on/off 토글 | +| 자동 출퇴근 | `use_auto` | on/off 토글 | +| 허용 반경 | `allowed_radius` | 미터 단위 입력 | +| 본사 주소 | `hq_address` | 주소 입력 | +| 본사 위도/경도 | `hq_latitude`, `hq_longitude` | 좌표 입력 | + +**수정 대상 파일**: +- `mng/routes/web.php`, `mng/routes/api.php` +- `mng/app/Http/Controllers/HR/AttendanceSettingController.php` (신규) +- `mng/app/Models/HR/AttendanceSetting.php` (신규 — API 모델 미러링) +- `mng/resources/views/hr/attendance-settings/index.blade.php` (신규) + +--- + +## 4. 데이터 흐름 + +### 4.1 MNG 자체 CRUD 패턴 (현재) + +``` +브라우저 ──HTMX──→ MNG API Controller ──→ MNG Service ──→ DB (직접) + (api/admin/hr/attendances) +``` + +> MNG는 API 서버를 경유하지 않고 DB에 직접 접근한다. + +### 4.2 엑셀 다운로드 흐름 + +``` +브라우저 ──GET──→ MNG AttendanceController::export() + → AttendanceService::getExportData() + → ExportService::download() (라라벨 엑셀) + ← BinaryFileResponse (.xlsx) +``` + +--- + +## 5. 구현 순서 및 의존 관계 + +``` +Phase 1 (버그 수정 + 핵심) + 1-1 버그 수정 ─────────────────────────────┐ + 1-2 엑셀 다운로드 ─────────────────────────┤ 독립적, 병렬 가능 + 1-3 일괄 삭제 ─────────────────────────────┤ + 1-4 통계 기간 선택 ────────────────────────┘ + +Phase 2 (확장) + 2-1 개인별 상세 ───→ 2-3 월간/주간 요약 (데이터 재사용) + 2-2 출퇴근 설정 ─── 독립적 + 2-4 일괄 등록 ───── 독립적 +``` + +--- + +## 6. 관련 파일 목록 + +### MNG 프로젝트 (`/home/aweso/sam/mng`) + +| 파일 | 역할 | +|------|------| +| `app/Models/HR/Attendance.php` | 모델 (8개 상태, json_details) | +| `app/Services/HR/AttendanceService.php` | 비즈니스 로직 | +| `app/Http/Controllers/HR/AttendanceController.php` | 뷰 컨트롤러 | +| `app/Http/Controllers/Api/Admin/HR/AttendanceController.php` | API 컨트롤러 | +| `resources/views/hr/attendances/index.blade.php` | 메인 페이지 | +| `resources/views/hr/attendances/partials/table.blade.php` | 테이블 partial | +| `routes/web.php` | 웹 라우트 | +| `routes/api.php` | API 라우트 | + +### API 프로젝트 (`/home/aweso/sam/api`) + +| 파일 | 역할 | +|------|------| +| `database/migrations/2025_12_09_*_attendances*` | 마이그레이션 (2개) | +| `database/migrations/2025_12_17_*_attendance_settings*` | 설정 테이블 | +| `app/Models/Tenants/Attendance.php` | API 모델 (참조용) | +| `app/Models/Tenants/AttendanceSetting.php` | 설정 모델 (참조용) | + +### 참조 문서 + +| 문서 | 경로 | +|------|------| +| 근태 API 규칙 | `docs/rules/attendance-api.md` | +| GPS 출퇴근 스펙 | `docs/specs/erp-analysis/03-gps-attendance.md` | + +--- + +## 7. 검증 방법 + +### Phase 1 체크리스트 + +- [ ] 근태 등록 모달 → 사원 선택 + 날짜 + 상태 입력 → 저장 성공 +- [ ] 근태 수정 모달 → 기존 데이터 로드 → 수정 → 저장 성공 +- [ ] 동일 사원/날짜 중복 등록 시 기존 데이터 업데이트 (Upsert) +- [ ] 엑셀 다운로드 버튼 클릭 → .xlsx 파일 다운로드 +- [ ] 체크박스 선택 → 일괄 삭제 → 테이블 갱신 +- [ ] 연/월 선택 → 통계 카드 갱신 + +### Phase 2 체크리스트 + +- [ ] 사원 이름 클릭 → 개인별 상세 페이지 이동 +- [ ] 달력에 근태 상태 색상 표시 +- [ ] 출퇴근 설정 페이지 → GPS/자동 토글 → 저장 +- [ ] 허용 반경 변경 → 저장 → DB 반영 + +--- + +**최종 업데이트**: 2026-02-26