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>
This commit is contained in:
@@ -4,6 +4,15 @@ import com.ga.batch.settlement.SettlementContext;
|
||||
import com.ga.batch.settlement.domain.BatchTaxCalculator;
|
||||
import com.ga.batch.settlement.domain.TaxBreakdown;
|
||||
import com.ga.common.util.MoneyUtil;
|
||||
import com.ga.core.mapper.commission.AwardLedgerMapper;
|
||||
import com.ga.core.mapper.commission.BranchMgrAllowanceLedgerMapper;
|
||||
import com.ga.core.mapper.commission.CollectionCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.LifeSupportLedgerMapper;
|
||||
import com.ga.core.mapper.commission.PersistencyBonusMapper;
|
||||
import com.ga.core.mapper.commission.ReferralCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.ReinstatementCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.RenewalCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.SettlingSupportLedgerMapper;
|
||||
import com.ga.core.mapper.ledger.ExceptionLedgerMapper;
|
||||
import com.ga.core.mapper.ledger.MaintainLedgerMapper;
|
||||
import com.ga.core.mapper.ledger.RecruitLedgerMapper;
|
||||
@@ -68,6 +77,17 @@ public class AggregateStep implements Tasklet {
|
||||
private final CommissionStatementMapper statementMapper;
|
||||
private final BatchTaxCalculator taxCalculator;
|
||||
|
||||
// 설계사 지급성 9종 원장 Mapper
|
||||
private final CollectionCommissionLedgerMapper collectionMapper;
|
||||
private final RenewalCommissionLedgerMapper renewalMapper;
|
||||
private final ReinstatementCommissionLedgerMapper reinstatementMapper;
|
||||
private final PersistencyBonusMapper persistencyBonusMapper;
|
||||
private final ReferralCommissionLedgerMapper referralMapper;
|
||||
private final SettlingSupportLedgerMapper settlingSupportMapper;
|
||||
private final AwardLedgerMapper awardMapper;
|
||||
private final LifeSupportLedgerMapper lifeSupportMapper;
|
||||
private final BranchMgrAllowanceLedgerMapper branchMgrAllowanceMapper;
|
||||
|
||||
@Override
|
||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
|
||||
log.info("[Step8 aggregate] settleMonth={}", ctx.getSettleMonth());
|
||||
@@ -86,6 +106,17 @@ public class AggregateStep implements Tasklet {
|
||||
excMinus.put(agentId, toBd(row.get("minus")));
|
||||
}
|
||||
|
||||
// 설계사 지급성 9종 집계
|
||||
Map<Long, BigDecimal> collectionMap = toMap(collectionMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> renewalMap = toMap(renewalMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> reinstatementMap = toMap(reinstatementMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> persistencyMap = toMap(persistencyBonusMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> referralMap = toMap(referralMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> settlingSupportMap = toMap(settlingSupportMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> awardMap = toMap(awardMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> lifeSupportMap = toMap(lifeSupportMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
Map<Long, BigDecimal> branchMgrMap = toMap(branchMgrAllowanceMapper.aggregateByAgent(ctx.getSettleMonth()));
|
||||
|
||||
// 합집합 agent_id
|
||||
Set<Long> agentIds = new HashSet<>();
|
||||
agentIds.addAll(recruitMap.keySet());
|
||||
@@ -94,6 +125,15 @@ public class AggregateStep implements Tasklet {
|
||||
agentIds.addAll(overrideMap.keySet());
|
||||
agentIds.addAll(excPlus.keySet());
|
||||
agentIds.addAll(excMinus.keySet());
|
||||
agentIds.addAll(collectionMap.keySet());
|
||||
agentIds.addAll(renewalMap.keySet());
|
||||
agentIds.addAll(reinstatementMap.keySet());
|
||||
agentIds.addAll(persistencyMap.keySet());
|
||||
agentIds.addAll(referralMap.keySet());
|
||||
agentIds.addAll(settlingSupportMap.keySet());
|
||||
agentIds.addAll(awardMap.keySet());
|
||||
agentIds.addAll(lifeSupportMap.keySet());
|
||||
agentIds.addAll(branchMgrMap.keySet());
|
||||
|
||||
// 활성 설계사 누락 보충
|
||||
AgentSearchParam ap = new AgentSearchParam();
|
||||
@@ -122,8 +162,21 @@ public class AggregateStep implements Tasklet {
|
||||
BigDecimal ep = excPlus.getOrDefault(agentId, BigDecimal.ZERO);
|
||||
BigDecimal em = excMinus.getOrDefault(agentId, BigDecimal.ZERO);
|
||||
|
||||
// 설계사 지급성 9종 합산 (원장 없으면 ZERO → gross 불변 보장)
|
||||
BigDecimal otherCommission = BigDecimal.ZERO;
|
||||
otherCommission = MoneyUtil.add(otherCommission, collectionMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, renewalMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, reinstatementMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, persistencyMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, referralMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, settlingSupportMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, awardMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, lifeSupportMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
otherCommission = MoneyUtil.add(otherCommission, branchMgrMap.getOrDefault(agentId, BigDecimal.ZERO));
|
||||
|
||||
BigDecimal gross = MoneyUtil.add(MoneyUtil.add(MoneyUtil.add(recruit, maintain), ov), ep)
|
||||
.subtract(cb).subtract(em);
|
||||
gross = MoneyUtil.add(gross, otherCommission);
|
||||
|
||||
// 세금유형 조회 (없으면 기본: BUSINESS_INCOME / NONE)
|
||||
AgentVO agentVO = agentMapper.selectById(agentId);
|
||||
@@ -152,6 +205,7 @@ public class AggregateStep implements Tasklet {
|
||||
vo.setExceptionMinus(em);
|
||||
vo.setOverrideTotal(ov);
|
||||
vo.setChargebackTotal(cb);
|
||||
vo.setOtherCommissionTotal(otherCommission);
|
||||
vo.setGrossAmount(gross);
|
||||
vo.setTaxAmount(totalTax); // incomeTax + localTax 합산
|
||||
vo.setNetAmount(netAmount); // gross - incomeTax - localTax + vat - deduction
|
||||
|
||||
Reference in New Issue
Block a user