Przeglądaj źródła

Merge branch 'master' into wrq_dev

wangrq 3 miesięcy temu
rodzic
commit
c1b45e8c4f

+ 4 - 0
tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/service/impl/RenBaoNewCrawlerRequestImpl.java

@@ -306,6 +306,10 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
         if (error == null) {
             return false;
         }
+        if (error.contains("重复投保")) {
+            return false;
+        }
+
         // 匹配 Python 的判断逻辑(第 4773-4787 行)
         return error.contains("成功")
                 || error.contains("此单符合续保条件,已按照续保流程处理")

+ 31 - 20
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java

@@ -303,7 +303,7 @@ public class QuoteVerificationAspect {
         calculateTotalPremium(insFeeOrders);
 
         // 8. 计算分销费用
-        calculateDistributionFee(insOrdersCosts,insFeeOrders, insOrders);
+//        calculateDistributionFee(insOrdersCosts,insFeeOrders, insOrders);
 
         insFeeOrdersService.save(insFeeOrders);
         return insFeeOrders;
@@ -386,7 +386,7 @@ public class QuoteVerificationAspect {
         BigDecimal addThrowPercent = convertPercent(costType.getAddThrow());
         BigDecimal exportPercent = convertPercent(costType.getExport());
 
-        // 计算应收金额
+        // 去税保费金额
         BigDecimal taxablePremium = premium.divide(taxFactor,5,RoundingMode.HALF_EVEN);
 
         // 计算应付金额(保费 * 出口比例,保留2位小数)
@@ -395,18 +395,24 @@ public class QuoteVerificationAspect {
         // 计算各类费用并设置到订单对象
         setPayable.accept(insFeeOrders, payable);
         BigDecimal commission = taxablePremium.multiply(commissionRatio).setScale(5, RoundingMode.HALF_EVEN);
-        BigDecimal follow = taxablePremium.multiply(followRatio).setScale(5, RoundingMode.HALF_EVEN);
+
         setCommission.accept(insFeeOrders, commission);
-        setFollow.accept(insFeeOrders, follow);
+
         // modify by lipf, 2026年6月16日15:35:09  加投比例,不需要根据平台/私有进行1.06的计算
 
         BigDecimal addAmount = premium.multiply(addThrowPercent).setScale(5, RoundingMode.HALF_EVEN);
         setAdditional.accept(insFeeOrders,addAmount);
 
-        BigDecimal receivable = BigDecimalUtil.add(commission,follow);
+        //应付金额计算
+        BigDecimal receivableRadio = commissionRatio.add(followRatio);
+        BigDecimal receivable = taxablePremium.multiply(receivableRadio).setScale(5,RoundingMode.HALF_EVEN);
         receivable = receivable.setScale(5, RoundingMode.HALF_EVEN);
         setReceivable.accept(insFeeOrders, receivable);
 
+        // 修改 应收-手续费 = 跟单费
+        BigDecimal follow = receivable.subtract(commission);
+        setFollow.accept(insFeeOrders, follow);
+
         // 设置留点比例 入口比例/taxFactor+加投比例-出口比例
         BigDecimal keepPointRateCal  = BigDecimalUtil.subtract(BigDecimalUtil.add(BigDecimalUtil.divide(inletPercent,taxFactor),addThrowPercent),exportPercent)
                 .setScale(5,RoundingMode.HALF_EVEN);
@@ -506,12 +512,18 @@ public class QuoteVerificationAspect {
         insFeeOrders.setJyInletRatio(jyCostType != null
                 ? convertPercent(jyCostType.getInlet() != null ? jyCostType.getInlet() : BigDecimal.ZERO) : BigDecimal.ZERO);
         // 跟单比例
-        insFeeOrders.setJqFollowRatio(jqCostType != null ?
-                calculateFollowRatio(jqCostType, convertPercent(agreementInfoVo.getAgreement().getJqEntranceFeeRatio())) : BigDecimal.ZERO);
-        insFeeOrders.setSyFollowRatio(syCostType != null ?
-                calculateFollowRatio(syCostType, convertPercent(agreementInfoVo.getAgreement().getSyEntranceFeeRatio())) : BigDecimal.ZERO);
-        insFeeOrders.setJyFollowRatio(jyCostType != null ?
-                calculateFollowRatio(jyCostType, convertPercent(agreementInfoVo.getAgreement().getJyEntranceFeeRatio())) : BigDecimal.ZERO);
+        insFeeOrders.setJqFollowRatio(Objects.nonNull(insFeeOrders.getJqFollowRatio()) ?
+                insFeeOrders.getJqFollowRatio() : BigDecimal.ZERO);
+        insFeeOrders.setSyFollowRatio(Objects.nonNull(insFeeOrders.getSyFollowRatio()) ?
+                insFeeOrders.getSyFollowRatio() : BigDecimal.ZERO);
+        insFeeOrders.setJyFollowRatio(Objects.nonNull(insFeeOrders.getJyFollowRatio()) ?
+                insFeeOrders.getJyFollowRatio() : BigDecimal.ZERO);
+//        insFeeOrders.setJqFollowRatio(jqCostType != null ?
+//                calculateFollowRatio(jqCostType, convertPercent(agreementInfoVo.getAgreement().getJqEntranceFeeRatio())) : BigDecimal.ZERO);
+//        insFeeOrders.setSyFollowRatio(syCostType != null ?
+//                calculateFollowRatio(syCostType, convertPercent(agreementInfoVo.getAgreement().getSyEntranceFeeRatio())) : BigDecimal.ZERO);
+//        insFeeOrders.setJyFollowRatio(jyCostType != null ?
+//                calculateFollowRatio(jyCostType, convertPercent(agreementInfoVo.getAgreement().getJyEntranceFeeRatio())) : BigDecimal.ZERO);
         // 加投比例
         insFeeOrders.setJqAdditionalRatio(jqCostType != null
                 ? convertPercent(jqCostType.getAddThrow() != null ? jqCostType.getAddThrow() : BigDecimal.ZERO)
@@ -523,15 +535,14 @@ public class QuoteVerificationAspect {
                 ? convertPercent(jyCostType.getAddThrow() != null ? jyCostType.getAddThrow() : BigDecimal.ZERO)
                 : BigDecimal.ZERO);
         // 留点比例
-        insFeeOrders.setJqKeepPointRatio(jqCostType != null
-                ? convertPercent(jqCostType.getKeepPointRatio() != null ? jqCostType.getKeepPointRatio() : BigDecimal.ZERO)
-                : BigDecimal.ZERO);
-        insFeeOrders.setSyKeepPointRatio(syCostType != null
-                ? convertPercent(syCostType.getKeepPointRatio() != null ? syCostType.getKeepPointRatio() : BigDecimal.ZERO)
-                : BigDecimal.ZERO);
-        insFeeOrders.setJyKeepPointRatio(jyCostType != null
-                ? convertPercent(jyCostType.getKeepPointRatio() != null ? jyCostType.getKeepPointRatio() : BigDecimal.ZERO)
-                : BigDecimal.ZERO);
+        insFeeOrders.setJqKeepPointRatio(Objects.nonNull(insFeeOrders.getJqKeepPointRatio())
+                ? insFeeOrders.getJqKeepPointRatio() : BigDecimal.ZERO);
+
+        insFeeOrders.setSyKeepPointRatio(Objects.nonNull(insFeeOrders.getSyKeepPointRatio())
+                ? insFeeOrders.getSyKeepPointRatio() : BigDecimal.ZERO);
+
+        insFeeOrders.setJyKeepPointRatio(Objects.nonNull(insFeeOrders.getJyKeepPointRatio())
+                ? insFeeOrders.getJyKeepPointRatio() : BigDecimal.ZERO);
 
         // 出口比例
         insFeeOrders.setJqExportRatio(jqCostType != null

+ 25 - 4
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java

@@ -92,6 +92,18 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         return insFeeOrders;
     }
 
+    /**
+     * 获取并计算保险费用订单的完整信息
+     * 主要流程:
+     * 1. 查询订单、费用、协议等基础数据
+     * 2. 校验并调整手续费比例(手续费比例不能大于入口比例,超出时强制调整为入口比例)
+     * 3. 保存各项比例信息(手续费、入口、跟单、加投、出口、留点)
+     * 4. 按险种(交强险、商业险、驾乘险)重新计算所有费用
+     * 5. 汇总总应收和总应付金额
+     *
+     * @param ptlAgreementCostRatioVo 协议成本比例VO对象,包含订单号和各险种的比例配置
+     * @return 计算后的保险费用订单对象
+     */
     private InsFeeOrders getInsFeeOrders(PtlAgreementCostRatioVo ptlAgreementCostRatioVo) {
         // 常量定义 保留小数5位
         final int SCALE = 5;
@@ -440,6 +452,15 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         return insFeeOrdersMapper.getInsFeeOrderByOrderNo(orderNo);
     }
 
+    /**
+     * 更新订单的可用金额,同时调整剩余金额
+     * 更新前会校验:订单存在性、出口留点比例必须为0、新可用金额不能大于当前金额
+     * 剩余金额调整规则:剩余金额 = 原剩余金额 + (原可用金额 - 新可用金额)
+     *
+     * @param orderNo 订单号
+     * @param availableAmount 新的可用金额,必须大于等于0且小于等于当前可用金额
+     * @return 更新结果,成功返回"更新成功"
+     */
     @Override
     public HttpResult updateAvailableAmount(String orderNo, BigDecimal availableAmount) {
         // 1. 参数校验
@@ -479,11 +500,11 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
     }
 
     /**
-     * 查询指定订单的应收总额
+     * 查询指定订单列表的应收保费总额
+     * 支持批量查询,内部按3000个订单分批处理以避免SQL参数过多
      *
-     * @param orderNos 订单编号
-     * @author lipf
-     * @date 2026/6/4 10:17
+     * @param orderNos 订单号列表
+     * @return 所有订单的应收保费总和,无数据时返回0
      */
     @Override
     public BigDecimal queryAllTotalReceivablePremiumByOrderNo(List<String> orderNos) {

+ 16 - 32
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -2900,12 +2900,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Integer endYear = Integer.parseInt(searchYear.getSearch().split(",")[1]);
 
         // 获取所有年份
-        List<Integer> yearList = new ArrayList<>();
-        if (startYear <= endYear) {
-            for (int year = startYear; year <= endYear; year++) {
-                yearList.add(year);
-            }
-        }
+        Map<String, List<Integer>> companyYearMap = new HashMap<>();
 
         // 获取当前用户的系统编码
         String systemCode = baseController.getUserSystemCode();
@@ -2949,42 +2944,30 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     }
                     return true;
                 };
-                // 签单年份
-                Predicate<InsPlyIncomeDto> signYearPredicate = insPlyIncome -> {
-                    if (!names.contains(FollowInvoicePageListVo.SearchVO.signYear)) {
-                        return true;
-                    }
-                    FollowInvoicePageListVo.SearchVO searchVO = searchVOMap.get(FollowInvoicePageListVo.SearchVO.signYear);
-                    String type = searchVO.getType();
-                    String search = searchVO.getSearch();
-                    if ("为空".equals(type) || "不为空".equals(type)) {
-                        return true;
-                    }
-                    if (StrUtil.isEmpty(search)) {
-                        return true;
-                    }
-                    if ("等于".equalsIgnoreCase(type) || "包含".equalsIgnoreCase(type)) {
-                        List<String> signYears = Arrays.asList(search.split(","));
-                        return signYears.contains(insPlyIncome.getSignYear());
-                    }
-                    if ("不等于".equalsIgnoreCase(type) || "不包含".equalsIgnoreCase(type)) {
-                        List<String> signYears = Arrays.asList(search.split(","));
-                        return !signYears.contains(insPlyIncome.getSignYear());
-                    }
-                    return true;
-                };
 
                 // AND / OR 组合逻辑(和代码A完全一致)
                 if ("and".equalsIgnoreCase(followInvoicePageListVo.getLogicJudge())) {
-                    Predicate<InsPlyIncomeDto> and = companyIdPredicate.and(signYearPredicate);
+                    Predicate<InsPlyIncomeDto> and = companyIdPredicate;
                     filterIncomes = incomes.stream().filter(and).toList();
                 } else if ("or".equalsIgnoreCase(followInvoicePageListVo.getLogicJudge())) {
-                    Predicate<InsPlyIncomeDto> or = companyIdPredicate.or(signYearPredicate);
+                    Predicate<InsPlyIncomeDto> or = companyIdPredicate;
                     filterIncomes = incomes.stream().filter(or).toList();
                 }
             }
         }
         // ======================条件过滤结束======================
+        for (InsPlyIncomeDto filterIncome : filterIncomes) {
+            List<Integer> years = companyYearMap.get(filterIncome.getPartnerCompanyId());
+            // 否则新建
+            if (CollUtil.isEmpty(years)) {
+                years = new ArrayList<>();
+            }
+            // 如果不包含当前公司id的年份,则添加
+            if (!years.contains(filterIncome.getSigningTime().getYear())) {
+                years.add(filterIncome.getSigningTime().getYear());
+            }
+            companyYearMap.put(filterIncome.getPartnerCompanyId(), years);
+        }
 
         // 按合作方分组(使用过滤后的数据)
         Map<String, List<InsPlyIncomeDto>> groupMap = filterIncomes.stream()
@@ -3009,6 +2992,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
 
             // 遍历12个月份,组装VO对象
             InsPlyIncomeDto firstItem = list.get(0);
+            List<Integer> yearList = companyYearMap.get(partnerCompanyId);
             for (Integer year : yearList) {
                 for (int month = 1; month <= 12; month++) {
                     InsFeeFollowOrderVo vo = buildFollowOrderVo(

+ 2 - 2
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -1780,14 +1780,14 @@
         ) a
         group by  a.company_id
     </select>
-    <!-- 查询已结算金额 lipf 2026年6月1日18:12:08  -->
+    <!-- 查询已结算金额 lipf 2026年6月1日18:12:08 modify by lipf 2026年6月24日19:10:53 添加distinct ins.id 按照结算记录的值进行去重。 因为私有开票是按照公司维度开票,的所以 同一个 ins.id 关联的 ipi.icompany_id 肯定是一样的 -->
     <select id="querySettledAmount" resultType="com.jzg.organization.entity.dto.CalRes">
         select
         a.company_id ,
         sum(COALESCE(a.actual_received_amount, 0)) as settlement
         from
         (
-        select
+        select distinct ins.id,
         ipi.company_id ,
         COALESCE(ins.actual_received_amount, 0) as actual_received_amount
         from ins_ply_income_invoice_settlement ins