package com.ydtech.modules.fee.service.impl; import com.ydtech.exception.SystemException; import com.ydtech.modules.admin.model.SysDept; import com.ydtech.modules.admin.model.SysUser; import com.ydtech.modules.admin.service.SysDeptService; import com.ydtech.modules.admin.service.SysUserService; import com.ydtech.modules.esm.model.EsmRetail; import com.ydtech.modules.esm.model.EsmUserReferrer; import com.ydtech.modules.esm.service.EsmRetailService; import com.ydtech.modules.esm.service.EsmUserReferrerService; import com.ydtech.modules.fee.dto.FeeFactorInfoDto; import com.ydtech.modules.fee.dto.FeeSchemeReqDto; import com.ydtech.modules.fee.dto.FeeSchemeResDto; import com.ydtech.modules.fee.service.FeeRuleSchemeService; import com.ydtech.modules.ins.model.vo.CarInfoVo; import com.ydtech.modules.ins.model.vo.KindInfoVo; import com.ydtech.modules.ins.model.vo.QuoteRespVo; import com.ydtech.modules.order.entity.InsFeeOrder; import com.ydtech.modules.order.entity.InsOrders; import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo; import com.ydtech.modules.order.service.InsFeeOrderService; import com.ydtech.modules.order.service.InsOrdersService; import com.ydtech.modules.protocol.entity.po.PtlAgreementProductCosts; import com.ydtech.modules.protocol.service.PtlAgreementProductCostsService; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * 费用接口中相关功能的实现类 */ @Service public class FeeRuleSchemeServiceImpl implements FeeRuleSchemeService { @Resource private PtlAgreementProductCostsService ptlAgreementProductCostsService; @Resource private InsOrdersService insOrdersService; @Resource private InsFeeOrderService insFeeOrderService; @Resource private SysUserService sysUserService; @Resource private SysDeptService sysDeptService; @Resource private EsmRetailService esmRetailService; @Resource private EsmUserReferrerService esmUserReferrerService; /** * 根据跟单信息,以及配置的费用因子,获取合适的跟单费用 * @param feeSchemeReqDto * @return */ public FeeSchemeResDto matchTheAppropriateFees(FeeSchemeReqDto feeSchemeReqDto) { FeeSchemeResDto feeSchemeResDto=new FeeSchemeResDto(); //先根据业务类别、有效期、协议编码、历史标志代码字段 获取对应费用方案列表 List ptlAgreementProductCosts =ptlAgreementProductCostsService.selectVliadFeeFactor(feeSchemeReqDto.getBusType(),feeSchemeReqDto.getAgreementId()); if (ptlAgreementProductCosts.isEmpty()) { //如果查询不到费用方案信息,则阻断算费流程,进行提示 throw new SystemException("未查询到费用配置,请先配置该协议的费用方案!"); }else{ //符合跟单信息的方案列表 List validSchemeList=new ArrayList(); //循环符合的方案列表,再进行细化的因子匹配,获取最终可以匹配到的方案 for(int i=0;i factorToBeVerified=getFactorToBeVerified(factorCost); //按规则拼接跟单信息 String matchKeyStr=getMatchKeyWithInsuranceInfo(feeSchemeReqDto); //循环进行各项因子校验 boolean checkFlag=checkFactorValidWithInsuranceInfo(matchKeyStr,factorToBeVerified); //如果该方案所有因子都校验通过,则放入符合校验方案列表 if(checkFlag){ validSchemeList.add(factorCost); } } if(validSchemeList.size()>0){ //先判断匹配到的是不是只有兜底类型,如果不是则过滤掉兜底类型的费用,优先以跟单的为准,如果只有兜底类型,则按同样逻辑进行筛选 //根据ProductId去重后的结果集 List tempList=validSchemeList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(PtlAgreementProductCosts :: getProductId))), ArrayList::new)); if(tempList.size()>1){//如果有多种类型,则过滤掉兜底类型的 validSchemeList=validSchemeList.stream().filter(x -> !"039999".equals(x.getProductId())).collect(Collectors.toList()); } //匹配到唯一一条费用方案,直接用这条 if(validSchemeList.size()==1){ //进行费用比例赋值,给返回对象 feeSchemeResDto=generateSchemeResDto((PtlAgreementProductCosts)validSchemeList.get(0)); }else{ //如果最终符合的有多条,则按特殊规则选择其中一条 PtlAgreementProductCosts finalSchemeCost=changeSchemeWithSpecialRule(validSchemeList,feeSchemeReqDto); //进行费用比例赋值,给返回对象 feeSchemeResDto=generateSchemeResDto(finalSchemeCost); } }else{ throw new SystemException("未匹配到合适的费用方案,请先配置该协议的费用方案!"); } } return feeSchemeResDto; } /** * 特殊处理选择费用方案 * 如果最终符合的有多条,则先看交强、商业谁的保费多,然后根据保费多得在匹配到的方案中找费用比例大的那一条 * @param validSchemeList * @param feeSchemeReqDto * @return */ private PtlAgreementProductCosts changeSchemeWithSpecialRule(List validSchemeList, FeeSchemeReqDto feeSchemeReqDto) { PtlAgreementProductCosts finalScheme=null; //险种标志,最终取哪个险种费用比例 1取交强 2取商业 String riskFlag=""; //判断险种标志 if("0330".equals(feeSchemeReqDto.getBusType())){//单交 riskFlag="1"; }else if("034001".equals(feeSchemeReqDto.getBusType())){//单商 riskFlag="2"; }else if("034002".equals(feeSchemeReqDto.getBusType())){//单三 riskFlag="2"; }else if("0330034002".equals(feeSchemeReqDto.getBusType())){//交三 if(Double.parseDouble(feeSchemeReqDto.getJqPremium())<=Double.parseDouble(feeSchemeReqDto.getSyPremium())){ riskFlag="2"; }else{ riskFlag="1"; } }else if("0330034001".equals(feeSchemeReqDto.getBusType())){//交商 if(Double.parseDouble(feeSchemeReqDto.getJqPremium())<=Double.parseDouble(feeSchemeReqDto.getSyPremium())){ riskFlag="2"; }else{ riskFlag="1"; } } //循环找出对应比例最大的 for(int i=0;i factorToBeVerified) { boolean result=false; //默认没有匹配到 String[] matchKeys= matchKeyStr.split(","); //循环待校验因子列表 for(Map.Entry entry : factorToBeVerified.entrySet()){ Integer key=entry.getKey(); FeeFactorInfoDto checkFactorInfo=entry.getValue(); //先看该方案是否需要匹配该因子,不需要则跳过本条因子 if(!checkFactorInfo.isNeedMatch()){ continue; } //下面处理需要进行匹配的因子 if("1".equals(checkFactorInfo.getMatchType())){//1.单字符串匹配(相等) if(matchKeys[key]!=null&&!"".equals(matchKeys[key])){ if(checkFactorInfo.getSingleSelectVal().equals(matchKeys[key])){ result=true; continue; }else{ //如果需要匹配且没有匹配到,则直接跳出本次循环,该方案不符合 result=false; break; } }else{ //判断跟单信息是否为空,如果为空,则直接没有匹配到,该方案不符合 result=false; break; } }else if("2".equals(checkFactorInfo.getMatchType())){//2.多字符串匹配(包含) if(matchKeys[key]!=null&&!"".equals(matchKeys[key])){ //如果需要匹配,且匹配成功,则跳过本次循环,继续校验下一因子 if(checkFactorInfo.getMultipleSelectVal().indexOf(matchKeys[key])>-1){ result=true; continue; }else{ //如果需要匹配且没有匹配到,则直接跳出循环,该方案不符合 result=false; break; } }else{ //判断跟单信息是否为空,如果为空,则直接没有匹配到,该方案不符合 result=false; break; } }else if("3".equals(checkFactorInfo.getMatchType())){//3.区间范围比较(左闭右闭) if(matchKeys[key]!=null&&NumberUtils.isDigits(matchKeys[key])){ //如果需要匹配,且匹配成功,则跳过本次循环,继续校验下一因子 if(Integer.parseInt(matchKeys[key])>=checkFactorInfo.getMinRangeVal()&&Integer.parseInt(matchKeys[key])<=checkFactorInfo.getMaxRangeVal()){ result=true; continue; }else{ //如果需要匹配且没有匹配到,则直接跳出循环,该方案不符合 result=false; break; } }else{ //判断跟单信息是否为空和可转整型,如果不符,则直接没有匹配到,该方案不符合 result=false; break; } } } return result; } /** * 根据跟单信息,按照约定顺序进行拼接匹配串 * 新增因子时,顺序需要与getFactorToBeVerified()方法放入待校验因子一致 * @param feeSchemeReqDto * @return */ private String getMatchKeyWithInsuranceInfo(FeeSchemeReqDto feeSchemeReqDto) { StringBuffer result=new StringBuffer(); result.append(feeSchemeReqDto.getIsTransfer()).append(","); result.append(feeSchemeReqDto.getIsNewCar()).append(","); result.append(feeSchemeReqDto.getIsNewEnergy()).append(","); result.append(feeSchemeReqDto.getIsRenewal()).append(","); result.append(feeSchemeReqDto.getVehicleCategory()).append(","); result.append(feeSchemeReqDto.getUseNature()).append(","); result.append(feeSchemeReqDto.getSeatNum()).append(","); result.append(feeSchemeReqDto.getPurchasePrice()).append(","); result.append(feeSchemeReqDto.getApprovedLoadCapacity()).append(","); result.append(feeSchemeReqDto.getJqPremium()).append(","); result.append(feeSchemeReqDto.getSumPayTax()).append(","); result.append(feeSchemeReqDto.getThirdPartyInsurance()).append(","); result.append(feeSchemeReqDto.getNoCarPremium()).append(","); result.append(feeSchemeReqDto.getSyDiscount()).append(","); result.append(feeSchemeReqDto.getJqDiscount()).append(","); result.append(feeSchemeReqDto.getInsuranceScore()).append(","); result.append(feeSchemeReqDto.getExpectedLossRate()).append(","); result.append(feeSchemeReqDto.getLicenseNo()); return result.toString(); } /** * 根据配置的因子表数据,组装标准的待校验因子列表 * 新增因子时,顺序需要与getMatchKeyWithInsuranceInfo()方法放入跟单信息一致 * @param factorCost * @return */ private Map getFactorToBeVerified(PtlAgreementProductCosts factorCost) { Map resultMqp=new HashMap<>(); //以下各项因子必须按顺序放入MAP,以便校验时关联 //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor0=new FeeFactorInfoDto(); factor0.setFactorName("是否过户"); factor0.setMatchType("1"); factor0.setMatchSequence(0); if(factorCost.getTransfer()!=null&&factorCost.getTransfer()!=9){ factor0.setNeedMatch(true); factor0.setSingleSelectVal(String.valueOf(factorCost.getTransfer())); }else{ //如果方案中未录入(是空或为9时),则不校验该项因子 factor0.setNeedMatch(false); } resultMqp.put(0,factor0); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor1=new FeeFactorInfoDto(); factor1.setFactorName("新旧车"); factor1.setMatchType("1"); factor1.setMatchSequence(1); if(factorCost.getOldAndNew()!=null&&factorCost.getOldAndNew()!=9){ factor1.setNeedMatch(true); factor1.setSingleSelectVal(String.valueOf(factorCost.getOldAndNew())); }else{ //如果方案中未录入(是空或为9时),则不校验该项因子 factor1.setNeedMatch(false); } resultMqp.put(1,factor1); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor2=new FeeFactorInfoDto(); factor2.setFactorName("是否新能源"); factor2.setMatchType("1"); factor2.setMatchSequence(2); if(factorCost.getNewEnergy()!=null&&factorCost.getNewEnergy()!=9){ factor2.setNeedMatch(true); factor2.setSingleSelectVal(String.valueOf(factorCost.getNewEnergy())); }else{ //如果方案中未录入(是空或为9时),则不校验该项因子 factor2.setNeedMatch(false); } resultMqp.put(2,factor2); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor3=new FeeFactorInfoDto(); factor3.setFactorName("是否续保"); factor3.setMatchType("1"); factor3.setMatchSequence(3); if(factorCost.getRenewal()!=null&&factorCost.getRenewal()!=9){ factor3.setNeedMatch(true); factor3.setSingleSelectVal(String.valueOf(factorCost.getRenewal())); }else{ //如果方案中未录入(是空或为9时),则不校验该项因子 factor3.setNeedMatch(false); } resultMqp.put(3,factor3); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor4=new FeeFactorInfoDto(); factor4.setFactorName("车辆大类"); factor4.setMatchType("2"); factor4.setMatchSequence(4); if(factorCost.getVehicleCategory()!=null&&!"".equals(factorCost.getVehicleCategory())){ factor4.setNeedMatch(true); factor4.setMultipleSelectVal(String.valueOf(factorCost.getVehicleCategory())); }else{ //如果方案中未录入,则不校验该项因子 factor4.setNeedMatch(false); } resultMqp.put(4,factor4); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor5=new FeeFactorInfoDto(); factor5.setFactorName("使用性质"); factor5.setMatchType("2"); factor5.setMatchSequence(5); if(factorCost.getNatureOfUse()!=null&&!"".equals(factorCost.getNatureOfUse())){ factor5.setNeedMatch(true); factor5.setMultipleSelectVal(String.valueOf(factorCost.getNatureOfUse())); }else{ //如果方案中未录入,则不校验该项因子 factor5.setNeedMatch(false); } resultMqp.put(5,factor5); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor6=new FeeFactorInfoDto(); factor6.setFactorName("客车座位数区间"); factor6.setMatchType("3"); factor6.setMatchSequence(6); if(checkFactorConfigWithArea(factorCost.getMinSeats(),factorCost.getMaxSeats(),factor6,factorCost)){ factor6.setNeedMatch(true); factor6.setMinRangeVal(factorCost.getMinSeats()); factor6.setMaxRangeVal(factorCost.getMaxSeats()); }else{ //如果方案中未录入,则不校验该项因子 factor6.setNeedMatch(false); } resultMqp.put(6,factor6); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor7=new FeeFactorInfoDto(); factor7.setFactorName("新车购置价区间"); factor7.setMatchType("3"); factor7.setMatchSequence(7); if(checkFactorConfigWithArea(factorCost.getMinPurchasePrice(),factorCost.getMaxPurchasePrice(),factor7,factorCost)){ factor7.setNeedMatch(true); factor7.setMinRangeVal(factorCost.getMinPurchasePrice()); factor7.setMaxRangeVal(factorCost.getMaxPurchasePrice()); }else{ //如果方案中未录入,则不校验该项因子 factor7.setNeedMatch(false); } resultMqp.put(7,factor7); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor8=new FeeFactorInfoDto(); factor8.setFactorName("核定载质量区间"); factor8.setMatchType("3"); factor8.setMatchSequence(8); if(checkFactorConfigWithArea(factorCost.getMinApprovedLoadCapacity(),factorCost.getMaxApprovedLoadCapacity(),factor8,factorCost)){ factor8.setNeedMatch(true); factor8.setMinRangeVal(factorCost.getMinApprovedLoadCapacity()); factor8.setMaxRangeVal(factorCost.getMaxApprovedLoadCapacity()); }else{ //如果方案中未录入,则不校验该项因子 factor8.setNeedMatch(false); } resultMqp.put(8,factor8); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor9=new FeeFactorInfoDto(); factor9.setFactorName("交强险保费区间"); factor9.setMatchType("3"); factor9.setMatchSequence(9); if(checkFactorConfigWithArea(factorCost.getMinCompulsoryInsurancePremium(),factorCost.getMaxCompulsoryInsurancePremium(),factor9,factorCost)){ factor9.setNeedMatch(true); factor9.setMinRangeVal(factorCost.getMinCompulsoryInsurancePremium()); factor9.setMaxRangeVal(factorCost.getMaxCompulsoryInsurancePremium()); }else{ //如果方案中未录入,则不校验该项因子 factor9.setNeedMatch(false); } resultMqp.put(9,factor9); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor10=new FeeFactorInfoDto(); factor10.setFactorName("车船税金额区间"); factor10.setMatchType("3"); factor10.setMatchSequence(10); if(checkFactorConfigWithArea(factorCost.getMinTaxAmount(),factorCost.getMaxTaxAmount(),factor10,factorCost)){ factor10.setNeedMatch(true); factor10.setMinRangeVal(factorCost.getMinTaxAmount()); factor10.setMaxRangeVal(factorCost.getMaxTaxAmount()); }else{ //如果方案中未录入,则不校验该项因子 factor10.setNeedMatch(false); } resultMqp.put(10,factor10); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor11=new FeeFactorInfoDto(); factor11.setFactorName("三者保额区间"); factor11.setMatchType("3"); factor11.setMatchSequence(11); if(checkFactorConfigWithArea(factorCost.getMinTheThreePremium(),factorCost.getMaxTheThreePremium(),factor11,factorCost)){ factor11.setNeedMatch(true); factor11.setMinRangeVal(factorCost.getMinTheThreePremium()); factor11.setMaxRangeVal(factorCost.getMaxTheThreePremium()); }else{ //如果方案中未录入,则不校验该项因子 factor11.setNeedMatch(false); } resultMqp.put(11,factor11); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor12=new FeeFactorInfoDto(); factor12.setFactorName("随车产品保费区间"); factor12.setMatchType("3"); factor12.setMatchSequence(12); if(checkFactorConfigWithArea(factorCost.getMinOnboardProductsPremium(),factorCost.getMaxOnboardProductsPremium(),factor12,factorCost)){ factor12.setNeedMatch(true); factor12.setMinRangeVal(factorCost.getMinOnboardProductsPremium()); factor12.setMaxRangeVal(factorCost.getMaxOnboardProductsPremium()); }else{ //如果方案中未录入,则不校验该项因子 factor12.setNeedMatch(false); } resultMqp.put(12,factor12); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor13=new FeeFactorInfoDto(); factor13.setFactorName("商业险折扣区间"); factor13.setMatchType("3"); factor13.setMatchSequence(13); if(checkFactorConfigWithArea(factorCost.getMinCommercialInsuranceDiscount(),factorCost.getMaxCommercialInsuranceDiscount(),factor13,factorCost)){ factor13.setNeedMatch(true); factor13.setMinRangeVal(factorCost.getMinCommercialInsuranceDiscount()); factor13.setMaxRangeVal(factorCost.getMaxCommercialInsuranceDiscount()); }else{ //如果方案中未录入,则不校验该项因子 factor13.setNeedMatch(false); } resultMqp.put(13,factor13); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor14=new FeeFactorInfoDto(); factor14.setFactorName("交强险折扣区间"); factor14.setMatchType("3"); factor14.setMatchSequence(14); if(checkFactorConfigWithArea(factorCost.getMinCompulsoryInsuranceDiscount(),factorCost.getMaxCompulsoryInsuranceDiscount(),factor14,factorCost)){ factor14.setNeedMatch(true); factor14.setMinRangeVal(factorCost.getMinCompulsoryInsuranceDiscount()); factor14.setMaxRangeVal(factorCost.getMaxCompulsoryInsuranceDiscount()); }else{ //如果方案中未录入,则不校验该项因子 factor14.setNeedMatch(false); } resultMqp.put(14,factor14); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor15=new FeeFactorInfoDto(); factor15.setFactorName("保司评分区间"); factor15.setMatchType("3"); factor15.setMatchSequence(15); if(checkFactorConfigWithArea(factorCost.getMinScore(),factorCost.getMaxScore(),factor15,factorCost)){ factor15.setNeedMatch(true); factor15.setMinRangeVal(factorCost.getMinScore()); factor15.setMaxRangeVal(factorCost.getMaxScore()); }else{ //如果方案中未录入,则不校验该项因子 factor15.setNeedMatch(false); } resultMqp.put(15,factor15); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor16=new FeeFactorInfoDto(); factor16.setFactorName("预期赔付率区间"); factor16.setMatchType("3"); factor16.setMatchSequence(16); if(checkFactorConfigWithArea(factorCost.getMinLossRation(),factorCost.getMaxLossRation(),factor16,factorCost)){ factor16.setNeedMatch(true); factor16.setMinRangeVal(factorCost.getMinLossRation()); factor16.setMaxRangeVal(factorCost.getMaxLossRation()); }else{ //如果方案中未录入,则不校验该项因子 factor16.setNeedMatch(false); } resultMqp.put(16,factor16); //--------------------因子处理分割线---------------------------------- FeeFactorInfoDto factor17=new FeeFactorInfoDto(); factor17.setFactorName("车牌号地区"); factor17.setMatchType("2"); factor17.setMatchSequence(17); if(factorCost.getLicenseNumber()!=null&&!"".equals(factorCost.getLicenseNumber())){ factor17.setNeedMatch(true); String matchStr=factorCost.getLicenseNumber(); //考虑是否含暂未上牌标志 if(factorCost.getContainNoLicense()!=null&&"1".equals(factorCost.getContainNoLicense())){ matchStr=matchStr+",暂未上牌"; } factor17.setMultipleSelectVal(matchStr); }else{ //如果方案中未录入,则不校验该项因子 factor17.setNeedMatch(false); } resultMqp.put(17,factor17); return resultMqp; } /** * 判断区间类因子是否需要匹配 * @param minVal * @param maxVal * @param factorInfoDto * @param productCosts * @return */ private boolean checkFactorConfigWithArea(Integer minVal, Integer maxVal,FeeFactorInfoDto factorInfoDto,PtlAgreementProductCosts productCosts) { boolean result=false; //默认不需要匹配 if(minVal!=null&&maxVal!=null){ if(minVal==0&&maxVal==0){//初始化没有配置的时候,全部默认的0,这种不需要匹配 result=false; }else{ if(minVal<=maxVal){ result=true; }else{ throw new SystemException("协议ID:"+productCosts.getAgreementId()+" 方案序号:"+productCosts.getId()+" 费用因子:"+factorInfoDto.getFactorName()+"配置有问题,请检查!"); } } }else if(minVal!=null && maxVal==null){ throw new SystemException("协议ID:"+productCosts.getAgreementId()+" 方案序号:"+productCosts.getId()+" 费用因子:"+factorInfoDto.getFactorName()+"配置有问题,请检查!"); }else if(minVal==null&&maxVal!=null){ throw new SystemException("协议ID:"+productCosts.getAgreementId()+" 方案序号:"+productCosts.getId()+" 费用因子:"+factorInfoDto.getFactorName()+"配置有问题,请检查!"); } return result; } //----------------------------------------------分割线 public FeeSchemeReqDto getFeeSchemeInfo(BaseQuoteInfoVo quoteInfoVo, QuoteRespVo quoteRespVo, String agreementId, String productId){ CarInfoVo carInfoVo = quoteInfoVo.getCarInfo(); List kindList = quoteInfoVo.getKindList(); String thirdPartyInsurance = ""; if(kindList!=null && kindList.size()>0){ for(KindInfoVo kindInfoVo:kindList){ if("B".equals(kindInfoVo.getKindCode())){ thirdPartyInsurance = String.valueOf(kindInfoVo.getAmount()); } } } FeeSchemeReqDto feeSchemeReqDto = new FeeSchemeReqDto(); String isTransfer = "0"; String isNewCar = "0"; String isRenewal = "0"; String useNature = "家庭自用"; String carType="客车"; String isNewEnergy = "0"; feeSchemeReqDto.setBusType(productId);//"业务类型:单交0330、单商034001、单三034002、交三0330034002、交商0330034001" feeSchemeReqDto.setAgreementId(agreementId);//协议ID if(carInfoVo.isTransferFlag()){ isTransfer = "1"; } feeSchemeReqDto.setIsTransfer(isTransfer);//是否过户 1是 0否" if(!carInfoVo.isUsedCar()){ isNewCar = "1"; } feeSchemeReqDto.setIsNewCar(isNewCar);//是否新车 1是 0否 if("1".equals(carInfoVo.getPowertype())||"2".equals(carInfoVo.getPowertype())||"3".equals(carInfoVo.getPowertype())){ isNewEnergy = "1"; } feeSchemeReqDto.setIsNewEnergy(isNewEnergy);//是否新能源 1是 0否 feeSchemeReqDto.setIsRenewal("0");//是否续保 1是 0否 续保取值有争议 默认送否 暂时搁置 //页面要素及中煤交互请求返参没有,先默认写死 if("A0".equals(carInfoVo.getCimodelclass())){ carType="客车"; } feeSchemeReqDto.setVehicleCategory(carType);//车辆大类: 客车、货车、特种车、挂车、摩托车、拖拉机 if("8A".equals(carInfoVo.getCarnature())){ useNature = "家庭自用"; } feeSchemeReqDto.setUseNature(useNature);//使用性质: 营业出租、营业租赁、营业公交、营业客运、营业货运、营业旅游、家庭自用、非营业机关事业、非营业企业、非营业个人 feeSchemeReqDto.setSeatNum(String.valueOf(carInfoVo.getSeatCount()));//座位数 大概率准 feeSchemeReqDto.setPurchasePrice(carInfoVo.getPurchasePrice());//新车购置价 可能再次新车筛选的时候送保司和页面带入有差异 feeSchemeReqDto.setApprovedLoadCapacity(String.valueOf(carInfoVo.getLimitLoad()));//核定载质量 可能再次新车筛选的时候送保司和页面带入有差异 feeSchemeReqDto.setJqPremium(String.valueOf(quoteRespVo.getJqPremium()));//交强保费 feeSchemeReqDto.setSyPremium(String.valueOf(quoteRespVo.getSyPremium()));//商业保费 feeSchemeReqDto.setSumPayTax(String.valueOf(quoteRespVo.getTaxAmount()));//车船税金额 feeSchemeReqDto.setThirdPartyInsurance(thirdPartyInsurance);//三者险保额 准 feeSchemeReqDto.setNoCarPremium("");//随车产品保费 feeSchemeReqDto.setSyDiscount("");//商业险折扣 feeSchemeReqDto.setJqDiscount("");//交强险折扣 // feeSchemeReqDto.setInsuranceScore(quotedPriceResponse.getPlatMain().getZmScore());//保司评分 这里直接取中煤分 feeSchemeReqDto.setExpectedLossRate("");//预期赔付率 if(carInfoVo.getLicenseNo()!=null&&!"".equals(carInfoVo.getLicenseNo())&&!"暂未上牌".equals(carInfoVo.getLicenseNo())){ feeSchemeReqDto.setLicenseNo(carInfoVo.getLicenseNo().substring(0,2));//车牌号 }else{ feeSchemeReqDto.setLicenseNo("暂未上牌");//车牌号 } return feeSchemeReqDto; } public void dealFeeOrderInfo(BaseQuoteInfoVo quoteInfoVo, QuoteRespVo quoteRespVo, String agreementId,String businessNo){ BigDecimal jqNoTaxPremium = new BigDecimal(0); BigDecimal syNoTaxPremium = new BigDecimal(0); InsOrders insOrders = insOrdersService.getById(quoteRespVo.getOrderno()); FeeSchemeReqDto feeSchemeReqDto = this.getFeeSchemeInfo(quoteInfoVo,quoteRespVo,agreementId,insOrders.getProductid()); FeeSchemeResDto feeSchemeResDto = this.matchTheAppropriateFees(feeSchemeReqDto); InsFeeOrder insFeeOrder = new InsFeeOrder(feeSchemeReqDto,feeSchemeResDto,businessNo); //先通过含税保费计算出不含税保费 公式 总保费/(1+增值税率) 目前增值税率是0.06 if(insFeeOrder.getJqPremium().doubleValue()>0){ jqNoTaxPremium = insFeeOrder.getJqPremium().divide(new BigDecimal(1+0.06),BigDecimal.ROUND_HALF_UP,2); insFeeOrder.setJqNoTaxPremium(jqNoTaxPremium); //交强险总费用 insFeeOrder.setJqCostsPremiums(getPremium(jqNoTaxPremium,insFeeOrder.getJqCostsProportion())); //监管费比例 if("1".equals(feeSchemeReqDto.getIsNewCar())){ insFeeOrder.setJqSuperviseCostsProportion(new BigDecimal(feeSchemeResDto.getJqNewCarCostsProportion())); }else if("0".equals(feeSchemeReqDto.getIsNewCar())){ insFeeOrder.setJqSuperviseCostsProportion(new BigDecimal(feeSchemeResDto.getJqOldCarCostsProportion())); }else{ insFeeOrder.setJqSuperviseCostsProportion(new BigDecimal(0)); } //监管费 insFeeOrder.setJqSuperviseCostsPremiums(getPremium(jqNoTaxPremium,insFeeOrder.getJqSuperviseCostsProportion())); //溢出费比例 先搁置放0 insFeeOrder.setJqSpilloverProportion(new BigDecimal(feeSchemeResDto.getJqSpilloverProportion())); //溢出费 先搁置放0 insFeeOrder.setJqSpilloverPremiums(getPremium(jqNoTaxPremium,insFeeOrder.getJqSpilloverProportion())); } if(insFeeOrder.getSyPremium().doubleValue()>0){ syNoTaxPremium = insFeeOrder.getJqPremium().divide(new BigDecimal(1+0.06),BigDecimal.ROUND_HALF_UP,2); insFeeOrder.setSyNoTaxPremium(syNoTaxPremium); //商业险总费用 insFeeOrder.setSyCostsPremiums(getPremium(syNoTaxPremium,insFeeOrder.getJqCostsProportion())); //监管费比例 if("1".equals(feeSchemeReqDto.getIsNewCar())){ insFeeOrder.setSySuperviseCostsProportion(new BigDecimal(feeSchemeResDto.getJqNewCarCostsProportion())); }else if("0".equals(feeSchemeReqDto.getIsNewCar())){ insFeeOrder.setSySuperviseCostsProportion(new BigDecimal(feeSchemeResDto.getJqOldCarCostsProportion())); }else{ insFeeOrder.setSySuperviseCostsProportion(new BigDecimal(0)); } //监管费 insFeeOrder.setSySuperviseCostsPremiums(getPremium(syNoTaxPremium,insFeeOrder.getJqSuperviseCostsProportion())); //溢出费比例 先搁置放0 insFeeOrder.setSySpilloverProportion(new BigDecimal(feeSchemeResDto.getJqSpilloverProportion())); //溢出费 先搁置放0 insFeeOrder.setSySpilloverPremiums(getPremium(syNoTaxPremium,insFeeOrder.getJqSpilloverProportion())); } if(jqNoTaxPremium.doubleValue() >0 || syNoTaxPremium.doubleValue() >0){ BigDecimal totalNoTaxPremium = jqNoTaxPremium.add(syNoTaxPremium); SysUser sysUser = sysUserService.findByUserId(insOrders.getUserid()); /** * 机构管理费比例逻辑 * 当前出单员的机构编码找他的上一级就是五级 * 机构层级划分方式 * 99 总公司 一级 * 9914山西分公司 二级 * 991401太原中支 三级 * 99140105小店中支 四级 * 9914010501 营销服务部 五级 * 1团队 无机构层级 */ SysDept sysDept = sysDeptService.getById(sysUser.getDeptId()); if(StringUtils.isNotEmpty(sysDept.getComlevel())){ throw new SystemException("当前出单员归属团队有误,请检查机构层级配置!"); } //得到五级机构 SysDept sysDeptFifth = sysDeptService.getById(sysDept.getParentId()); SysDept sysDeptForth = sysDeptService.getById(sysDeptFifth.getParentId()); SysDept sysDeptThird = sysDeptService.getById(sysDeptForth.getParentId()); SysDept sysDeptSecond = sysDeptService.getById(sysDeptThird.getParentId()); SysDept sysDeptFirst = sysDeptService.getById(sysDeptSecond.getParentId()); //五级机构管理费用比例 if(sysDeptFifth!=null && "5".equals(sysDeptFifth.getComlevel())){ insFeeOrder.setFifthDeptProportion(new BigDecimal(sysDeptFifth.getManagementFee())); insFeeOrder.setFifthDeptPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getFifthDeptProportion())); } //四级机构管理费用比例 if(sysDeptForth!=null && "4".equals(sysDeptForth.getComlevel())){ insFeeOrder.setForthDeptProportion(new BigDecimal(sysDeptForth.getManagementFee())); insFeeOrder.setForthDeptPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getForthDeptProportion())); } //三级机构管理费用比例 if(sysDeptThird!=null && "3".equals(sysDeptThird.getComlevel())){ insFeeOrder.setThirdDeptProportion(new BigDecimal(sysDeptThird.getManagementFee())); insFeeOrder.setThirdDeptPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getThirdDeptProportion())); } //二级机构管理费用比例 if(sysDeptSecond!=null && "2".equals(sysDeptSecond.getComlevel())){ insFeeOrder.setSecondDeptProportion(new BigDecimal(sysDeptSecond.getManagementFee())); insFeeOrder.setSecondDeptPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getSecondDeptProportion())); } //一级机构管理费用比例 if(sysDeptFirst!=null && "1".equals(sysDeptFirst.getComlevel())){ insFeeOrder.setFirstDeptProportion(new BigDecimal(sysDeptFirst.getManagementFee())); insFeeOrder.setFirstDeptPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getFirstDeptProportion())); } //一级分销比例 推荐人 //二级分销比例 //三级分销比例 /** * 分销一级、二级、三级存值取团队配置的分销佣金比例,若该团队走三级分销模式,当前出单员出单时,跟单的分销取值方式为: * 根据出单员的推荐人向上找三级,若可以找到,则跟单存一、二、三分销比例; * 若向上只能找到一级或者二级,则跟单存一级或者一级、二级 * 比如 A 1 B 2 C 3 D 若D出单 则给 C 3个 B 2个 A 1个;C出单给 B 3个 A 2个 * 第一步,先判断团队配置的分销模式 * 第二步,根据分销模式找上级存值相应分销比例 * 第三步,仅有一个上级的情况分销比例存啥 */ List esmRetailList = esmRetailService.selectList(" where t.deptid=? and t.status = '1' ", new Object[]{sysUser.getDeptId()}); if(esmRetailList!=null && esmRetailList.size()>0){ EsmRetail esmRetail = esmRetailList.get(0); if(esmRetail!=null){ int cycleIndex = 0; if("3".equals(esmRetail.getRetailtype())){//团队配置了三级分销模式 cycleIndex = 3; }else if("2".equals(esmRetail.getRetailtype())){//团队配置了二级分销模式 cycleIndex = 2; }else if("1".equals(esmRetail.getRetailtype())){//团队配置了一级分销模式 cycleIndex = 1; }else if("0".equals(esmRetail.getRetailtype())){//团队没有配置分销模式 cycleIndex = 0; } //利用当前工号,循环向上找推荐人 String userId = sysUser.getId(); int breakCycle = 99999999; for(int i=0;i<=cycleIndex;i++){ EsmUserReferrer userReferrer = esmUserReferrerService.getById(userId); if(userReferrer.getReferrerId().equals(userReferrer.getId())){//团队长,没有上级 //跳出循环 breakCycle = i; break; }else { userId = userReferrer.getReferrerId(); } } //breakCycle是3,当前工号的上级的上级的上级就是团队长 //breakCycle是2,当前工号的上级的上级就是团队长 //breakCycle是1,当前工号的上级就是团队长 //breakCycle是0,当前工号就是团队长 if("3".equals(esmRetail.getRetailtype())){//团队配置了三级分销模式 if(breakCycle==99999999||breakCycle==3){ insFeeOrder.setFirstRetailProportion(new BigDecimal(esmRetail.getDisrate1())); insFeeOrder.setSecondRetailProportion(new BigDecimal(esmRetail.getDisrate2())); insFeeOrder.setThirdRetailProportion(new BigDecimal(esmRetail.getDisrate3())); }else if(breakCycle==2){ insFeeOrder.setSecondRetailProportion(new BigDecimal(esmRetail.getDisrate2())); insFeeOrder.setThirdRetailProportion(new BigDecimal(esmRetail.getDisrate3())); }else if(breakCycle==1){ insFeeOrder.setThirdRetailProportion(new BigDecimal(esmRetail.getDisrate3())); } }else if("2".equals(esmRetail.getRetailtype())){//团队配置了二级分销模式 if(breakCycle==99999999||breakCycle==3 || breakCycle==2){ insFeeOrder.setFirstRetailProportion(new BigDecimal(esmRetail.getDisrate1())); insFeeOrder.setSecondRetailProportion(new BigDecimal(esmRetail.getDisrate2())); }else if(breakCycle==1){ insFeeOrder.setSecondRetailProportion(new BigDecimal(esmRetail.getDisrate2())); } }else if("1".equals(esmRetail.getRetailtype())){//团队配置了一级分销模式 if(breakCycle==99999999||breakCycle==3 || breakCycle==2||breakCycle==1){ insFeeOrder.setFirstRetailProportion(new BigDecimal(esmRetail.getDisrate1())); } } insFeeOrder.setFirstRetailPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getFirstRetailProportion())); insFeeOrder.setSecondRetailPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getSecondRetailProportion())); insFeeOrder.setThirdRetailPremiums(getPremium(totalNoTaxPremium,insFeeOrder.getThirdRetailProportion())); } } } insFeeOrderService.insertCompanyAndOrders(insFeeOrder); } private BigDecimal getPremium(BigDecimal noTaxPremium,BigDecimal costsProportion){ BigDecimal premium = new BigDecimal(0); if(costsProportion!=null && costsProportion.doubleValue()>0){ premium = noTaxPremium.multiply(costsProportion).divide(new BigDecimal(100),4,BigDecimal.ROUND_HALF_UP); } return premium; } }