Files
sam-docs/frontend/api-specs/payroll-api.md
김보곤 e83954eddd docs: [payroll] 급여관리 API 프론트엔드 연동 명세서 추가
- 18개 엔드포인트 전체 명세 (CRUD, 상태변경, 일괄생성, 미리보기 등)
- 4대보험/근로소득세 계산 엔진 설명
- 상태 흐름도 (draft → confirmed → paid)
- 프론트엔드 구현 가이드 및 UI 와이어프레임
- INDEX.md에 문서 등록
2026-03-11 19:30:00 +09:00

31 KiB
Raw Blame History

급여관리 API 명세

작성일: 2026-03-11 상태: 개발 완료 (API 배포됨) Base URL: api.codebridge-x.com (운영) / api.dev.codebridge-x.com (개발)


1. 개요

월별 급여를 등록/확정/지급하고, 4대보험과 근로소득세를 자동 계산하는 급여관리 API이다.

1.1 인증

모든 요청에 다음 헤더가 필요하다:

X-API-KEY: {api_key}
Authorization: Bearer {token}

1.2 공통 응답 형식

{
  "success": true,
  "message": "조회 성공",
  "data": { ... }
}

에러 시:

{
  "success": false,
  "message": "에러 메시지"
}

1.3 엔드포인트 요약

# Method Path 설명
1 GET /api/v1/payrolls 급여 목록 (페이지네이션)
2 POST /api/v1/payrolls 급여 등록
3 GET /api/v1/payrolls/summary 월간 요약 통계
4 POST /api/v1/payrolls/calculate 급여 일괄 계산 (draft 재계산)
5 POST /api/v1/payrolls/calculate-preview 계산 미리보기 (저장 안 함)
6 POST /api/v1/payrolls/bulk-confirm 일괄 확정
7 POST /api/v1/payrolls/bulk-generate 재직사원 일괄 생성
8 POST /api/v1/payrolls/copy-from-previous 전월 급여 복사
9 GET /api/v1/payrolls/{id} 급여 상세
10 PUT /api/v1/payrolls/{id} 급여 수정
11 DELETE /api/v1/payrolls/{id} 급여 삭제
12 POST /api/v1/payrolls/{id}/confirm 확정
13 POST /api/v1/payrolls/{id}/unconfirm 확정 취소
14 POST /api/v1/payrolls/{id}/pay 지급 처리
15 POST /api/v1/payrolls/{id}/unpay 지급 취소 (슈퍼관리자)
16 GET /api/v1/payrolls/{id}/payslip 급여명세서 조회
17 GET /api/v1/payrolls/settings 급여 설정 조회
18 PUT /api/v1/payrolls/settings 급여 설정 수정

2. 상태 흐름도

┌────────────────┐
│  draft (작성중) │
└───┬──────┬─────┘
    │      ▲
    │ confirm  │ unconfirm
    ▼      │
┌────────────────┐
│confirmed (확정) │
└───┬──────┬─────┘
    │      ▲
    │ pay      │ unpay*
    ▼      │
┌────────────────┐
│  paid (지급완료)│
└────────────────┘

* unpay는 슈퍼관리자 전용 (paid → draft 초기화)

2.1 상태값

상태 설명 UI 배지 색상
작성중 draft 수정/삭제/확정 가능 gray
확정 confirmed 확정취소/지급 가능 blue
지급완료 paid 상세보기만 가능 green

2.2 상태별 가능한 작업

상태 일반 사용자 슈퍼관리자
draft 수정, 삭제, 확정, 일괄계산 동일
confirmed 확정취소, 지급처리 + 수정
paid 상세보기만 + 수정, 지급취소

3. 급여 계산 엔진

3.1 과세표준

과세표준 = 총지급액(gross_salary) - 식대(bonus)
  • bonus 필드는 식대(비과세) 항목이다
  • 4대보험과 세금은 과세표준 기준으로 계산한다

3.2 4대보험 자동 계산

항목 계산식 기본 요율 비고
건강보험 과세표준 × 3.545% 3.545% 10원 단위 절삭
장기요양보험 건강보험료 × 0.9082% 0.9082% 건강보험료 기준, 10원 단위 절삭
국민연금 과세표준 × 4.5% 4.5% 상한 590만 / 하한 37만 적용
고용보험 과세표준 × 0.9% 0.9% 10원 단위 절삭

