diff --git a/INDEX.md b/INDEX.md index f3b933c..4eff9f6 100644 --- a/INDEX.md +++ b/INDEX.md @@ -1,7 +1,7 @@ # SAM 문서 인덱스 (Claude Code용) > 작업 유형에 맞는 문서를 먼저 읽고 시작하세요. -> 최종 갱신: 2026-03-07 +> 최종 갱신: 2026-03-11 --- @@ -132,6 +132,7 @@ DB 도메인별: | [sales/README.md](features/sales/README.md) | 영업 관리 | | [documents/README.md](features/documents/README.md) | 문서관리 | | [finance/README.md](features/finance/README.md) | 재무 관리 | +| [finance/payroll.md](features/finance/payroll.md) | 급여관리 (전표 변환, 권한, 멀티테넌트) | | [hr/](features/hr/) | 인사관리 | | [crm/README.md](features/crm/README.md) | CRM | | [esign/README.md](features/esign/README.md) | 전자서명 | diff --git a/features/finance/payroll.md b/features/finance/payroll.md index f5d1498..ff9c6d6 100644 --- a/features/finance/payroll.md +++ b/features/finance/payroll.md @@ -1,66 +1,237 @@ -# 급여관리 (Payroll & Salary) +# 급여관리 (Payroll) -> **최종 갱신**: 2026-02-27 +> **작성일**: 2026-02-27 +> **상태**: 운영 중 +> **최종 갱신**: 2026-03-11 --- ## 1. 개요 -두 가지 급여 모델이 병존한다: -- **Payroll**: 급여대장 (기본급, 수당, 공제 상세, 확정/지급 워크플로우) -- **Salary**: 급여관리 React 연동용 (통계, 내보내기, 상태 일괄 변경) +### 1.1 목적 + +MNG 관리자 페이지(`/hr/payrolls`)에서 월별 급여를 등록/확정/지급하고, 일반전표로 자동 변환하는 시스템이다. + +### 1.2 핵심 원칙 + +- **Payroll 모델** 중심 운영 (Salary 모델은 React 연동용으로 별도 존재) +- 급여 데이터는 MNG에서 관리, DB 마이그레이션은 API에서 관리 +- 법정공제는 자동 계산, 기타공제(`deductions` JSON)는 수기 입력 --- -## 2. 모델 +## 2. 상태 워크플로우 -### Payroll (급여대장) +``` +draft(작성중) ──확정──→ confirmed(확정) ──지급──→ paid(지급완료) + ↑ │ │ + │ 확정취소 지급취소* + │ │ │ + └───────────────────────┘ │ + └───────────────────────────────────────────────┘ + * 슈퍼관리자 전용 +``` -**주요 필드:** user_id, pay_year, pay_month, base_salary, overtime_pay, bonus, allowances(JSON), gross_salary, income_tax, resident_tax, health_insurance, pension, employment_insurance, deductions(JSON), total_deductions, net_salary, status, confirmed_at, paid_at, withdrawal_id +### 2.1 상태별 가능한 작업 -**상태:** draft → confirmed → paid +| 상태 | 일반 사용자 | 슈퍼관리자 | +|------|-----------|-----------| +| `draft` (작성중) | 수정, 삭제, 확정 | 동일 | +| `confirmed` (확정) | 확정취소, 지급처리, 이메일발송 | + **수정** | +| `paid` (지급완료) | 상세보기만 | + **수정**, **지급취소** | -### Salary (급여관리) +### 2.2 슈퍼관리자 예외 (2026-03-11 추가) -**주요 필드:** employee_id, year, month, base_salary, total_allowance, total_overtime, total_bonus, total_deduction, net_payment, allowance_details(JSON), deduction_details(JSON), payment_date, status +- `confirmed`/`paid` 상태에서도 급여 데이터 직접 수정 가능 +- `paid` → `draft` 지급취소: 확정/지급 이력(`confirmed_at`, `paid_at`) 초기화 +- 용도: 수기 입력 오류(기타공제 항목명 오타 등) 수정 후 전표 재생성 --- -## 3. API 엔드포인트 +## 3. 데이터 구조 -### 급여대장 (Payrolls) +### 3.1 payrolls 테이블 주요 필드 -| HTTP | URI | 설명 | -|------|-----|------| -| GET | `/v1/payrolls` | 급여 목록 | -| POST | `/v1/payrolls` | 급여 생성 | -| GET | `/v1/payrolls/summary` | 급여 요약 | -| POST | `/v1/payrolls/calculate` | 급여 계산 | -| POST | `/v1/payrolls/bulk-confirm` | 일괄 확정 | -| GET | `/v1/payrolls/{id}` | 급여 상세 | -| PUT | `/v1/payrolls/{id}` | 급여 수정 | -| DELETE | `/v1/payrolls/{id}` | 급여 삭제 | -| POST | `/v1/payrolls/{id}/confirm` | 확정 | -| POST | `/v1/payrolls/{id}/pay` | 지급 처리 | -| GET | `/v1/payrolls/{id}/payslip` | 급여명세서 조회 | +| 구분 | 필드 | 설명 | +|------|------|------| +| **식별** | `tenant_id`, `user_id`, `pay_year`, `pay_month` | 테넌트/사원/귀속연월 | +| **지급** | `base_salary`, `overtime_pay`, `bonus` | 기본급, 고정연장근로수당, 식대(비과세) | +| **수당** | `allowances` (JSON) | `[{name, amount}, ...]` | +| **총액** | `gross_salary` | 기본급 + 수당 + 식대 합계 | +| **법정공제** | `pension`, `health_insurance`, `long_term_care`, `employment_insurance`, `income_tax`, `resident_tax` | 자동 계산 (수동 override 가능) | +| **기타공제** | `deductions` (JSON) | `[{name, amount}, ...]` 수기 입력 | +| **결과** | `total_deductions`, `net_salary` | 총공제액, 실수령액 | +| **상태** | `status`, `confirmed_at`, `paid_at` | draft/confirmed/paid | -### 급여관리 (Salaries) +### 3.2 기타공제 (deductions JSON) -| HTTP | URI | 설명 | -|------|-----|------| -| GET | `/v1/salaries` | 급여 목록 | -| POST | `/v1/salaries` | 급여 생성 | -| GET | `/v1/salaries/statistics` | 급여 통계 | -| GET | `/v1/salaries/export` | 급여 내보내기 | -| POST | `/v1/salaries/bulk-update-status` | 상태 일괄 변경 | -| GET | `/v1/salaries/{id}` | 급여 상세 | -| PUT | `/v1/salaries/{id}` | 급여 수정 | -| DELETE | `/v1/salaries/{id}` | 급여 삭제 | -| PATCH | `/v1/salaries/{id}/status` | 상태 변경 | +> **경고: `deductions`의 `name`은 수기 입력 데이터다. 오타에 주의해야 한다.** + +```json +[ + {"name": "연말정산 소득세", "amount": -564120}, + {"name": "연말정산 지방소득세", "amount": -120650}, + {"name": "건강보험 퇴직정산", "amount": -41600} +] +``` + +- 양수: 공제 (급여에서 차감) +- 음수: 환급 (급여에 추가) +- **이름이 다르면 전표 변환 시 별도 항목으로 처리됨** (예: "소득세" vs "소득제" → 그룹핑 실패) + +--- + +## 4. 일반전표 변환 + +### 4.1 개요 + +해당 월의 전체 급여를 합산하여 일반전표 1건을 자동 생성한다. + +- 메서드: `PayrollController::generateJournalEntry()` +- `source_type`: `payroll` +- `source_key`: `payroll-{year}-{month}` (중복 생성 불가) +- 전표일자: 해당 월 말일 + +### 4.2 분개 구조 + +| 차/대 | 계정코드 | 계정명 | 거래처 | 금액 | 적요 | +|-------|---------|--------|--------|------|------| +| 차변 | 801 | 급여 | 임직원 | 총지급액 합산 | N월분 급여 | +| 대변 | 207 | 예수금 | 건강보험연금 | 국민연금 합산 | 국민연금 | +| 대변 | 207 | 예수금 | 건강보험건강 | 건강보험 합산 | 건강보험 | +| 대변 | 207 | 예수금 | 건강보험건강 | 장기요양보험 합산 | 장기요양보험 | +| 대변 | 207 | 예수금 | 건강보험고용 | 고용보험 합산 | 고용보험 | +| 대변 | 207 | 예수금 | 강서세무서 | 근로소득세 합산 | N월분 근로소득세 | +| 대변 | 207 | 예수금 | 강서구청 | 지방소득세 합산 | N월분 지방소득세 | +| 대변 | 207 | 예수금 | 임직원 | 기타공제 항목별 | 항목명 | +| 대변 | 205 | 미지급비용 | 임직원 | 실수령액 합산 | N월분 급여 | + +### 4.3 거래처 매핑 (현재 하드코딩) + +| 공제 항목 | 거래처명 | +|----------|---------| +| 국민연금 | 건강보험연금 | +| 건강보험, 장기요양보험 | 건강보험건강 | +| 고용보험 | 건강보험고용 | +| 근로소득세 | 강서세무서 | +| 지방소득세 | 강서구청 | +| 기타공제, 실수령액 | 임직원 | + +### 4.4 음수 공제(환급) 처리 + +- `amount < 0`: 적요에 `"(환급)"` 접미사 추가 +- 대변에 음수 금액으로 표기 (예수금 감소) +- 동일 `거래처+적요` 조합은 병합: `mergeKey = "{partnerName}|{description}"` + +### 4.5 차대 균형 검증 + +전표 저장 전 `총 차변 === 총 대변` 검증. 불일치 시 상세 내역과 함께 에러 반환. + +### 4.6 전표 수정/삭제 + +생성된 전표의 수정/삭제는 **회계관리 > 일반전표입력** 메뉴에서 처리한다. +급여관리에서 전표를 삭제하면 동일 월에 대해 재생성 가능하다. + +--- + +## 5. 권한 체계 + +### 5.1 접근 제어 + +```php +private const ALLOWED_PAYROLL_USERS = ['이의찬', '전진선', '김보곤']; +``` + +급여관리 메뉴 접근은 위 사용자로 제한된다 (`auth()->user()->name` 기준). + +### 5.2 슈퍼관리자 권한 + +`users.is_super_admin = true`인 사용자: +- `confirmed`/`paid` 상태에서 급여 데이터 수정 +- `paid` → `draft` 지급취소 (`unpay`) + +--- + +## 6. MNG API 엔드포인트 + +| Method | URI | 설명 | +|--------|-----|------| +| GET | `/api/admin/hr/payrolls` | 급여 목록 (HTMX 테이블) | +| GET | `/api/admin/hr/payrolls/stats` | 월간 통계 카드 | +| GET | `/api/admin/hr/payrolls/export` | 엑셀 내보내기 | +| POST | `/api/admin/hr/payrolls` | 급여 등록 | +| PUT | `/api/admin/hr/payrolls/{id}` | 급여 수정 | +| DELETE | `/api/admin/hr/payrolls/{id}` | 급여 삭제 | +| POST | `/api/admin/hr/payrolls/{id}/confirm` | 확정 | +| POST | `/api/admin/hr/payrolls/{id}/unconfirm` | 확정 취소 | +| POST | `/api/admin/hr/payrolls/{id}/pay` | 지급 처리 | +| POST | `/api/admin/hr/payrolls/{id}/unpay` | 지급 취소 (슈퍼관리자) | +| POST | `/api/admin/hr/payrolls/bulk-generate` | 재직사원 일괄 생성 | +| POST | `/api/admin/hr/payrolls/copy-from-previous` | 전월 복사 | +| POST | `/api/admin/hr/payrolls/calculate` | 공제 자동 계산 | +| POST | `/api/admin/hr/payrolls/generate-journal-entry` | 일반전표 생성 | +| POST | `/api/admin/hr/payrolls/{id}/send-payslip` | 급여명세서 이메일 (PDF) | +| GET | `/api/admin/hr/payroll-settings` | 급여 설정 조회 | +| PUT | `/api/admin/hr/payroll-settings` | 급여 설정 수정 | + +--- + +## 7. 멀티테넌트 확장 계획 + +> 현재 `tenant_id=1`에서만 운영. 추후 전체 테넌트에 확장 예정. + +### 7.1 확장 시 변경 필요 항목 + +| 항목 | 현재 | 확장 후 | +|------|------|--------| +| 거래처 매핑 | 하드코딩 (`건강보험연금` 등) | 테넌트별 설정 테이블 | +| 계정과목 코드 | 하드코딩 (`801`/`207`/`205`) | 테넌트별 설정 | +| `AccountCode` 조회 | `tenant_id` 필터 없음 | `tenant_id` 필터 추가 필수 | +| 접근 권한 | `ALLOWED_PAYROLL_USERS` (이름 기반) | 역할(Role) 기반 권한 | +| `PayrollSetting` | 이미 테넌트별 분리 가능 | 변경 불필요 | + +### 7.2 거래처/계정과목 설정 방안 + +`PayrollSetting` 또는 별도 설정에 테넌트별 매핑 저장: + +```json +{ + "journal_accounts": { + "salary": "801", + "withholding": "207", + "accrued": "205" + }, + "journal_partners": { + "pension": "건강보험연금", + "health": "건강보험건강", + "employment": "건강보험고용", + "income_tax": "강서세무서", + "resident_tax": "강서구청", + "employee": "임직원" + } +} +``` + +--- + +## 8. 관련 코드 + +| 프로젝트 | 경로 | 설명 | +|---------|------|------| +| MNG | `app/Http/Controllers/Api/Admin/HR/PayrollController.php` | API 컨트롤러 (전표 생성 포함) | +| MNG | `app/Services/HR/PayrollService.php` | 비즈니스 로직 | +| MNG | `app/Models/HR/Payroll.php` | 모델 (상태 헬퍼) | +| MNG | `resources/views/hr/payrolls/` | Blade 뷰 | +| API | `database/migrations/2025_12_18_100001_create_payrolls_table.php` | 테이블 정의 | --- ## 관련 문서 - [재무관리 개요](README.md) -- Swagger: `/api-docs` → Payrolls / Salaries 섹션 +- [DB 스키마 — 인사](../../system/database/hr.md) +- [DB 스키마 — 재무](../../system/database/finance.md) + +--- + +**최종 업데이트**: 2026-03-11