fix: 모집정산 재실행 시 1200% clip 분급 UNIQUE 충돌 — 멱등성 보강
CalcRecruitStep(Step4)이 1200%룰 clip 초과분을 installment_plan(7년)으로 생성할 때, 재계산을 위해 recruit_ledger는 deleteBySettleMonth로 지우면서 분급은 정리하지 않아 같은 정산월을 재실행하면 동일 계약이 또 clip되어 동일 분급키(contract_id,plan_year, plan_month)로 INSERT → UNIQUE 충돌로 Job 실패하던 버그. 수정: insertBatch 직전에 clip된 계약들의 SCHEDULED(미지급) 분급을 먼저 삭제 (InstallmentPlanMapper.deleteScheduledByContractIds). PAID 분급 이력은 보존하여 PayInstallmentStep 지급분과 충돌하지 않음. 검증: CalcRecruitStepTest 멱등 테스트(clip 시 delete→insert 순서/대상계약 검증) 추가, 전체 build SUCCESS. 라이브 E2E: 202605 정산을 연속 2회 실행 → 둘 다 COMPLETED, 분급 196건 불변(중복 0), settle_master gross 동일, 무결성 유지. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,13 @@ public interface InstallmentPlanMapper {
|
||||
/** 7년치 분급 계획 일괄 생성 */
|
||||
int insertBatch(@Param("list") List<InstallmentPlanVO> list);
|
||||
|
||||
/**
|
||||
* 지정 계약들의 SCHEDULED(미지급) 분급 계획을 삭제. 모집정산(Step4) 재실행 시
|
||||
* clip으로 재생성할 분급 계획이 기존 분급과 UNIQUE(contract_id,plan_year,plan_month)
|
||||
* 충돌하는 것을 막는 멱등 장치. 이미 지급(PAID)된 분급은 이력 보존을 위해 건드리지 않는다.
|
||||
*/
|
||||
int deleteScheduledByContractIds(@Param("contractIds") List<Long> contractIds);
|
||||
|
||||
int update(InstallmentPlanVO vo);
|
||||
|
||||
int updateStatus(@Param("planId") Long planId, @Param("status") String status);
|
||||
|
||||
@@ -197,4 +197,14 @@
|
||||
DELETE FROM installment_plan WHERE contract_id = #{contractId}
|
||||
</delete>
|
||||
|
||||
<!-- 모집정산 재실행 멱등: 지정 계약들의 미지급(SCHEDULED) 분급만 삭제 (PAID 이력은 보존) -->
|
||||
<delete id="deleteScheduledByContractIds">
|
||||
DELETE FROM installment_plan
|
||||
WHERE status = 'SCHEDULED'
|
||||
AND contract_id IN
|
||||
<foreach collection="contractIds" item="cid" open="(" separator="," close=")">
|
||||
#{cid}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user