모든 보험료는 10원 단위 절삭 (floor to nearest 10)

3.3 근로소득세

  • 770천원 미만: 0원
  • 770~10,000천원: 간이세액표(DB) 조회 (연도, 월급여 천원단위, 가족수)
  • 10,000천원 초과: 공식 계산 (소득세법 시행령 별표2)

3.4 지방소득세

지방소득세 = 근로소득세 × 10% (10원 단위 절삭)

3.5 가족수 (공제대상가족수)

  • 기본: 본인 1인
  • TenantUserProfile의 json_extra.dependents 배열에서 is_dependent: true인 수만큼 추가
  • 범위: 최소 1, 최대 11

3.6 요율 설정

요율은 payroll_settings 테이블에서 테넌트별로 관리한다. 기본값은 위 표와 동일하며, 설정 API(17, 18번)를 통해 변경 가능하다.


4. 데이터 모델

4.1 Payroll 객체

{
  "id": 1,
  "tenant_id": 1,
  "user_id": 5,
  "pay_year": 2026,
  "pay_month": 3,
  "base_salary": "3500000",
  "overtime_pay": "0",
  "bonus": "200000",
  "allowances": [
    {"name": "직책수당", "amount": 300000},
    {"name": "교통비", "amount": 100000}
  ],
  "gross_salary": "4100000",
  "income_tax": "117750",
  "resident_tax": "11770",
  "health_insurance": "138220",
  "long_term_care": "1250",
  "pension": "175500",
  "employment_insurance": "35100",
  "deductions": [
    {"name": "대출상환", "amount": 500000}
  ],
  "options": null,
  "total_deductions": "979590",
  "net_salary": "3120410",
  "status": "draft",
  "confirmed_at": null,
  "confirmed_by": null,
  "paid_at": null,
  "withdrawal_id": null,
  "note": null,
  "created_by": 1,
  "updated_by": 1,
  "created_at": "2026-03-11T10:00:00.000000Z",
  "updated_at": "2026-03-11T10:00:00.000000Z",
  "user": {
    "id": 5,
    "name": "홍길동",
    "email": "hong@example.com"
  },
  "creator": {
    "id": 1,
    "name": "관리자"
  }
}

4.2 필드 설명

지급 항목:

필드 타입 설명
base_salary decimal(0) 기본급
overtime_pay decimal(0) 고정연장근로수당
bonus decimal(0) 식대 (비과세)
allowances json 추가 수당 [{name, amount}]
gross_salary decimal(0) 총지급액 (자동 계산)

법정 공제 항목 (자동 계산):

필드 타입 설명
income_tax decimal(0) 근로소득세
resident_tax decimal(0) 지방소득세
health_insurance decimal(0) 건강보험료
long_term_care decimal(0) 장기요양보험료
pension decimal(0) 국민연금
employment_insurance decimal(0) 고용보험료

기타 공제:

필드 타입 설명
deductions json 기타공제 [{name, amount}]

결과:

필드 타입 설명
total_deductions decimal(0) 총공제액 (법정 + 기타)
net_salary decimal(0) 실수령액 = gross - total_deductions

상태:

필드 타입 설명
status string draft / confirmed / paid
confirmed_at datetime 확정 일시
confirmed_by int 확정자 user_id
paid_at datetime 지급 일시
withdrawal_id int 연결된 출금 ID

5. API 상세

5.1 급여 목록 조회

GET /api/v1/payrolls

Query Parameters:

파라미터 타입 필수 설명 예시
year int - 귀속연도 2026
month int - 귀속월 3
user_id int - 사원 ID 5
status string - 상태 필터 draft
department_id int - 부서 필터 2
search string - 사원명 검색 홍길동
sort_by string - 정렬 기준 (기본: pay_year) net_salary
sort_dir string - 정렬 방향 (기본: desc) asc
per_page int - 페이지당 건수 (기본: 20) 50
page int - 페이지 번호 1

응답 (200):

