jiangping
2024-06-20 09da100729793848bc01b51f7b05ca3f1e7ec64f
server/service/src/main/java/com/doumee/core/utils/Constants.java
@@ -4,7 +4,9 @@
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.dao.business.dto.CountCyclePriceDTO;
import com.doumee.dao.business.model.ApplyDetail;
import com.doumee.dao.business.model.Solutions;
import com.doumee.dao.business.vo.ChangeDealTypeVO;
import com.doumee.dao.business.vo.CountCyclePriceVO;
import io.swagger.models.auth.In;
import org.apache.commons.collections4.CollectionUtils;
@@ -228,6 +230,131 @@
        countCyclePriceVO.setCyclePrice(solutions.getPrice());
        return countCyclePriceVO;
    }
    //查询每个批改周期费用
    public static BigDecimal calculateSingleCycleFee(Solutions solutions,Date startTime){
        if(Constants.equalsInteger(solutions.getTimeUnit(),solutions.getInsureCycleUnit())){
            return solutions.getPrice();
        }
        CountCyclePriceVO countCyclePriceVO = Constants.countPriceVO(startTime,solutions);
        //单计费周期的费用
        BigDecimal singleFee = Constants.singleCycleFee(solutions,startTime,countCyclePriceVO.getEndDate());
        return singleFee;
    }
    /**
     * 加减保业务使用
     * 判断是否处于 周期节点
     * 结束日期 入的日期为批单日期 前一天 23:59:59
     * @param solutions
     * @param startTime
     * @param endTime
     * @return 0=无周期费用;1=有周期费用;2无周期费用 且 数据标记无效
     */
    public static ChangeDealTypeVO calculateRetreatCost(Solutions solutions , Date startTime , Date endTime){
        ChangeDealTypeVO changeDealTypeVO = new ChangeDealTypeVO();
        //查询每个周期的费用
        changeDealTypeVO.setSinglePrice(Constants.calculateSingleCycleFee(solutions,startTime));
        //批单日期为开始日期的第一天 则标记明细记录为 无效数据 或者 开始时间大于当前时间 直接返回 数据标记无效
        if(startTime.getTime()>endTime.getTime()
        || startTime.getTime() > System.currentTimeMillis()){
            changeDealTypeVO.setChangeStatus(Constants.TWO);
            return changeDealTypeVO;
        }
        //获取昨日日期结束  为实际减保结束日期·
        Boolean isOver = true;
        if(solutions.getInsureCycleUnit().equals(InsureCycleUnit.DAY.getValue())){
            //方案 计费周期和批改周期 相同 直接返回 有周期费用
            changeDealTypeVO.setChangeStatus(Constants.ONE);
            return changeDealTypeVO;
        }else if(solutions.getInsureCycleUnit().equals(InsureCycleUnit.HALF_MONTH.getValue())){
            //半月周期 以15.5计算 由于15.5 无法整除 所以需要特殊处理
            //奇数/偶数 用于添加天数 如果是奇数
            BigDecimal cycleHalfMonth = new BigDecimal(15.5);
            Integer cycle = 1;
            while(isOver){
                //获取周期后的结束时间 带时分秒 23:59:59
                Date cycleEndTime =   DateUtil.getMontageDate(DateUtil.afterDateByType(startTime,0,  cycleHalfMonth.multiply(new BigDecimal(cycle)).setScale(2,RoundingMode.HALF_UP).intValue()
                ),2);
                if(cycleEndTime.getTime()>=endTime.getTime()){
                    isOver = false;
                    //当计费周期的结束日期 刚好 与批单日期的结束日期相等 则 不需要扣除批单周期费用
                    if(cycleEndTime.getTime()==endTime.getTime()){
                        changeDealTypeVO.setChangeStatus(Constants.ZERO);
                    }else{
                        changeDealTypeVO.setChangeStatus(Constants.ONE);
                    }
                    return changeDealTypeVO;
                }
                cycle = cycle + 1;
            }
        }else if(solutions.getInsureCycleUnit().equals(InsureCycleUnit.MONTH.getValue())){
            //扣费周期为月
            Integer cycle = 1;
            while(isOver){
                //获取周期后的结束时间 带时分秒 23:59:59
                Date cycleEndTime =  DateUtil.getMontageDate(DateUtil.afterDateByType(startTime,1,cycle),2);
                //当前周期 大于等于 批单结束日期时 , 则结束流程
                if(cycleEndTime.getTime()>=endTime.getTime()){
                    isOver = false;
                    //当计费周期的结束日期 刚好 与批单日期的结束日期相等 则 不需要扣除批单周期费用
                    if(cycleEndTime.getTime()==endTime.getTime()){
                        changeDealTypeVO.setChangeStatus(Constants.ZERO);
                    }else{
                        changeDealTypeVO.setChangeStatus(Constants.ONE);
                    }
                    return changeDealTypeVO;
                }
                cycle = cycle + 1;
            }
        }else if(solutions.getTimeUnit().equals(TimeUnit.QUARTER.getValue())){
            //扣费周期为季度
            Integer cycle = 3;
            while(isOver){
                //获取周期后的结束时间 带时分秒 23:59:59
                Date cycleEndTime =  DateUtil.getMontageDate(DateUtil.afterDateByType(startTime,1,cycle),2);
                //当前周期 大于等于 批单结束日期时 , 则结束流程
                if(cycleEndTime.getTime()>=endTime.getTime()){
                    isOver = false;
                    //当计费周期的结束日期 刚好 与批单日期的结束日期相等 则 不需要扣除批单周期费用
                    if(cycleEndTime.getTime()==endTime.getTime()){
                        changeDealTypeVO.setChangeStatus(Constants.ZERO);
                    }else{
                        changeDealTypeVO.setChangeStatus(Constants.ONE);
                    }
                    return changeDealTypeVO;
                }
                cycle = cycle + 3;
            }
        }else if(solutions.getTimeUnit().equals(TimeUnit.HALF_YEAR.getValue())){
            //扣费周期为半年
            Integer cycle = 3;
            while(isOver){
                //获取周期后的结束时间 带时分秒 23:59:59
                Date cycleEndTime =  DateUtil.getMontageDate(DateUtil.afterDateByType(startTime,1,cycle),2);
                //当前周期 大于等于 批单结束日期时 , 则结束流程
                if(cycleEndTime.getTime()>=endTime.getTime()){
                    isOver = false;
                    //当计费周期的结束日期 刚好 与批单日期的结束日期相等 则 不需要扣除批单周期费用
                    if(cycleEndTime.getTime()==endTime.getTime()){
                        changeDealTypeVO.setChangeStatus(Constants.ZERO);
                    }else{
                        changeDealTypeVO.setChangeStatus(Constants.ONE);
                    }
                    return changeDealTypeVO;
                }
                cycle = cycle + 3;
            }
        }
        throw new BusinessException(ResponseStatus.DATA_ERRO.getCode(),"计算批单周期信息异常");
    }
