00ead64c4c
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>
4.1 KiB
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)
POSTcreate(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 중복 생성 허용(이름으로 구분).GETlist(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. 테스트 데이터 정리.