{
  "success": true,
  "message": "조회 성공",
  "data": {
    "current_page": 1,
    "data": [
      {
        "id": 1,
        "user_id": 5,
        "pay_year": 2026,
        "pay_month": 3,
        "base_salary": "3500000",
        "gross_salary": "4100000",
        "total_deductions": "979590",
        "net_salary": "3120410",
        "status": "draft",
        "user": {"id": 5, "name": "홍길동", "email": "hong@example.com"},
        "creator": {"id": 1, "name": "관리자"}
      }
    ],
    "per_page": 20,
    "total": 15,
    "last_page": 1
  }
}

프론트엔드 참고:

  • 연월을 선택하는 UI를 제공하면 year + month 필터 사용
  • sort_by=period 전달 시 pay_year + pay_month 복합 정렬

5.2 급여 등록

POST /api/v1/payrolls

Request Body:

{
  "user_id": 5,
  "pay_year": 2026,
  "pay_month": 3,
  "base_salary": 3500000,
  "overtime_pay": 0,
  "bonus": 200000,
  "allowances": [
    {"name": "직책수당", "amount": 300000}
  ],
  "deductions": [
    {"name": "대출상환", "amount": 500000}
  ],
  "family_count": 3,
  "deduction_overrides": {
    "income_tax": 100000,
    "pension": 170000
  },
  "note": "메모"
}

필드 규칙:

필드 타입 필수 설명
user_id int 급여 대상 사원 ID
pay_year int 귀속연도 (2000~2100)
pay_month int 귀속월 (1~12)
base_salary numeric 기본급 (0 이상)
overtime_pay numeric - 고정연장근로수당
bonus numeric - 식대 (비과세)
allowances array - 추가수당 [{name, amount}]
deductions array - 기타공제 [{name, amount}]
family_count int - 공제대상가족수 (1~11, 미전달 시 자동)
deduction_overrides object - 법정공제 수동 입력 (아래 참고)
note string - 메모 (최대 1000자)

deduction_overrides 필드:

자동 계산된 법정 공제 항목을 수동으로 덮어쓸 때 사용한다. 지정한 항목만 덮어쓰고, 나머지는 자동 계산값을 유지한다.

{
  "income_tax": 100000,
  "resident_tax": 10000,
  "health_insurance": 140000,
  "long_term_care": 1300,
  "pension": 170000,
  "employment_insurance": 35000
}

응답 (201):

{
  "success": true,
  "message": "등록 성공",
  "data": { /* Payroll 객체 (4.1 참고) */ }
}

에러:

상황 응답 코드 메시지
동일 연월+사원 중복 400 해당 연월에 이미 급여가 등록되어 있습니다.
검증 실패 422 요청 데이터 검증에 실패했습니다.

5.3 월간 요약 통계

GET /api/v1/payrolls/summary?year=2026&month=3

Query Parameters:

파라미터 타입 필수 기본값
year int - 현재 연도
month int - 현재 월

응답 (200):

{
  "success": true,
  "message": "조회 성공",
  "data": {
    "year": 2026,
    "month": 3,
    "total_count": 15,
    "draft_count": 3,
    "confirmed_count": 7,
    "paid_count": 5,
    "total_gross": 62500000,
    "total_deductions": 15800000,
    "total_net": 46700000
  }
}

프론트엔드 참고:

  • 대시보드 카드에 total_count, total_gross, total_net 표시
  • 상태별 카운트로 진행 상태 게이지 표현 가능

5.4 급여 일괄 계산

기존 draft 상태 급여의 공제 항목을 재계산한다.

POST /api/v1/payrolls/calculate

Request Body:

{
  "year": 2026,
  "month": 3,
  "user_ids": [5, 8, 12]
}
필드 타입 필수 설명
year int 대상 연도
month int 대상 월
user_ids array - 특정 사원만 지정 (미전달 시 전체)

응답 (200):

{
  "success": true,
  "message": "급여가 일괄 계산되었습니다.",
  "data": [
    { /* 재계산된 Payroll 객체들 */ }
  ]
}

주의: confirmed/paid 상태 급여는 재계산하지 않는다 (draft만 대상).


5.5 계산 미리보기

