Files
ga-commission-system/docs/DOMAIN_GAP_P12_지급대상건구성.md
GA Pro 00ead64c4c feat: P12(#2) 지급대상건 구성·수정 — 정산월 지급대상 배치 구성/확정 (PL 자율진행)
incar 지급대상건구성/수정/조회 대응. 기존 settle_master 건별 confirm/hold 위에
정산월 단위 지급대상 배치를 구성→포함/제외 편집→확정하는 워크플로우 레이어 추가
(AccountingClose DRAFT/마감 패턴 준용, settle_master 상태는 미변경=결합 최소화).

- DB(V115): payment_batch(배치 마스터, status DRAFT/FINALIZED/CANCELLED, total_count/
  total_payable) + payment_batch_item(건, settle_id FK, payable 스냅샷, included/exclude_reason,
  UNIQUE(batch_id,settle_id)) + 메뉴 PAYMENT_TARGET(GRP_SETTLE) + 권한 READ/CREATE/UPDATE/
  EXECUTE + 공통코드 PAYMENT_BATCH_STATUS.
- core: PaymentBatch/Item VO/Resp/SaveReq/SearchParam/Enum + Mapper. insertFromSettleMaster
  (INSERT-SELECT 자동채움: settle_month·payable>0·status!=PAID) + recalcTotals + updateInclude.
- api: PaymentBatchService create(자동채움+집계)/list/detail/updateItem(DRAFT만,재집계)/
  finalize(포함0건 거부)/cancel/export. Controller /api/payment-batches.
- frontend: PaymentTarget 화면(배치 목록 + 구성 모달 + 상세 Drawer items 포함/제외 토글 +
  합계 + 확정/취소/엑셀) + api 모듈 + App 라우트. export 권한 READ로 정렬.

검증: build+test SUCCESSFUL, Flyway V115(schema v115). 라이브 e2e: 202603 create→39건
자동채움(합 15,438,386.9) → 1건 제외 → 38건 재집계(정확히 −35,079) → finalize → 확정후
수정 400 차단 → cancel. 테스트 배치 정리. 스펙 docs/DOMAIN_GAP_P12.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 01:10:50 +09:00

4.1 KiB

P12 — 지급대상건 구성·수정 (#2)

작성: PL, 2026-06-04. 후속 갭 3종 중 마지막. 근거: incar 지급대상건구성/지급대상건수정/지급대상건조회. GA는 settle_master를 건별 confirm/hold/release만 가능, 정산월 단위 지급대상 배치 구성(일괄 포함/제외 후 확정) 레이어 부재.

범위: 풀스택. 기존 settle_master 위의 구성/스냅샷 레이어(settle_master 상태는 본 범위에서 변경 안 함 — 결합 최소화). Flyway: V114 최신 → V115. 금액 NUMERIC(15,2).

1. 개념

  • 정산월의 지급대상(settle_master, payable_amount>0)을 모아 배치(payment_batch) 로 구성.
  • 각 건(payment_batch_item)을 포함/제외(사유) 편집 → 합계 재계산.
  • 확정(finalize): 배치 잠금(FINALIZED). 확정된 포함건 목록 = 지급대상 확정본(스냅샷).
  • AccountingClose(V75 DRAFT/마감/재오픈) 패턴 준용. settle_master.status는 본 범위에서 미변경(향후 finalize→지급실행 연계는 별도).

2. 스키마 (V115)

payment_batch (지급대상 배치)

컬럼 타입 설명
batch_id BIGSERIAL PK
settle_month CHAR(6) NN
batch_name VARCHAR(100) NN
status VARCHAR(20) NN DEFAULT 'DRAFT' DRAFT/FINALIZED/CANCELLED
total_count INT NN DEFAULT 0 포함건수
total_payable NUMERIC(15,2) NN DEFAULT 0 포함건 payable 합
created_at/created_by/finalized_at/finalized_by/updated_at
  • idx(settle_month, status). CHECK status IN('DRAFT','FINALIZED','CANCELLED').

payment_batch_item (지급대상건)

컬럼 타입 설명
item_id BIGSERIAL PK
batch_id BIGINT NN FK payment_batch
settle_id BIGINT NN FK settle_master
agent_id BIGINT NN FK agent
payable_amount NUMERIC(15,2) NN settle_master.payable_amount 스냅샷
included BOOLEAN NN DEFAULT true 포함여부
exclude_reason VARCHAR(300) 제외사유
created_at
  • UNIQUE(batch_id, settle_id). idx(batch_id).

메뉴/권한/코드

  • 메뉴 PAYMENT_TARGET(지급대상관리), GRP_SETTLE, /settle/payment-target, settle/PaymentTarget.
  • 권한 READ/CREATE/UPDATE/EXECUTE(확정) + 역할(SUPER_ADMIN·ADMIN 전체, MANAGER READ).
  • 공통코드 PAYMENT_BATCH_STATUS(DRAFT=작성중/FINALIZED=확정/CANCELLED=취소).

3. API (PaymentBatchService, /api/payment-batches)

  • POST create(settleMonth, batchName) @Transactional: payment_batch(DRAFT) INSERT → settle_master 조회(settle_month=, payable_amount>0, status != 'PAID') → 각 행 payment_batch_item(included=true, payable 스냅샷) INSERT → total_count/total_payable 집계 UPDATE. 동일월 DRAFT 중복 생성 허용(이름으로 구분).
  • GET list(settleMonth/status 필터, PageResponse) / GET /{id} detail(배치 + items).
  • PUT /{id}/items/{itemId} updateItem(included, excludeReason) @Transactional: DRAFT 배치만(FINALIZED/CANCELLED 시 E411). 항목 갱신 후 배치 total 재집계.
  • PUT /{id}/finalize @Transactional, @RequirePermission EXECUTE: DRAFT→FINALIZED, finalized_at/by. 포함건 0이면 E411.
  • PUT /{id}/cancel: DRAFT/FINALIZED→CANCELLED.
  • GET /{id}/export 엑셀(@Transactional).
  • @RequirePermission(PAYMENT_TARGET, *) + @DataChangeLog(쓰기).

총계 재집계: total_count = COUNT(included=true), total_payable = SUM(payable WHERE included) — Mapper에 recalcTotals(batchId) 제공.

4. Frontend (PaymentTarget.tsx)

  • 배치 목록(정산월/상태 필터) + "구성" 버튼(정산월+배치명 입력 → create).
  • 배치 행 클릭 → 상세: 배치 헤더(상태/포함건수/합계) + items AG Grid(설계사/payable/포함체크/제외사유). DRAFT일 때 포함토글·사유 편집(PermissionButton UPDATE) → updateItem. 합계행.
  • "확정" 버튼(PermissionButton EXECUTE, DRAFT만) → finalize. "취소" 버튼. 엑셀.
  • React Query, 변경 후 invalidate.

5. 검증(PL)

build+test, Flyway V115, 라이브: create(특정월) → items 자동생성 확인 → updateItem 제외 → total 재집계 확인 → finalize → 잠금(이후 updateItem E411) → cancel. 테스트 데이터 정리.