Qchen 1 год назад
Родитель
Сommit
5f22978a3f

+ 9 - 0
commons/src/main/java/com/jzg/commons/entity/po/InsFeeOrders.java

@@ -91,4 +91,13 @@ public class InsFeeOrders {
 
     @Schema(description = "驾意险加投费费费用")
     private BigDecimal jyAdditionalPremium;
+
+    @Schema(description = "交强险留点费用")
+    private BigDecimal jqKeepPointPremium;
+
+    @Schema(description = "商业险留点费用")
+    private BigDecimal syKeepPointPremium;
+
+    @Schema(description = "驾意险留点费用")
+    private BigDecimal jyKeepPointPremium;
 }

+ 12 - 0
commons/src/main/java/com/jzg/commons/entity/vo/PtlAgreementCostRatioVo.java

@@ -15,6 +15,9 @@ import java.util.List;
 
 @Data
 public class PtlAgreementCostRatioVo {
+    @Schema(description = "订单号")
+    private String orderNo;
+
     @Schema(description = "交强险手续费比例")
     private BigDecimal jqCommissionRatio;
 
@@ -60,6 +63,15 @@ public class PtlAgreementCostRatioVo {
     @Schema(description = "驾意险入口比例")
     private BigDecimal jyInletRatio;
 
+    @Schema(description = "交强险留点比例")
+    private BigDecimal jqKeepPointRatio;
+
+    @Schema(description = "商业险留点比例")
+    private BigDecimal syKeepPointRatio;
+
+    @Schema(description = "非车险留点比例")
+    private BigDecimal jyKeepPointRatio;
+
     public PtlAgreementCostRatioVo(List<PtlAgreementCostTypeVo> ptlAgreementCostTypeList, PtlAgreement ptlAgreement) {
         ptlAgreementCostTypeList.forEach(ptlAgreementCostType -> {
             switch (ptlAgreementCostType.getCostType()) {

+ 12 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsOrdersController.java

@@ -4,10 +4,13 @@ package com.jzg.quotation.summary.controller;
 import com.jzg.commons.aop.OperatorTrajectory;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.dto.InsOrdersParam;
+import com.jzg.commons.entity.po.InsFeeOrders;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.orders.InsOrdersAdd;
 import com.jzg.commons.entity.quote.vo.orders.InsOrdersEnd;
+import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
 import com.jzg.quotation.summary.mapper.InsOrdersMapper;
+import com.jzg.quotation.summary.service.InsFeeOrdersService;
 import com.jzg.quotation.summary.service.InsOrdersCarInfoService;
 import com.jzg.quotation.summary.service.InsOrdersService;
 import com.jzg.quotation.summary.service.InsTaskImagesService;
@@ -37,6 +40,9 @@ public class InsOrdersController {
     @Autowired
     private InsOrdersCarInfoService insOrdersCarInfoService;
 
+    @Resource
+    private InsFeeOrdersService insFeeOrdersService;
+
 
     @OperatorTrajectory(moduleName = "车险订单/补录订单)",mapperClass = InsOrdersMapper.class,entityClass = InsOrdersAdd.class,isRecorded = "insOrders.isTemporarily")
     @Operation(summary = "录入订单新增")
@@ -109,4 +115,10 @@ public class InsOrdersController {
         return HttpResult.ok(insOrdersService.getExistCompany());
     }
 
+    @Operation(summary = "费用调整并计算保存")
+    @PostMapping("/adjustmentCostAndSave")
+    public HttpResult<InsFeeOrders> adjustmentCostAndSave(@RequestBody PtlAgreementCostRatioVo ptlAgreementCostRatioVo) throws ReflectiveOperationException {
+        return HttpResult.ok(insFeeOrdersService.calcCosts(ptlAgreementCostRatioVo));
+    }
+
 }

+ 4 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsFeeOrdersService.java

@@ -2,6 +2,10 @@ package com.jzg.quotation.summary.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jzg.commons.entity.po.InsFeeOrders;
+import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
 
 public interface InsFeeOrdersService extends IService<InsFeeOrders> {
+    InsFeeOrders calcCosts(PtlAgreementCostRatioVo ptlAgreementCostRatioVo) throws ReflectiveOperationException;
+
+
 }

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

@@ -1,11 +1,26 @@
 package com.jzg.quotation.summary.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.core.base.BaseController;
+import com.jzg.commons.entity.orders.po.InsOrders;
+import com.jzg.commons.entity.orders.po.InsOrdersCosts;
 import com.jzg.commons.entity.po.InsFeeOrders;
+import com.jzg.commons.entity.po.PtlAgreement;
+import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
+import com.jzg.quotation.commons.client.OrgClient;
 import com.jzg.quotation.summary.mapper.InsFeeOrdersMapper;
 import com.jzg.quotation.summary.service.InsFeeOrdersService;
+import com.jzg.quotation.summary.service.InsOrdersCostsService;
+import com.jzg.quotation.summary.service.InsOrdersService;
+import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * @author quchen
  * @date 2025/7/3 8:48
@@ -13,4 +28,176 @@ import org.springframework.stereotype.Service;
 
 @Service
 public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, InsFeeOrders> implements InsFeeOrdersService {
+    @Resource
+    private InsOrdersService insOrdersService;
+
+    @Resource
+    private InsOrdersCostsService insOrdersCostsService;
+
+    @Resource
+    private OrgClient orgClient;
+
+    @Resource
+    private BaseController baseController;
+
+    @Resource
+    private InsFeeOrdersService insFeeOrdersService;
+
+    @Override
+    public InsFeeOrders calcCosts(PtlAgreementCostRatioVo ptlAgreementCostRatioVo) throws ReflectiveOperationException {
+        // 常量定义 保留小数5位
+        final int SCALE = 5;
+        final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
+        final BigDecimal TAX_FACTOR = new BigDecimal("1").divide(new BigDecimal("1.06"), 10, ROUNDING_MODE);
+
+        // 获取订单信息
+        InsOrders insOrders = insOrdersService.getById(ptlAgreementCostRatioVo.getOrderNo());
+        // 获取订单费用信息
+        InsOrdersCosts insOrdersCosts = insOrdersCostsService.getById(insOrders.getId());
+        // 获取协议信息
+        PtlAgreement ptlAgreement = orgClient.getByAgreementId(insOrders.getAgreementId(), baseController.getToken());
+        // 获取费用信息
+        InsFeeOrders insFeeOrders = insFeeOrdersService.getById(insOrders.getId());
+        // 保费
+        BigDecimal jqPremium = insOrdersCosts.getJqPremium();
+        BigDecimal syPremium = insOrdersCosts.getSyPremium();
+        BigDecimal jyPremium = insOrdersCosts.getJyPremium();
+        // 手续费比例
+        BigDecimal jqCommissionRatio = covertPercent(ptlAgreementCostRatioVo.getJqCommissionRatio());
+        BigDecimal syCommissionRatio = covertPercent(ptlAgreementCostRatioVo.getSyCommissionRatio());
+        BigDecimal jyCommissionRatio = covertPercent(ptlAgreementCostRatioVo.getJyCommissionRatio());
+        // 跟单费比例
+        BigDecimal jqFollowRatio = covertPercent(ptlAgreementCostRatioVo.getJqFollowRatio());
+        BigDecimal syFollowRatio = covertPercent(ptlAgreementCostRatioVo.getSyFollowRatio());
+        BigDecimal jyFollowRatio = covertPercent(ptlAgreementCostRatioVo.getJyFollowRatio());
+        // 加投费比例
+        BigDecimal jqAddThrowRatio = covertPercent(ptlAgreementCostRatioVo.getJqAdditionalRatio());
+        BigDecimal syAddThrowRatio = covertPercent(ptlAgreementCostRatioVo.getSyAdditionalRatio());
+        BigDecimal jyAddThrowRatio = covertPercent(ptlAgreementCostRatioVo.getJyAdditionalRatio());
+        // 留点比例
+        BigDecimal jqKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getJqKeepPointRatio());
+        BigDecimal syKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getSyKeepPointRatio());
+        BigDecimal jyKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getJyKeepPointRatio());
+        // 入口比例
+        BigDecimal jqInletRatio = covertPercent(ptlAgreementCostRatioVo.getJqInletRatio());
+        BigDecimal syInletRatio = covertPercent(ptlAgreementCostRatioVo.getSyInletRatio());
+        BigDecimal jyInletRatio = covertPercent(ptlAgreementCostRatioVo.getJyInletRatio());
+        // 出口比例
+        BigDecimal jqExportRatio = covertPercent(ptlAgreementCostRatioVo.getJqExportRatio());
+        BigDecimal syExportRatio = covertPercent(ptlAgreementCostRatioVo.getSyExportRatio());
+        BigDecimal jyExportRatio = covertPercent(ptlAgreementCostRatioVo.getJyExportRatio());
+
+        List<CostTypeParam> typeParams = Arrays.asList(
+                new CostTypeParam("jq", jqPremium, jqCommissionRatio, jqFollowRatio, jqAddThrowRatio,
+                        jqKeepPointRatio, jqInletRatio, jqExportRatio),
+                new CostTypeParam("sy", syPremium, syCommissionRatio, syFollowRatio, syAddThrowRatio,
+                        syKeepPointRatio, syInletRatio, syExportRatio),
+                new CostTypeParam("jy", jyPremium, jyCommissionRatio, jyFollowRatio, jyAddThrowRatio,
+                        jyKeepPointRatio, jyInletRatio, jyExportRatio)
+        );
+        // 5. 根据协议类型计算费用
+        boolean isPlatformAgreement = ptlAgreement.getAgreementType() == 1;
+        BigDecimal totalReceivable = BigDecimal.ZERO;
+        BigDecimal totalPayable = BigDecimal.ZERO;
+
+        for (CostTypeParam param : typeParams) {
+            // 5.1 计算基础保费(平台协议直接用原始保费,私有协议扣税)
+            BigDecimal basePremium = isPlatformAgreement ?
+                    param.premium : divideTaxFactor(param.premium, TAX_FACTOR, SCALE);
+
+            // 5.2 计算各类费用
+            BigDecimal commission = calculateFee(basePremium, param.commissionRatio, SCALE);
+            BigDecimal follow = calculateFee(basePremium, param.followRatio, SCALE);
+            BigDecimal addThrow = calculateFee(basePremium, param.addThrowRatio, SCALE);
+            BigDecimal keepPoint = calculateFee(basePremium, param.keepPointRatio, SCALE);
+            BigDecimal inlet = calculateFee(basePremium, param.inletRatio, SCALE);
+            BigDecimal export = calculateFee(basePremium, param.exportRatio, SCALE);
+
+            // 5.3 设置费用到对象(通过反射或方法引用简化setter调用)
+            setFeeToOrder(insFeeOrders, param.typePrefix, commission, follow, addThrow, keepPoint, inlet, export);
+
+            // 5.4 累加总应收/应付款
+            totalReceivable = totalReceivable.add(inlet);
+            totalPayable = totalPayable.add(export);
+        }
+
+        // 6. 设置总费用并更新
+        insFeeOrders.setTotalReceivablePremium(scale(totalReceivable, SCALE));
+        insFeeOrders.setTotalPayablePremium(scale(totalPayable, SCALE));
+        insFeeOrdersService.updateById(insFeeOrders);
+        return insFeeOrders;
+    }
+
+    // 转换百分比
+    public BigDecimal covertPercent(BigDecimal ratio) {
+        if (ratio == null) {
+            return BigDecimal.ZERO;
+        }
+       return ratio.divide(BigDecimal.valueOf(100), 10, RoundingMode.HALF_EVEN);
+    }
+
+    // 计算单种费用(保费 * 比例)
+    private BigDecimal calculateFee(BigDecimal basePremium, BigDecimal ratio, int scale) {
+        if (basePremium == null || ratio == null) {
+            return BigDecimal.ZERO;
+        }
+        return scale(basePremium.multiply(ratio), scale);
+    }
+
+    // 统一保留小数
+    private BigDecimal scale(BigDecimal value, int scale) {
+        return value.setScale(scale, RoundingMode.HALF_EVEN);
+    }
+
+    // 扣税计算(抽取为方法)
+    private BigDecimal divideTaxFactor(BigDecimal premium, BigDecimal taxFactor, int scale) {
+        if (premium == null) {
+            return BigDecimal.ZERO;
+        }
+        return scale(premium.multiply(taxFactor), scale);
+    }
+
+    private static class CostTypeParam {
+        String typePrefix; // 类型前缀(jq/sy/jy)
+        BigDecimal premium; // 保费
+        BigDecimal commissionRatio; // 手续费比例
+        BigDecimal followRatio; // 跟单费比例
+        BigDecimal addThrowRatio; // 加投费比例
+        BigDecimal keepPointRatio; // 留点比例
+        BigDecimal inletRatio; // 入口比例
+        BigDecimal exportRatio; // 出口比例
+
+        public CostTypeParam(String typePrefix, BigDecimal premium, BigDecimal commissionRatio,
+                             BigDecimal followRatio, BigDecimal addThrowRatio, BigDecimal keepPointRatio,
+                             BigDecimal inletRatio, BigDecimal exportRatio) {
+            this.typePrefix = typePrefix;
+            this.premium = premium;
+            this.commissionRatio = commissionRatio;
+            this.followRatio = followRatio;
+            this.addThrowRatio = addThrowRatio;
+            this.keepPointRatio = keepPointRatio;
+            this.inletRatio = inletRatio;
+            this.exportRatio = exportRatio;
+        }
+    }
+    // 设置费用到订单对象(通过反射简化重复setter)
+    private void setFeeToOrder(InsFeeOrders feeOrders, String prefix,
+                               BigDecimal commission, BigDecimal follow, BigDecimal addThrow,
+                               BigDecimal keepPoint, BigDecimal inlet, BigDecimal export) throws ReflectiveOperationException {
+        Class<?> clazz = InsFeeOrders.class;
+        // 利用反射调用setter方法(如setJqCommissionPremium)
+        setField(feeOrders, clazz, prefix + "CommissionPremium", commission);
+        setField(feeOrders, clazz, prefix + "FollowPremium", follow);
+        setField(feeOrders, clazz, prefix + "AdditionalPremium", addThrow);
+        setField(feeOrders, clazz, prefix + "KeepPointPremium", keepPoint);
+        setField(feeOrders, clazz, prefix + "ReceivablePremium", inlet);
+        setField(feeOrders, clazz, prefix + "PayablePremium", export);
+    }
+
+    // 反射设置字段值
+    private void setField(InsFeeOrders obj, Class<?> clazz, String fieldName, BigDecimal value) throws ReflectiveOperationException {
+        String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+        Method setter = clazz.getMethod(setterName, BigDecimal.class);
+        setter.invoke(obj, value);
+    }
 }