급여 데이터를 저장하지 않고 계산 결과만 미리 확인한다. 급여 등록/수정 폼에서 실시간 미리보기용.

POST /api/v1/payrolls/calculate-preview

Request Body:

{
  "user_id": 5,
  "base_salary": 3500000,
  "overtime_pay": 0,
  "bonus": 200000,
  "allowances": [
    {"name": "직책수당", "amount": 300000}
  ],
  "deductions": [
    {"name": "대출상환", "amount": 500000}
  ]
}

응답 (200):

{
  "success": true,
  "message": "계산 완료",
  "data": {
    "gross_salary": 4100000,
    "taxable_base": 3900000,
    "income_tax": 117750,
    "resident_tax": 11770,
    "health_insurance": 138220,
    "long_term_care": 1250,
    "pension": 175500,
    "employment_insurance": 35100,
    "total_deductions": 979590,
    "net_salary": 3120410,
    "family_count": 3
  }
}

프론트엔드 참고:

  • user_id를 전달하면 해당 사원의 가족수를 자동 반영
  • user_id 미전달 시 가족수 1로 계산
  • 폼 입력값이 변경될 때마다 호출하여 실시간 계산 결과를 표시 (debounce 300ms 권장)

5.6 일괄 확정

해당 월의 모든 draft 급여를 한 번에 confirmed로 변경한다.

POST /api/v1/payrolls/bulk-confirm

Request Body:

{
  "year": 2026,
  "month": 3
}

응답 (200):

{
  "success": true,
  "message": "급여가 일괄 확정되었습니다.",
  "data": {
    "count": 12
  }
}

5.7 재직사원 일괄 생성

해당 연월에 재직 중인(employee_status=active) 모든 사원의 급여를 자동 생성한다.

POST /api/v1/payrolls/bulk-generate

Request Body:

{
  "year": 2026,
  "month": 3
}

응답 (200):

{
  "success": true,
  "message": "급여가 일괄 생성되었습니다.",
  "data": {
    "created": 12,
    "skipped": 3
  }
}

동작 설명:

  • 사원별 연봉 정보(json_extra.salary_info.annual_salary)에서 ÷12로 월 기본급 산출
  • 이미 존재하는 사원은 skipped 처리 (중복 생성하지 않음)
  • 연봉 정보가 없는 사원도 기본급 0으로 생성됨
  • 모든 급여는 draft 상태로 생성됨

프론트엔드 참고:

  • 매월 초에 "일괄 생성" 버튼을 눌러 해당 월 급여를 초기화
  • created/skipped 결과를 토스트 메시지로 표시

5.8 전월 급여 복사

전월 급여 데이터를 현재 월로 복사한다. 매월 동일한 급여 구조를 유지할 때 사용.

POST /api/v1/payrolls/copy-from-previous

Request Body:

{
  "year": 2026,
  "month": 3
}

응답 (200):

{
  "success": true,
  "message": "전월 급여가 복사되었습니다.",
  "data": {
    "created": 15,
    "skipped": 0
  }
}

동작 설명:

  • 지급/공제 항목을 전월 그대로 복사 (base_salary, allowances, deductions 등)
  • 상태는 draft로 초기화
  • 이미 존재하는 사원은 skipped 처리
  • 1월 요청 시 전년 12월 데이터 참조

에러:

상황 응답 코드 메시지
전월 데이터 없음 400 전월 급여 데이터가 없습니다.

5.9 급여 상세 조회

GET /api/v1/payrolls/{id}

응답 (200):

{
  "success": true,
  "message": "조회 성공",
  "data": {
    "id": 1,
    "user": {"id": 5, "name": "홍길동", "email": "hong@example.com"},
    "confirmer": {"id": 1, "name": "관리자"},
    "withdrawal": null,
    "creator": {"id": 1, "name": "관리자"},
    /* ... 전체 Payroll 필드 */
  }
}

5.10 급여 수정

PUT /api/v1/payrolls/{id}

Request Body:

{
  "base_salary": 3600000,
  "overtime_pay": 100000,
  "bonus": 200000,
  "allowances": [
    {"name": "직책수당", "amount": 300000}
  ],
  "deductions": [
    {"name": "대출상환", "amount": 500000}
  ],
  "deduction_overrides": {
    "pension": 175000
  },
  "_is_super_admin": false,
  "note": "기본급 인상 반영"
}

