jiangping
2024-06-26 70a391a8b8013d56383e876a0b2a10ceafdd22c9
server/service/src/main/java/com/doumee/core/utils/Constants.java
@@ -1,8 +1,14 @@
package com.doumee.core.utils;
import cn.hutool.core.util.IdcardUtil;
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.ApplyChange;
import com.doumee.dao.business.model.ApplyDetail;
import com.doumee.dao.business.model.InsuranceApply;
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;
@@ -13,6 +19,7 @@
import javax.servlet.ServletOutputStream;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.net.URLDecoder;
import java.time.LocalDate;
@@ -49,6 +56,11 @@
    public static final String WX_MIN_SECRET = "WX_MIN_SECRET";
    public static final String SYSTEM ="SYSTEM";
    public static final String PROTOCOL ="PROTOCOL";
    public static final String PRIVACY ="PRIVACY";
    public static final String USE ="USE";
    public static final String GOODS_IMG_DIR ="GOODS_IMG_DIR";
    public static final String CREDIT_CODE_REGEX = "[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}";
@@ -86,7 +98,47 @@
    public static final String DU_FILE ="DU_FILE" ;
    public static final String SIGN_DONE_NOTIFY_URL = "SIGN_DONE_NOTIFY_URL";
    public static final int FOUR = 4;
    public static final String COMPANY_PHONE_AUTH ="COMPANY_PHONE_AUTH" ;
    /**
     * 获取申请单时间列标题
     * @param type 0开始时间 1截止时间
     * @param model
     * @return
     */
    public static String getApplyTimeTitle(int type, InsuranceApply model){
        if(type ==1){
            if(Constants.equalsInteger(model.getSolutionType(),Constants.ONE)){
                return  Constants.equalsInteger(model.getUnionApplyTbdStatus(),Constants.THREE)?"保险生效起期":"期望保险生效起期";
            }else{
                return  Constants.equalsInteger(model.getStatus(), InsuranceApplyStatus.UPLOAD_INSURANCE.getKey())?"保险生效起期":"期望保险生效起期";
            }
        }else{
            if(Constants.equalsInteger(model.getSolutionType(),Constants.ONE)){
                return  Constants.equalsInteger(model.getUnionApplyTbdStatus(),Constants.THREE)?"保险生效止期":"预计生效止期";
            }else{
                return  Constants.equalsInteger(model.getStatus(), InsuranceApplyStatus.UPLOAD_INSURANCE.getKey())?"保险生效止期":"预计生效止期";
            }
        }
    }
    /**
     * 获取批改单时间标题列
     * @param type 0更换派遣单位 1加保 0减保
     * @param model
     * @return
     */
    public static String getChangeApplyTimeTitle(int type, ApplyChange model){
        if(type ==2){
             return  Constants.equalsInteger(model.getStatus(), ApplyChangeStatus.APPROVE.getKey())?"批单生效期":"期望批单生效期";
        }else  if(type ==1){
            return  Constants.equalsInteger(model.getStatus(), ApplyChangeStatus.APPROVE.getKey())?"批增生效起期":"期望批增生效起期";
        }else{
            return  Constants.equalsInteger(model.getStatus(), ApplyChangeStatus.APPROVE.getKey())?"批减生效起期":"期望批减生效起期";
        }
    }
    /**
     * 企业数据来源 0平台注册 1后台导入
     */
