Files
ga-commission-system/ga-common/src/main/resources/db/migration/V88__수입수수료_수지차.sql
T
GA Pro bfc724669b feat: incar 갭 반영 수수료/운영 14개 도메인 풀스택 + 배치통합 + 신입교육자료
incar CMS(116메뉴) 벤치마킹 갭분석으로 ga-pro에 없던 14개 도메인을 풀스택 추가.

P7 수수료 계산 7종 (V88~V96):
- 수입수수료+수지차, 소개·이관수수료, 정착지원금, 인정실적+환산율,
  시상, 생보운영지원수수료, 지점장수당
- 각 rule/ledger + 공식(보험료×요율, 수입−지급 등) Service 내장

P8 운영/정산 7종 (V97~V105):
- 단계마감, 본사정산, 등급평가, 공동계약, 보증보험, 적립금, 수수료시뮬레이터
- close/reopen/apply/simulate/upsert 등 액션 + 손익·잔액·등급 산정 로직

배치 통합 (V106):
- settle_master.other_commission_total 컬럼 추가(DEFAULT 0, 백필)
- 설계사 지급성 9종 원장 aggregateByAgent → AggregateStep gross 합산
- 빈 원장 0 → 기존 정산결과·무결성 불변(비파괴적)

테스트: P7/P8 Service 공식 단위테스트 21건(ga-api:test 57건 전체 통과)
프론트: 화면 14개 + React.lazy 코드 스플리팅(단일 4MB → 130+ 청크)
문서: DOMAIN_GAP_P7/P8.md, 신입교육_보험과수수료_완전기초.md, DOMAIN_KNOWLEDGE/HANDOFF 갱신

검증: 전체 ./gradlew build(test 포함) SUCCESSFUL, Flyway V88~V106 success,
GET+액션POST smoke 5xx 0건, 9개 집계쿼리 SQL 유효성 확인, 공식 런타임 실측.

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

82 lines
4.8 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- V88: 수입수수료 + 수지차 (income_commission_ledger + margin_summary)
-- 보험사가 GA에 지급한 수입 측 원장. 수지차 = 수입 합계 - 지급 합계(settle_master 기준).
--
-- settle_master 지급 합계 집계 컬럼 (확인 완료):
-- settle_master.agent_id : 설계사 FK (BIGINT)
-- settle_master.settle_month : 정산월 CHAR(6)
-- settle_master.net_amount : 설계사 실지급액 (세후) NUMERIC
-- settle_master.gross_amount : 설계사 총지급액 (세전) NUMERIC
-- payout_total 산출 시 net_amount 합산 권장 (tax_amount 차감 후 기준)
-- ============================================================
-- 1. income_commission_ledger — 수입수수료 원장
-- 보험사 → GA 수입 수수료. 계약 단위로 발생.
-- ============================================================
CREATE TABLE income_commission_ledger (
income_id BIGSERIAL PRIMARY KEY,
contract_id BIGINT NOT NULL REFERENCES contract(contract_id),
carrier_id BIGINT NOT NULL REFERENCES insurance_company(company_id),
settle_month CHAR(6) NOT NULL,
premium_amount NUMERIC(15,2) NOT NULL,
company_rate NUMERIC(7,4) NOT NULL,
income_amount NUMERIC(15,2) NOT NULL,
commission_type VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'CALCULATED',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP,
CHECK (commission_type IN ('RECRUIT','MAINTAIN','RENEWAL','REINSTATE','COLLECTION')),
CHECK (status IN ('CALCULATED','CONFIRMED','CANCELLED')),
CHECK (company_rate >= 0 AND company_rate <= 1),
CHECK (premium_amount >= 0),
CHECK (income_amount >= 0)
);
COMMENT ON TABLE income_commission_ledger IS '수입수수료 원장 — 보험사가 GA에 지급한 수입 수수료 (계약 단위)';
COMMENT ON COLUMN income_commission_ledger.income_id IS '수입수수료 원장 PK';
COMMENT ON COLUMN income_commission_ledger.contract_id IS '대상 계약 FK';
COMMENT ON COLUMN income_commission_ledger.carrier_id IS '보험사 FK (insurance_company.company_id)';
COMMENT ON COLUMN income_commission_ledger.settle_month IS '정산 귀속월 (YYYYMM)';
COMMENT ON COLUMN income_commission_ledger.premium_amount IS '보험료';
COMMENT ON COLUMN income_commission_ledger.company_rate IS '보험사 수수료율 (소수, 예: 0.12 = 12%)';
COMMENT ON COLUMN income_commission_ledger.income_amount IS '수입수수료 = premium_amount × company_rate';
COMMENT ON COLUMN income_commission_ledger.commission_type IS '수수료 유형 (RECRUIT/MAINTAIN/RENEWAL/REINSTATE/COLLECTION)';
COMMENT ON COLUMN income_commission_ledger.status IS '상태 (CALCULATED/CONFIRMED/CANCELLED)';
CREATE INDEX idx_icl_carrier_month ON income_commission_ledger(carrier_id, settle_month);
CREATE INDEX idx_icl_contract ON income_commission_ledger(contract_id);
CREATE INDEX idx_icl_status_month ON income_commission_ledger(status, settle_month);
-- ============================================================
-- 2. margin_summary — 수지차 집계
-- 수지차 recalc 배치 액션으로 채움.
-- agent_id NULL = 전체(GA 총 수지차).
-- payout_total: settle_master.net_amount SUM (설계사별 세후 실지급액 기준)
-- ============================================================
CREATE TABLE margin_summary (
margin_id BIGSERIAL PRIMARY KEY,
settle_month CHAR(6) NOT NULL,
agent_id BIGINT REFERENCES agent(agent_id),
income_total NUMERIC(15,2) NOT NULL DEFAULT 0,
payout_total NUMERIC(15,2) NOT NULL DEFAULT 0,
margin_amount NUMERIC(15,2) NOT NULL DEFAULT 0,
margin_rate NUMERIC(7,4),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
UNIQUE (settle_month, agent_id),
CHECK (income_total >= 0),
CHECK (payout_total >= 0)
);
COMMENT ON TABLE margin_summary IS '수지차 집계 — settle_month + agent_id 단위 수입/지급 대비 수지차';
COMMENT ON COLUMN margin_summary.margin_id IS '수지차 집계 PK';
COMMENT ON COLUMN margin_summary.settle_month IS '정산월 (YYYYMM)';
COMMENT ON COLUMN margin_summary.agent_id IS '설계사 FK (NULL = GA 전체 합산)';
COMMENT ON COLUMN margin_summary.income_total IS '수입 합계 (income_commission_ledger SUM)';
COMMENT ON COLUMN margin_summary.payout_total IS '지급 합계 (settle_master.net_amount SUM — 설계사 세후 실지급액)';
COMMENT ON COLUMN margin_summary.margin_amount IS '수지차 = income_total - payout_total';
COMMENT ON COLUMN margin_summary.margin_rate IS '수지차율 = margin_amount / income_total (income_total > 0 일 때)';
CREATE INDEX idx_ms_month ON margin_summary(settle_month);
CREATE INDEX idx_ms_agent_month ON margin_summary(agent_id, settle_month);