필드 규칙:

  • _is_super_admin: true 전달 시 confirmed/paid 상태에서도 수정 가능
  • deduction_overrides로 법정 공제 항목을 수동 변경 가능
  • 전달하지 않은 필드는 기존값 유지

에러:

상황 응답 코드 메시지
draft 아닌 상태에서 수정 400 작성중 상태의 급여만 수정할 수 있습니다.
연월/사원 변경 시 중복 400 해당 연월에 이미 급여가 등록되어 있습니다.

5.11 급여 삭제

DELETE /api/v1/payrolls/{id}

응답 (200):

{
  "success": true,
  "message": "삭제 성공",
  "data": null
}

draft 상태에서만 삭제 가능. Soft delete 처리.


5.12 확정

POST /api/v1/payrolls/{id}/confirm

Request Body: 없음

응답 (200):

{
  "success": true,
  "message": "급여가 확정되었습니다.",
  "data": {
    "id": 1,
    "status": "confirmed",
    "confirmed_at": "2026-03-11T14:30:00.000000Z",
    "confirmer": {"id": 1, "name": "관리자"}
  }
}

5.13 확정 취소

POST /api/v1/payrolls/{id}/unconfirm

Request Body: 없음

응답 (200):

{
  "success": true,
  "message": "급여 확정이 취소되었습니다.",
  "data": {
    "id": 1,
    "status": "draft",
    "confirmed_at": null,
    "confirmed_by": null
  }
}

confirmed 상태에서만 가능. draft로 되돌린다.


5.14 지급 처리

POST /api/v1/payrolls/{id}/pay

Request Body:

{
  "withdrawal_id": 42
}
필드 타입 필수 설명
withdrawal_id int - 연결할 출금 내역 ID

응답 (200):

{
  "success": true,
  "message": "급여가 지급 처리되었습니다.",
  "data": {
    "id": 1,
    "status": "paid",
    "paid_at": "2026-03-25T09:00:00.000000Z",
    "withdrawal": { "id": 42, "..." : "..." }
  }
}

5.15 지급 취소

POST /api/v1/payrolls/{id}/unpay

Request Body: 없음

슈퍼관리자 전용. paiddraft로 초기화. 확정/지급 이력 모두 제거.

응답 (200):

{
  "success": true,
  "message": "급여 지급이 취소되었습니다.",
  "data": {
    "id": 1,
    "status": "draft",
    "confirmed_at": null,
    "paid_at": null,
    "withdrawal_id": null
  }
}

5.16 급여명세서 조회

GET /api/v1/payrolls/{id}/payslip

응답 (200):

{
  "success": true,
  "message": "조회 성공",
  "data": {
    "payroll": { /* 전체 Payroll 객체 */ },
    "period": "2026년 03월",
    "employee": {
      "id": 5,
      "name": "홍길동",
      "email": "hong@example.com"
    },
    "earnings": {
      "base_salary": 3500000,
      "overtime_pay": 0,
      "bonus": 200000,
      "allowances": [
        {"name": "직책수당", "amount": 300000},
        {"name": "교통비", "amount": 100000}
      ],
      "allowances_total": 400000,
      "gross_total": 4100000
    },
    "deductions": {
      "income_tax": 117750,
      "resident_tax": 11770,
      "health_insurance": 138220,
      "long_term_care": 1250,
      "pension": 175500,
      "employment_insurance": 35100,
      "other_deductions": [
        {"name": "대출상환", "amount": 500000}
      ],
      "other_total": 500000,
      "total": 979590
    },
    "net_salary": 3120410,
    "status": "confirmed",
    "status_label": "확정",
    "paid_at": null
  }
}

프론트엔드 참고:

  • earnings 구조로 지급 항목 테이블 구성
  • deductions 구조로 공제 항목 테이블 구성
  • period, employee, net_salary로 명세서 헤더 구성
  • 인쇄용 레이아웃은 A4 세로 기준 권장

5.17 급여 설정 조회

GET /api/v1/payrolls/settings

