diff --git a/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentPlanMapper.java b/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentPlanMapper.java new file mode 100644 index 0000000..0e0d1c7 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentPlanMapper.java @@ -0,0 +1,34 @@ +package com.ga.core.mapper.installment; + +import com.ga.core.vo.installment.InstallmentPlanResp; +import com.ga.core.vo.installment.InstallmentPlanSearchParam; +import com.ga.core.vo.installment.InstallmentPlanVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface InstallmentPlanMapper { + + List selectList(InstallmentPlanSearchParam param); + + InstallmentPlanResp selectDetailById(@Param("planId") Long planId); + + InstallmentPlanVO selectById(@Param("planId") Long planId); + + /** 계약의 전체 분급 계획 조회 (계약 상세 화면용) */ + List selectByContract(@Param("contractId") Long contractId); + + /** 정산월의 SCHEDULED 분급 계획 조회 (배치 지급 처리용) */ + List selectScheduledByMonth(@Param("settleMonth") String settleMonth); + + int insert(InstallmentPlanVO vo); + + /** 7년치 분급 계획 일괄 생성 */ + int insertBatch(@Param("list") List list); + + int update(InstallmentPlanVO vo); + + int updateStatus(@Param("planId") Long planId, @Param("status") String status); +} diff --git a/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentRatioMapper.java b/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentRatioMapper.java new file mode 100644 index 0000000..90e70c9 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/mapper/installment/InstallmentRatioMapper.java @@ -0,0 +1,32 @@ +package com.ga.core.mapper.installment; + +import com.ga.core.vo.installment.InstallmentRatioResp; +import com.ga.core.vo.installment.InstallmentRatioSearchParam; +import com.ga.core.vo.installment.InstallmentRatioVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface InstallmentRatioMapper { + + List selectList(InstallmentRatioSearchParam param); + + InstallmentRatioResp selectDetailById(@Param("ratioId") Long ratioId); + + InstallmentRatioVO selectById(@Param("ratioId") Long ratioId); + + /** 특정 날짜에 유효한 분급 비율 1건 (planYear + productCategory 조합) */ + InstallmentRatioVO selectActive(@Param("productCategory") String productCategory, + @Param("planYear") Integer planYear, + @Param("baseDate") String baseDate); + + /** 특정 날짜에 유효한 1~7년 차 전체 비율 조회 (분급 계획 일괄 생성 시 사용) */ + List selectAllActiveRatios(@Param("productCategory") String productCategory, + @Param("baseDate") String baseDate); + + int insert(InstallmentRatioVO vo); + + int update(InstallmentRatioVO vo); +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanResp.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanResp.java new file mode 100644 index 0000000..b6a2724 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanResp.java @@ -0,0 +1,25 @@ +package com.ga.core.vo.installment; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class InstallmentPlanResp { + private Long planId; + private Long contractId; + private String policyNo; + private String productName; + private Long agentId; + private String agentName; + private Integer planYear; + private Integer planMonth; + private String settleMonth; + private BigDecimal expectedAmount; + private BigDecimal paidAmount; + private LocalDateTime paidAt; + private Long paymentId; + private String status; + private String statusName; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanSearchParam.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanSearchParam.java new file mode 100644 index 0000000..fbae505 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanSearchParam.java @@ -0,0 +1,14 @@ +package com.ga.core.vo.installment; + +import com.ga.common.model.SearchParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class InstallmentPlanSearchParam extends SearchParam { + private Long contractId; + private String settleMonth; + private String status; + private Integer planYear; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanVO.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanVO.java new file mode 100644 index 0000000..bbac84f --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentPlanVO.java @@ -0,0 +1,25 @@ +package com.ga.core.vo.installment; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class InstallmentPlanVO { + private Long planId; + private Long contractId; + private Integer planYear; // 1~7 + private Integer planMonth; // 1~12 + private String settleMonth; // YYYYMM + private BigDecimal expectedAmount; + private BigDecimal paidAmount; + private LocalDateTime paidAt; + private Long paymentId; + private String status; + + private LocalDateTime createdAt; + private Long createdBy; + private LocalDateTime updatedAt; + private Long updatedBy; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioResp.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioResp.java new file mode 100644 index 0000000..df00ed8 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioResp.java @@ -0,0 +1,18 @@ +package com.ga.core.vo.installment; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +public class InstallmentRatioResp { + private Long ratioId; + private String productCategory; + private String productCategoryName; + private Integer planYear; + private BigDecimal ratioPercent; + private LocalDate effectiveFrom; + private LocalDate effectiveTo; + private Boolean isActive; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSaveReq.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSaveReq.java new file mode 100644 index 0000000..88eb5f0 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSaveReq.java @@ -0,0 +1,30 @@ +package com.ga.core.vo.installment; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +public class InstallmentRatioSaveReq { + + private String productCategory; // NULL = 전체 상품 + + @NotNull(message = "분급 연차는 필수입니다") + @Min(value = 1, message = "분급 연차는 1 이상이어야 합니다") + @Max(value = 7, message = "분급 연차는 7 이하여야 합니다") + private Integer planYear; + + @NotNull(message = "비율은 필수입니다") + @Positive(message = "비율은 양수여야 합니다") + private BigDecimal ratioPercent; + + @NotNull(message = "적용 시작일은 필수입니다") + private LocalDate effectiveFrom; + + private LocalDate effectiveTo; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSearchParam.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSearchParam.java new file mode 100644 index 0000000..06e4143 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioSearchParam.java @@ -0,0 +1,13 @@ +package com.ga.core.vo.installment; + +import com.ga.common.model.SearchParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class InstallmentRatioSearchParam extends SearchParam { + private String productCategory; + private Integer planYear; + private String effectiveDate; // YYYY-MM-DD — 해당 날짜 유효 비율 필터 +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioVO.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioVO.java new file mode 100644 index 0000000..6e3a678 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentRatioVO.java @@ -0,0 +1,23 @@ +package com.ga.core.vo.installment; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Data +public class InstallmentRatioVO { + private Long ratioId; + private String productCategory; // NULL = ALL 상품 + private Integer planYear; // 1~7 + private BigDecimal ratioPercent; + private LocalDate effectiveFrom; + private LocalDate effectiveTo; // NULL = 현재 유효 + private Boolean isActive; + + private LocalDateTime createdAt; + private Long createdBy; + private LocalDateTime updatedAt; + private Long updatedBy; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentStatus.java b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentStatus.java new file mode 100644 index 0000000..3786617 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/installment/InstallmentStatus.java @@ -0,0 +1,7 @@ +package com.ga.core.vo.installment; + +public enum InstallmentStatus { + SCHEDULED, PAID, DEFERRED, CANCELLED; + + public String code() { return this.name(); } +} diff --git a/ga-core/src/main/resources/mapper/installment/InstallmentPlanMapper.xml b/ga-core/src/main/resources/mapper/installment/InstallmentPlanMapper.xml new file mode 100644 index 0000000..ef0713b --- /dev/null +++ b/ga-core/src/main/resources/mapper/installment/InstallmentPlanMapper.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p.plan_id, + p.contract_id, + c.policy_no, + pr.product_name, + c.agent_id, + a.agent_name, + p.plan_year, + p.plan_month, + p.settle_month, + p.expected_amount, + p.paid_amount, + p.paid_at, + p.payment_id, + p.status, + (SELECT cc.code_name FROM common_code cc + WHERE cc.group_code = 'INSTALLMENT_STATUS' AND cc.code = p.status) AS status_name + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO installment_plan ( + contract_id, plan_year, plan_month, settle_month, + expected_amount, paid_amount, status, + created_at, created_by + ) VALUES ( + #{contractId}, #{planYear}, #{planMonth}, #{settleMonth}, + #{expectedAmount}, COALESCE(#{paidAmount}, 0), + COALESCE(#{status}, 'SCHEDULED'), + NOW(), #{createdBy} + ) + + + + + INSERT INTO installment_plan ( + contract_id, plan_year, plan_month, settle_month, + expected_amount, paid_amount, status, + created_at, created_by + ) VALUES + + (#{p.contractId}, #{p.planYear}, #{p.planMonth}, #{p.settleMonth}, + #{p.expectedAmount}, COALESCE(#{p.paidAmount}, 0), + COALESCE(#{p.status}, 'SCHEDULED'), + NOW(), #{p.createdBy}) + + + + + + + UPDATE installment_plan + + settle_month = #{settleMonth}, + expected_amount = #{expectedAmount}, + paid_amount = #{paidAmount}, + paid_at = #{paidAt}, + payment_id = #{paymentId}, + status = #{status}, + updated_at = NOW(), + updated_by = #{updatedBy} + + WHERE plan_id = #{planId} + + + + + UPDATE installment_plan + SET status = #{status}, updated_at = NOW() + WHERE plan_id = #{planId} + + + diff --git a/ga-core/src/main/resources/mapper/installment/InstallmentRatioMapper.xml b/ga-core/src/main/resources/mapper/installment/InstallmentRatioMapper.xml new file mode 100644 index 0000000..b896177 --- /dev/null +++ b/ga-core/src/main/resources/mapper/installment/InstallmentRatioMapper.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + r.ratio_id, + r.product_category, + (SELECT cc.code_name FROM common_code cc + WHERE cc.group_code = 'PRODUCT_CATEGORY' AND cc.code = r.product_category) AS product_category_name, + r.plan_year, + r.ratio_percent, + r.effective_from, + r.effective_to, + r.is_active + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO installment_ratio ( + product_category, plan_year, ratio_percent, + effective_from, effective_to, is_active, + created_at, created_by + ) VALUES ( + #{productCategory}, #{planYear}, #{ratioPercent}, + #{effectiveFrom}, #{effectiveTo}, COALESCE(#{isActive}, TRUE), + NOW(), #{createdBy} + ) + + + + + + UPDATE installment_ratio + + ratio_percent = #{ratioPercent}, + effective_from = #{effectiveFrom}, + effective_to = #{effectiveTo}, + is_active = #{isActive}, + updated_at = NOW(), + updated_by = #{updatedBy} + + WHERE ratio_id = #{ratioId} + + +