//    public static CountCyclePriceVO countPriceVO(Date startDate, Solutions solutions){
@@ -783,7 +910,8 @@
        WTBYTH(24, "已退回"),
        WTBYGB(25, "已关闭"),
        //2024年4月25日15:17:13 修改 投保中 = 》 批改申请中
        WTBTBZ(26, "批改申请中"),
        //2024-5-21 14:04:10 修改   批改申请中= 》投保中
        WTBTBZ(26, "投保中"),
        WTBBZZ(27, "保障中"),
        ;
        // 成员变量
@@ -1567,7 +1695,7 @@
        CLOSE(6, "已关闭"),
        CHECHED_PASSED(7, "审核通过"),
        PALTFORM_CHECK_PASS_NO(8, "审核不通过"),
        WTB_TOUBAOING(9, "投保中"),
        WTB_TOUBAOING(9, "批改申请中"),
        ;
        // 成员变量
        private String name;
@@ -2220,6 +2348,35 @@
        }
    }
    public static BigDecimal singleCycleFee(Solutions solutions,Date startTime ,Date endTime){
        Integer countDays = DateUtil.daysBetweenDates(endTime, startTime) + 1;
        Constants.TimeUnit timeUnit = Constants.TimeUnit.getTimeUnit(solutions.getTimeUnit());
        BigDecimal fee = solutions.getPrice();
        if(solutions.getTimeUnit().equals(solutions.getInsureCycleUnit())){
            return fee;
        }else{
            if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.DAY.getValue())){
                //天为批改单位
                return fee.divide(new BigDecimal(countDays),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_MONTH.getValue())) {
                //根据投保周期 定义的 每个周期 = X个 半月周期 进行计算
                // 总金额 / 投保周期定义的 半月周期数
                return fee.divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.MONTH.getValue())) {
                // 总金额 / 投保周期定义的 半月周期数 * 2
                return fee.multiply(new BigDecimal(2)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.QUARTER.getValue())) {
                //季度为批改单位
                // 总金额  / 投保周期定义的 半月周期数 * 6
                return fee.multiply(new BigDecimal(6)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_YEAR.getValue())) {
                //半年为批改单位
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(new BigDecimal(12)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else {
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"方案配置错误");
            }
        }
    }
}