응답 (200):

{
  "success": true,
  "message": "조회 성공",
  "data": {
    "id": 1,
    "tenant_id": 1,
    "income_tax_rate": "0.00",
    "resident_tax_rate": "10.00",
    "health_insurance_rate": "3.545",
    "long_term_care_rate": "0.9082",
    "pension_rate": "4.500",
    "employment_insurance_rate": "0.900",
    "pension_max_salary": "5900000.00",
    "pension_min_salary": "370000.00",
    "pay_day": 25,
    "auto_calculate": false,
    "allowance_types": [
      {"code": "meal", "name": "식대", "is_taxable": false},
      {"code": "transport", "name": "교통비", "is_taxable": false},
      {"code": "position", "name": "직책수당", "is_taxable": true},
      {"code": "skill", "name": "기술수당", "is_taxable": true},
      {"code": "family", "name": "가족수당", "is_taxable": true},
      {"code": "housing", "name": "주거수당", "is_taxable": true}
    ],
    "deduction_types": [
      {"code": "loan", "name": "대출상환"},
      {"code": "union", "name": "조합비"},
      {"code": "savings", "name": "저축"},
      {"code": "etc", "name": "기타공제"}
    ]
  }
}

프론트엔드 참고:

  • allowance_types로 수당 입력 폼의 드롭다운 구성
  • deduction_types로 공제 입력 폼의 드롭다운 구성
  • pay_day를 급여 지급일 표시에 활용

5.18 급여 설정 수정

PUT /api/v1/payrolls/settings

Request Body:

{
  "health_insurance_rate": 3.545,
  "pension_rate": 4.5,
  "pay_day": 25,
  "allowance_types": [
    {"code": "meal", "name": "식대", "is_taxable": false},
    {"code": "transport", "name": "교통비", "is_taxable": false}
  ]
}

전달한 필드만 업데이트. 미전달 필드는 기존값 유지.


6. 에러 코드 정리

에러 키 메시지 발생 상황
error.payroll.not_found 급여 정보를 찾을 수 없습니다. 존재하지 않는 ID
error.payroll.already_exists 해당 연월에 이미 급여가 등록되어 있습니다. 동일 사원+연월 중복
error.payroll.not_editable 작성중 상태의 급여만 수정할 수 있습니다. draft 외 수정 시도
error.payroll.not_deletable 작성중 상태의 급여만 삭제할 수 있습니다. draft 외 삭제 시도
error.payroll.not_confirmable 작성중 상태의 급여만 확정할 수 있습니다. draft 외 확정 시도
error.payroll.not_unconfirmable 확정된 급여만 확정 취소할 수 있습니다. confirmed 외 확정취소
error.payroll.not_payable 확정된 급여만 지급 처리할 수 있습니다. confirmed 외 지급
error.payroll.not_unpayable 지급완료된 급여만 지급 취소할 수 있습니다. paid 외 지급취소
error.payroll.no_previous_month 전월 급여 데이터가 없습니다. 전월 복사 시 데이터 없음
error.payroll.invalid_withdrawal 유효하지 않은 출금 내역입니다. 존재하지 않는 withdrawal_id

7. 프론트엔드 구현 가이드

7.1 추천 화면 구성

┌─────────────────────────────────────────────────────┐
│ 급여관리                            [2026년 03월 ▼] │
├─────────────────────────────────────────────────────┤
│                                                     │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
│ │ 총 인원   │ │ 총 지급액 │ │ 총 공제액 │ │ 실수령액 ││
│ │    15명   │ │ 62,500천원│ │ 15,800천원│ │46,700천원││
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘│
│                                                     │
│ [일괄생성] [전월복사] [일괄계산] [일괄확정] [+ 등록] │
│                                                     │
│ ┌───┬──────┬──────┬──────┬──────┬──────┬────┬────┐│
│ │ # │ 사원  │ 기본급│총지급액│총공제액│실수령액│상태 │ 작업││
│ ├───┼──────┼──────┼──────┼──────┼──────┼────┼────┤│
│ │ 1 │홍길동│ 350만│ 410만│ 98만 │ 312만│작성│ ⋮  ││
│ │ 2 │김철수│ 300만│ 350만│ 85만 │ 265만│확정│ ⋮  ││
│ └───┴──────┴──────┴──────┴──────┴──────┴────┴────┘│
└─────────────────────────────────────────────────────┘