@@ -156,52 +208,227 @@
    }
    public static long getAgeByIdCard(String idCard){
        int birthYear = Integer.parseInt(idCard.substring(6, 10));
        int birthMonth = Integer.parseInt(idCard.substring(10, 12));
        int birthDay = Integer.parseInt(idCard.substring(12, 14));
        try{
            LocalDate birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
            LocalDate currentDate = LocalDate.now();
            long age = ChronoUnit.YEARS.between(birthDate, currentDate);
            return age;
        try {
            int birthYear = Integer.parseInt(idCard.substring(6, 10));
            int birthMonth = Integer.parseInt(idCard.substring(10, 12));
            int birthDay = Integer.parseInt(idCard.substring(12, 14));
            try{
                LocalDate birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
                LocalDate currentDate = LocalDate.now();
                long age = ChronoUnit.YEARS.between(birthDate, currentDate);
                return age;
            }catch (Exception e){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"身份证号码错误:"+idCard);
            }
        }catch (Exception e){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"身份证号码错误:"+idCard);
        }
        }
        return 0;
    }
    public static CountCyclePriceVO getCountCyclePriceVO(CountCyclePriceDTO countCyclePriceDTO){
        if(Objects.isNull(countCyclePriceDTO)
                || Objects.isNull(countCyclePriceDTO.getSolutions())
                || Objects.isNull(countCyclePriceDTO.getStartDate())
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        return Constants.countPriceVO(countCyclePriceDTO.getStartDate(),countCyclePriceDTO.getSolutions());
    }
    public static CountCyclePriceVO countPriceVO(Date startDate, Solutions solutions){
        CountCyclePriceVO countCyclePriceVO = new CountCyclePriceVO();
        if(solutions.getInsureCycleUnit().equals(Constants.ZERO)){
        //天
        if(solutions.getTimeUnit().equals(TimeUnit.DAY.getValue())){
            countCyclePriceVO.setEndDate(
                    DateUtil.getMontageDate(
                        DateUtil.afterDateByType(startDate,0,solutions.getInsureCycle()-1)
                    ,2)
                            DateUtil.afterDateByType(startDate,0,0)
                            ,2)
            );
        }else if(solutions.getInsureCycleUnit().equals(Constants.TWO)){
        }else if(solutions.getTimeUnit().equals(TimeUnit.MONTH.getValue())){
            //获取当月天数
            Integer monthDays = DateUtil.monthDays(startDate);
            //获取天数后的日期
            Date afterDate = DateUtil.afterDateByType(startDate,0,monthDays);
            //赋值 每日结束时分秒
            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
        }else if(solutions.getInsureCycleUnit().equals(Constants.THREE)){
        }else if(solutions.getTimeUnit().equals(TimeUnit.QUARTER.getValue())){
            //获取X年后日期 多了一天
            Date afterDate = DateUtil.afterDateByType(startDate,2,solutions.getInsureCycle());
            Date afterDate = DateUtil.afterDateByType(startDate,1,3);
            //赋值 每日结束时分秒 然后减少一天
            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
        }else if(solutions.getTimeUnit().equals(TimeUnit.HALF_YEAR.getValue())){
            //获取X年后日期 多了一天
            Date afterDate = DateUtil.afterDateByType(startDate,1,6);
            //赋值 每日结束时分秒 然后减少一天
            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
        }else if(solutions.getTimeUnit().equals(TimeUnit.YEAR.getValue())){
            //获取X年后日期 多了一天
            Date afterDate = DateUtil.afterDateByType(startDate,2,1);
            //赋值 每日结束时分秒 然后减少一天
            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
        }
        countCyclePriceVO.setCyclePrice(Constants.countDetailFee(solutions,countCyclePriceVO.getEndDate(),startDate));
        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){
//        CountCyclePriceVO countCyclePriceVO = new CountCyclePriceVO();
//        if(solutions.getInsureCycleUnit().equals(Constants.ZERO)){
//            countCyclePriceVO.setEndDate(
//                    DateUtil.getMontageDate(
//                        DateUtil.afterDateByType(startDate,0,solutions.getInsureCycle()-1)
//                    ,2)
//            );
//        }else if(solutions.getInsureCycleUnit().equals(Constants.TWO)){
//            //获取当月天数
//            Integer monthDays = DateUtil.monthDays(startDate);
//            //获取天数后的日期
//            Date afterDate = DateUtil.afterDateByType(startDate,0,monthDays);
//            //赋值 每日结束时分秒
//            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
//        }else if(solutions.getInsureCycleUnit().equals(Constants.THREE)){
//            //获取X年后日期 多了一天
//            Date afterDate = DateUtil.afterDateByType(startDate,2,solutions.getInsureCycle());
//            //赋值 每日结束时分秒 然后减少一天
//            countCyclePriceVO.setEndDate(DateUtil.getMontageDate(afterDate,3));
//        }
//        countCyclePriceVO.setCyclePrice(Constants.countDetailFee(solutions,countCyclePriceVO.getEndDate(),startDate));
//        return countCyclePriceVO;
//    }
    public static Integer getSexByIdCard(String idCard){
        if(StringUtils.isBlank(idCard)){
            return 2;
        }
        Pattern pattern = Pattern.compile("\\d{17}[\\d|x]"); // 定义身份证号码格式的正则表达式
        Pattern pattern = Pattern.compile("\\d{17}[\\d|x|X]"); // 定义身份证号码格式的正则表达式
        Matcher matcher = pattern.matcher(idCard);
        Integer sex = 0;
        if (matcher.matches()) {
@@ -216,6 +443,7 @@
        }
        return sex;
    }
    /**
     * 状态 0已保存、1待审核、2审核通过、3退回修改、4审核驳回、5待服务机构确认、6服务机构拒绝、7已分配服务机构、8诊断中
@@ -574,8 +802,14 @@
    }
    public static void main(String[] args) {
        System.out.println(IdcardUtil.isValidCard("342623199201150101"));
        System.out.println(IdcardUtil.isValidCard("342623199201150102"));
        System.out.println(IdcardUtil.isValidCard("342623199201150103"));
        System.out.println(IdcardUtil.isValidCard("342623199201150104"));
//        System.out.println(IdcardUtil.isValidCard("340621199310134818"));
//        System.out.println(IdcardUtil.isValidCard("341621199310134818"));
        System.out.println("{\"companyName\":\"应宝科技\",\"endtime\":\"2024-03-01 17:19:00\",\"erpId\":\"4D40185D5BC74A13821BE46EAF8B4179\",\"erpWithVisitDTOList\":[],\"faceImg\":\"20240304/1709518170325_742.jpg\",\"idcardNo\":\"342501199609300535\",\"idcardType\":0,\"name\":\"黄晋\",\"phone\":\"17756328697\",\"reason\":\"探险\",\"receptMemberId\":\"E7E514BD7DE3F27CE0530B630A0AEAE0\",\"starttime\":\"2024-03-01 13:18:00\"}");
//        System.out.println("{\"companyName\":\"应宝科技\",\"endtime\":\"2024-03-01 17:19:00\",\"erpId\":\"4D40185D5BC74A13821BE46EAF8B4179\",\"erpWithVisitDTOList\":[],\"faceImg\":\"20240304/1709518170325_742.jpg\",\"idcardNo\":\"342501199609300535\",\"idcardType\":0,\"name\":\"黄晋\",\"phone\":\"17756328697\",\"reason\":\"探险\",\"receptMemberId\":\"E7E514BD7DE3F27CE0530B630A0AEAE0\",\"starttime\":\"2024-03-01 13:18:00\"}");
    }
    /**
     * 用户类型 0系统用户 1企业用户 2服务机构管理员 3服务机构子账号 4综合服务单位管理员 5综合服务单位子账号 6专家 7县区用户 8市局用户
@@ -707,7 +941,7 @@
    }
    public  enum ApplyCollectStatus {
        DSP(0, "待审批"),
        DSP(0, "待审核"),
        DCD(1, "待出单"),
        BZZ(2, "保障中"),
        YGQ(3, "已过期"),
@@ -721,6 +955,8 @@
        WTBDCD(23, "待出单"),
        WTBYTH(24, "已退回"),
        WTBYGB(25, "已关闭"),
        //2024年4月25日15:17:13 修改 投保中 = 》 批改申请中
        //2024-5-21 14:04:10 修改   批改申请中= 》投保中
        WTBTBZ(26, "投保中"),
        WTBBZZ(27, "保障中"),
        ;
@@ -791,6 +1027,7 @@
        CA_JIAJIAN_APPLY_SIGN(23, "加减保申请企业签章","",1),
        CA_CHANGUNIT_APPLY_SIGN(24, "换厂申请企业签章","",1),
        CA_UPLOAD_AGAIN(25, "再次投保","",1),
        CA_HBD_AUDIT(42, "审批通过","原因:${param}",1),
        WTB_FINISH_FAQRS(26, "委托保 - 企业完成签署方案确认书","",0),
        WTB_FINISH_MEMBER_LIST(27, "委托保 - 企业完成签署人员名单","",0),
@@ -808,6 +1045,7 @@
        IA_HBD_SIGNATURE_TBD(34, "商户签章","",3),
        IA_HBD_UPLOAD_INSURANCE(35, "投保完成","保险生效起期:${param1}变更为${param2}",3),
        IA_HBD_CLOSE(36, "退回申请","原因:${param}",3),
        IA_HBD_UPLOAD_BXD(41, "上传保险单","",3),
@@ -993,6 +1231,128 @@
            this.collectStatus = collectStatus;
        }
    }
    /**
     * 方案 周期单位
     *  coefficient  以半月为最小颗粒
     */
    public enum TimeUnit {
        DAY(0,"日",0),
        MONTH(2,"月",2),
        QUARTER(3,"季度",6),
        HALF_YEAR(4,"半年",12),
        YEAR(5,"年",24);
        private  Integer value;
        private  String des;
        private  Integer coefficient;
        TimeUnit(Integer value, String des, Integer coefficient) {
            this.value = value;
            this.des = des;
            this.coefficient = coefficient;
        }
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
        public String getDes() {
            return des;
        }
        public void setDes(String des) {
            this.des = des;
        }
        public Integer getCoefficient() {
            return coefficient;
        }
        public void setCoefficient(Integer coefficient) {
            this.coefficient = coefficient;
        }
        public static TimeUnit getTimeUnit(Integer value) {
            for (TimeUnit c : TimeUnit.values()) {
                if (Constants.equalsInteger(c.getValue() , value)) {
                    return c;
                }
            }
            return null;
        }
    }
    /**
     * 方案 周期单位 INSURE_CYCLE_UNIT
     *  coefficient  以半月为最小颗粒
     */
    public enum InsureCycleUnit {
        DAY(0,"日",new BigDecimal(1),0),
        HALF_MONTH(1,"半月",new BigDecimal(15.5),1),
        MONTH(2,"月",new BigDecimal(31),2),
        QUARTER(3,"季度",new BigDecimal(92),6),
        HALF_YEAR(4,"半年", new BigDecimal(184),12),
        YEAR(5,"年", new BigDecimal(365),24);
        private  Integer value;
        private  String des;
        private  BigDecimal days;
        private  Integer coefficient;
        public static InsureCycleUnit getInsureCycleUnit(Integer value) {
            for (InsureCycleUnit c : InsureCycleUnit.values()) {
                if (Constants.equalsInteger(c.getValue() , value)) {
                    return c;
                }
            }
            return null;
        }
        InsureCycleUnit(Integer value, String des,BigDecimal days, Integer coefficient) {
            this.value = value;
            this.des = des;
            this.days = days;
            this.coefficient = coefficient;
        }
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
        public String getDes() {
            return des;
        }
        public void setDes(String des) {
            this.des = des;
        }
        public BigDecimal getDays() {
            return days;
        }
        public void setDays(BigDecimal days) {
            this.days = days;
        }
        public Integer getCoefficient() {
            return coefficient;
        }
        public void setCoefficient(Integer coefficient) {
            this.coefficient = coefficient;
        }
    }
@@ -1233,9 +1593,9 @@
    public  enum NoticeType {
        ZERO(0, "待审批","","","待审核","待处理","处理中"),
        ZERO(0, "待审核","","","待审核","待处理","处理中"),
        ONE(1, "企业待签署","","","工种待审核","","已结案"),
        TWO(2, "待出单","待审批","待审批","","",""),
        TWO(2, "待出单","待审核","待审核","","",""),
        THREE(3, "申请退回","申请退回","申请退回","","",""),
        FOUR(4, "已退回","已退回","已退回","","","已撤销"),
        FIVE(5, "申请驳回","申请驳回","申请驳回","","",""),
@@ -1381,7 +1741,7 @@
        CLOSE(6, "已关闭"),
        CHECHED_PASSED(7, "审核通过"),
        PALTFORM_CHECK_PASS_NO(8, "审核不通过"),
        WTB_TOUBAOING(9, "投保中"),
        WTB_TOUBAOING(9, "批改申请中"),
        ;
        // 成员变量
        private String name;
@@ -1867,4 +2227,203 @@
            }
        }
    }
    /**
     * 减保 总费用
     * @param solutions
     * @param fee
     * @param startTime
     * @param endTime
     * @param reduceStartTime
     * @param reduceEndTime
     * @return
     */
    public static BigDecimal reduceFee(Solutions solutions,BigDecimal fee,Date startTime ,Date endTime,Date reduceStartTime,Date reduceEndTime){
        Integer days = DateUtil.daysBetweenDates(reduceEndTime, reduceStartTime) + 1;
        Integer countDays = DateUtil.daysBetweenDates(endTime, startTime) + 1;
        Constants.TimeUnit timeUnit = Constants.TimeUnit.getTimeUnit(solutions.getTimeUnit());
        Constants.InsureCycleUnit insureCycleUnit = Constants.InsureCycleUnit.getInsureCycleUnit(solutions.getInsureCycleUnit());
        if(solutions.getTimeUnit().equals(solutions.getInsureCycleUnit())){
            return fee;
        }else{
            if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.DAY.getValue())){
                //天为批改单位
                return fee.multiply(new BigDecimal(days)).divide(new BigDecimal(countDays),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_MONTH.getValue())) {
                //半月为批改单位
                BigDecimal cycle = new BigDecimal(days).divide(insureCycleUnit.getDays(),0,RoundingMode.CEILING);
                //根据投保周期 定义的 每个周期 = X个 半月周期 进行计算
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数
                return fee.multiply(cycle).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.MONTH.getValue())) {
                //月份为批改单位
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(reduceEndTime,reduceStartTime));
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 2
                return fee.multiply(cycle).multiply(new BigDecimal(2)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.QUARTER.getValue())) {
                //季度为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(reduceEndTime,reduceStartTime));
                //转换为 总季度
                cycle = cycle.divide(new BigDecimal(3),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(6)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_YEAR.getValue())) {
                //半年为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(reduceEndTime,reduceStartTime));
                //转换为 半年
                cycle = cycle.divide(new BigDecimal(6),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(12)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else {
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"方案配置错误");
            }
        }
    }
    /**
     * 加保业务 根据方案计算总费用
     * @param solutions
     * @param startTime
     * @param endTime
     * @param newStartTime
     * @return
     */
    public static BigDecimal addFee(Solutions solutions,BigDecimal fee,Date startTime ,Date endTime,Date newStartTime,Date newEndTime){
        Integer days = DateUtil.daysBetweenDates(newEndTime, newStartTime) + 1;
        Integer countDays = DateUtil.daysBetweenDates(endTime, startTime) + 1;
        Constants.TimeUnit timeUnit = Constants.TimeUnit.getTimeUnit(solutions.getTimeUnit());
        Constants.InsureCycleUnit insureCycleUnit = Constants.InsureCycleUnit.getInsureCycleUnit(solutions.getInsureCycleUnit());
        if(solutions.getTimeUnit().equals(solutions.getInsureCycleUnit())){
            return fee;
        }else{
            if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.DAY.getValue())){
                //天为批改单位
                return fee.multiply(new BigDecimal(days)).divide(new BigDecimal(countDays),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_MONTH.getValue())) {
                //半月为批改单位
                BigDecimal cycle = new BigDecimal(days).divide(insureCycleUnit.getDays(),0,RoundingMode.CEILING);
                //根据投保周期 定义的 每个周期 = X个 半月周期 进行计算
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数
                return fee.multiply(cycle).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.MONTH.getValue())) {
                //月份为批改单位
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(newEndTime,newStartTime));
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 2
                return fee.multiply(cycle).multiply(new BigDecimal(2)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.QUARTER.getValue())) {
                //季度为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(newEndTime,newStartTime));
                //转换为 总季度
                cycle = cycle.divide(new BigDecimal(3),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(6)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_YEAR.getValue())) {
                //半年为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(newEndTime,newStartTime));
                //转换为 半年
                cycle = cycle.divide(new BigDecimal(6),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(12)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else {
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"方案配置错误");
            }
        }
    }
    /**
     * 计算已产生费用
     * @param solutions
     * @param fee
     * @param startTime
     * @param endTime
     * @return
     */
    public static BigDecimal produceFee(Solutions solutions,BigDecimal fee,Date startTime ,Date endTime,Date produceStartTime){
        //超出天数
        Integer days = DateUtil.daysBetweenDates(DateUtil.getMontageDate(new Date(), 2), produceStartTime) + 1;
        Integer countDays = DateUtil.daysBetweenDates(endTime, startTime) + 1;
        Constants.TimeUnit timeUnit = Constants.TimeUnit.getTimeUnit(solutions.getTimeUnit());
        Constants.InsureCycleUnit insureCycleUnit = Constants.InsureCycleUnit.getInsureCycleUnit(solutions.getInsureCycleUnit());
        if(solutions.getTimeUnit().equals(solutions.getInsureCycleUnit())){
            return fee;
        }else{
            if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.DAY.getValue())){
                //天为批改单位
                return fee.multiply(new BigDecimal(days)).divide(new BigDecimal(countDays),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_MONTH.getValue())) {
                //半月为批改单位
                BigDecimal cycle = new BigDecimal(days).divide(insureCycleUnit.getDays(),0,RoundingMode.CEILING);
                //根据投保周期 定义的 每个周期 = X个 半月周期 进行计算
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数
                return fee.multiply(cycle).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.MONTH.getValue())) {
                //月份为批改单位
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(new Date(),startTime));
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 2
                return fee.multiply(cycle).multiply(new BigDecimal(2)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.QUARTER.getValue())) {
                //季度为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(new Date(),startTime));
                //转换为 总季度
                cycle = cycle.divide(new BigDecimal(3),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(6)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else if(solutions.getInsureCycleUnit().equals(Constants.InsureCycleUnit.HALF_YEAR.getValue())) {
                //半年为批改单位
                //查询产生费用总月份
                BigDecimal cycle = new BigDecimal(DateUtil.getDifferenceMonths(new Date(),startTime));
                //转换为 半年
                cycle = cycle.divide(new BigDecimal(6),0,RoundingMode.CEILING);
                // 总金额 * 产生费用的周期 / 投保周期定义的 半月周期数 * 6
                return fee.multiply(cycle).multiply(new BigDecimal(12)).divide(new BigDecimal(timeUnit.getCoefficient()),2, RoundingMode.HALF_UP);
            }else {
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"方案配置错误");
            }
        }
    }
    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(),"方案配置错误");
            }
        }
    }
}