-- 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);