7.2 급여 등록/수정 폼

┌─────────────────────────────────────────────────────┐
│ 급여 등록                                           │
├─────────────────────────────────────────────────────┤
│ 사원: [홍길동 ▼]  연도: [2026]  월: [3 ▼]          │
│                                                     │
│ ── 지급 항목 ──────────────────────────────────── │
│ 기본급:         [  3,500,000 ]                      │
│ 연장근로수당:    [          0 ]                      │
│ 식대(비과세):   [    200,000 ]                      │
│ 수당:                                               │
│   직책수당      [    300,000 ] [삭제]               │
│   교통비        [    100,000 ] [삭제]               │
│   [+ 수당 추가]                                     │
│ ────────────────────────── 총 지급액: 4,100,000    │
│                                                     │
│ ── 공제 항목 (자동 계산) ────────────────────────  │
│ 근로소득세:     [    117,750 ] ← 자동 (수정 가능)   │
│ 지방소득세:     [     11,770 ] ← 자동 (수정 가능)   │
│ 건강보험:       [    138,220 ] ← 자동 (수정 가능)   │
│ 장기요양보험:   [      1,250 ] ← 자동 (수정 가능)   │
│ 국민연금:       [    175,500 ] ← 자동 (수정 가능)   │
│ 고용보험:       [     35,100 ] ← 자동 (수정 가능)   │
│ 기타 공제:                                          │
│   대출상환      [    500,000 ] [삭제]               │
│   [+ 기타 공제 추가]                                │
│ ────────────────────────── 총 공제액:   979,590    │
│                                                     │
│ ═════════════════════════ 실수령액:  3,120,410    │
│                                                     │
│ 메모: [                    ]                        │
│                                                     │
│                            [취소]  [미리보기]  [저장]│
└─────────────────────────────────────────────────────┘

구현 포인트:

  • 지급 항목 변경 시 calculate-preview API 호출하여 공제 항목 자동 갱신
  • 법정 공제 필드는 기본 readonly + "수정" 토글로 수동 입력 허용
  • 수동 입력된 공제 항목은 deduction_overrides로 전달
  • allowance_types, deduction_types는 설정 API에서 조회하여 드롭다운 제공

7.3 급여명세서 (인쇄용)

payslip API 응답의 earnings/deductions 구조를 활용:

┌─────────────────────────────────────────────┐
│              급 여 명 세 서                  │
│                                             │
│ 사원명: 홍길동     귀속기간: 2026년 03월    │
│                                             │
│ ┌──── 지급 내역 ────┬── 공제 내역 ────┐    │
│ │ 기본급    3,500,000│ 소득세    117,750│    │
│ │ 식대       200,000│ 지방소득세 11,770│    │
│ │ 직책수당    300,000│ 건강보험  138,220│    │
│ │ 교통비     100,000│ 장기요양    1,250│    │
│ │                   │ 국민연금  175,500│    │
│ │                   │ 고용보험   35,100│    │
│ │                   │ 대출상환  500,000│    │
│ ├───────────────────┼─────────────────┤    │
│ │ 지급합계 4,100,000│ 공제합계 979,590│    │
│ └───────────────────┴─────────────────┘    │
│                                             │
│         실수령액: 3,120,410원               │
└─────────────────────────────────────────────┘

7.4 월간 워크플로우

1. 월초 → [일괄생성] 또는 [전월복사] 실행
2. 개별 급여 데이터 확인/수정
3. [일괄계산] 실행 (공제 항목 최신 요율로 재계산)
4. 데이터 확인 완료 → [일괄확정]
5. 급여 지급일 → 개별 [지급처리] (출금과 연결)
6. 급여명세서 조회/인쇄

7.5 금액 표시 규칙

  • 모든 금액은 원(KRW) 단위 정수
  • 천 단위 콤마 필수: 3,500,000
  • 음수 금액(환급): 빨간색 + - 부호

관련 문서


최종 업데이트: 2026-03-11