ソースを参照

优惠政策改为下单时直接扣库存

ZHOUTD 1 週間 前
コミット
7021b3fa47

+ 75 - 50
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/otc/impl/OtcTradeOrderServiceImpl.java

@@ -525,32 +525,17 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                 } catch (Exception e) {
                     log.error("发送短信异常", e);
                 }
-                TradeOrderTotalDO tradeOrderTotal = tradeOrderTotalMapper.selectByOrderId(tradeOrderDO.getId());
-                List<BigDecimal> amountList = new ArrayList<>();
-                List<OrderPolicyDO> orderPolicyList = orderPolicyMapper.selectList(OrderPolicyDO::getOrderId, orderId);
-                if (!orderPolicyList.isEmpty()) {
-                    orderPolicyList.forEach(item -> {
-                        amountList.add(item.getAmount());
-                        policyApi.updatePolicySurplusNum(item.getPolicyId(), tradeOrderDO.getVoyageId(), item.getPreUseNum());
-                    });
-                }
-                BigDecimal amount = amountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
                 int orderStatus = TradeOrderStatusEnum.UNPAID.getStatus();
                 if(tradeOrderDO.getPayStatus()==1){
                     orderStatus = 6;
                 }
                 LocalDateTime confireDate = tradeOrderDO.getConfirmDate();
-                BigDecimal newPayAmount = tradeOrderTotal.getRealMoney().subtract(amount);
                 LambdaUpdateWrapper<TradeOrderDO> updateWrapper = Wrappers.<TradeOrderDO>lambdaUpdate()
                         .set(TradeOrderDO::getOrderStatus, orderStatus)
                         .set(TradeOrderDO::getConfirmDate, confireDate)
                         .set(TradeOrderDO::getAuditStatus, tradeOrderDO.getAuditStatus() + 1)
                         .set(TradeOrderDO::getUpdateTime, LocalDateTime.now())
                         .eq(TradeOrderDO::getId, orderId);
-                if(amount.compareTo(BigDecimal.ZERO) != 0){
-                    updateWrapper.set(TradeOrderDO::getPayAmount, newPayAmount);
-                    updateWrapper.set(TradeOrderDO::getFreeAmount, amount);
-                }
                 if(confireDate == null){
                     updateWrapper.set(TradeOrderDO::getConfirmDate, LocalDateTime.now());
                 }
@@ -565,17 +550,8 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                 }
 
                 tradeOrderMapper.update(updateWrapper);
-                String str ="";
-                if(tradeOrderDO.getPayAmount().compareTo(newPayAmount)!=0){
-                    str+=",支付金额发送变化,从"+tradeOrderDO.getPayAmount()+"到"+newPayAmount;
-                }
-                BigDecimal oldFreeAmount = tradeOrderDO.getFreeAmount()==null?BigDecimal.ZERO:tradeOrderDO.getFreeAmount();
-                if(oldFreeAmount.compareTo(amount)!=0){
-                    str+=",优惠金额发送变化,从"+tradeOrderDO.getFreeAmount()+"到"+amount;
-                }
-
                 Map<String, Object> extMap = new HashMap<>();
-                extMap.put("result", "审核通过,审核意见:"+auditAdvice+" "+str);
+                extMap.put("result", "审核通过,审核意见:"+auditAdvice);
                 TradeOrderLogUtils.setOrderInfo(orderId, tradeOrderDO.getOrderStatus(), TradeOrderStatusEnum.UNPAID.getStatus(), extMap);
             } else {
                 AuditUserDO auditUserDO = auditUserMapper.selectOne(new QueryWrapper<AuditUserDO>().eq("type", tradeOrderDO.getAuditType()).eq("audit_status", tradeOrderDO.getAuditStatus() + 1).last("limit 1"));
@@ -2624,6 +2600,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
             List<OrderPolicyDO> orderPolicyDOList = new ArrayList<>();
             List<TradeOrderPolicyReqVO> policyList = createVO.getPolicyList();
             if (policyList != null) {
+                adjustPolicySurplusNum(Collections.emptyList(), policyList, voyageId);
                 policyList.forEach(policy -> {
                     OrderPolicyDO orderPolicyDO = new OrderPolicyDO();
                     orderPolicyDO.setOrderId(orderId);
@@ -2635,24 +2612,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                     orderPolicyDO.setUseNum(policy.getUseNum());
                     orderPolicyDO.setPreUseNum(policy.getUseNum());
                     // 只要不是审核,都是预占,实占和预占一样,不用区分了,其实实占没有意义了
-                    orderPolicyDO.setRealUseNum(BigDecimal.ZERO);
-                    //判断当前库存够不够
-                    if(!policyApi.checkPolicySurplusNum(policy.getPolicyId(),voyageId,policy.getUseNum())){
-                        BigDecimal policySurplusNum = policyApi.getPolicySurplusNum(policy.getPolicyId(), voyageId);
-                        throw exception(new ErrorCode(POLICY_OVER_NUM.getCode(),
-                                "营销政策-"+policy.getPolicyName()+
-                                        "剩余房间不足,当前剩余房间数量:"+policySurplusNum+",本次使用房间数:"+policy.getUseNum()));
-                    }
-//                    if (createVO.getIsYd() != null && createVO.getIsYd() == 1) {
-//                        orderPolicyDO.setPreUseNum(policy.getUseNum());
-//                        orderPolicyDO.setRealUseNum(BigDecimal.ZERO);
-//                    } else {
-//                        //TODO: 需要修改订单金额,参考文档
-//                        orderPolicyDO.setPreUseNum(BigDecimal.ZERO);
-//                        orderPolicyDO.setRealUseNum(policy.getUseNum());
-//                        // 这个地方不去扣库存,要审核通过了才扣
-////                        policyApi.updatePolicySurplusNum(policy.getPolicyId(), createVO.getVoyageId(), policy.getUseNum());
-//                    }
+                    orderPolicyDO.setRealUseNum(policy.getUseNum());
                     orderPolicyDO.setAmount(policy.getAmount());
                     orderPolicyDO.setRooms(policy.getRooms());
                     orderPolicyDOList.add(orderPolicyDO);
@@ -2661,6 +2621,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                     //TODO: 判断优惠政策是否需要审核
                     orderPolicyMapper.insertBatch(orderPolicyDOList);
                 }
+                updateOrderPolicyAmount(orderId, tradeOrderTotalDO.getRealMoney(), sumPolicyAmount(policyList));
             }
 
             int auditType = 0;
@@ -3079,6 +3040,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
             List<OrderPolicyDO> insetOrderPolicyDOList = new ArrayList<>();
             List<OrderPolicyDO> updateOrderPolicyDOList = new ArrayList<>();
             if (policyList != null) {
+                adjustPolicySurplusNum(orderPolicyList, policyList, voyageId);
                 // 传入的优惠政策id
                 List<Long> newIds = CollUtil.emptyIfNull(policyList).stream()
                         .map(TradeOrderPolicyReqVO::getId)
@@ -3101,13 +3063,6 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                     orderPolicyDO.setPreUseNum(policy.getUseNum());
                     // 只要不是审核,都是预占,实占和预占一样,不用区分了,其实实占没有意义了
                     orderPolicyDO.setRealUseNum(policy.getUseNum());
-                    //判断当前库存够不够
-                    if(!policyApi.checkPolicySurplusNum(policy.getPolicyId(),voyageId,policy.getUseNum())){
-                        BigDecimal policySurplusNum = policyApi.getPolicySurplusNum(policy.getPolicyId(), voyageId);
-                        throw exception(new ErrorCode(POLICY_OVER_NUM.getCode(),
-                                "营销政策-"+policy.getPolicyName()+
-                                        "剩余房间不足,当前剩余房间数量:"+policySurplusNum+",本次使用房间数:"+policy.getUseNum()));
-                    }
                     orderPolicyDO.setAmount(policy.getAmount());
                     orderPolicyDO.setRooms(policy.getRooms());
                     if(policy.getId()!=null){
@@ -3141,6 +3096,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                         }
                     }
                 }
+                updateOrderPolicyAmount(orderId, tradeOrderTotalDO.getRealMoney(), sumPolicyAmount(policyList));
             }
             int oldSize = orderPolicyList==null?0:orderPolicyList.size();
             int newSize = orderPolicyDOList.size();
@@ -3256,6 +3212,75 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
         }
     }
 
+    /**
+     * 按营销政策新增使用数量扣减库存,避免订单反复修改时按完整使用量重复扣减。
+     * 政策数量减少、删除或订单回滚时不退回库存。
+     */
+    private void adjustPolicySurplusNum(List<OrderPolicyDO> oldPolicyList,
+                                        List<TradeOrderPolicyReqVO> newPolicyList,
+                                        Long voyageId) {
+        Map<Long, BigDecimal> oldUseNumMap = CollUtil.emptyIfNull(oldPolicyList).stream()
+                .filter(item -> item.getPolicyId() != null)
+                .collect(Collectors.toMap(OrderPolicyDO::getPolicyId,
+                        item -> ObjectUtil.defaultIfNull(item.getPreUseNum(), BigDecimal.ZERO),
+                        BigDecimal::add));
+        Map<Long, BigDecimal> newUseNumMap = CollUtil.emptyIfNull(newPolicyList).stream()
+                .filter(item -> item.getPolicyId() != null)
+                .collect(Collectors.toMap(TradeOrderPolicyReqVO::getPolicyId,
+                        item -> ObjectUtil.defaultIfNull(item.getUseNum(), BigDecimal.ZERO),
+                        BigDecimal::add));
+        Map<Long, String> policyNameMap = CollUtil.emptyIfNull(newPolicyList).stream()
+                .filter(item -> item.getPolicyId() != null)
+                .collect(Collectors.toMap(TradeOrderPolicyReqVO::getPolicyId,
+                        item -> ObjectUtil.defaultIfNull(item.getPolicyName(), String.valueOf(item.getPolicyId())),
+                        (first, second) -> first));
+
+        Set<Long> policyIds = new TreeSet<>();
+        policyIds.addAll(oldUseNumMap.keySet());
+        policyIds.addAll(newUseNumMap.keySet());
+
+        // 先完成所有增量库存校验,再统一调整,避免后一个政策校验失败时产生部分扣减。
+        for (Long policyId : policyIds) {
+            BigDecimal oldUseNum = oldUseNumMap.getOrDefault(policyId, BigDecimal.ZERO);
+            BigDecimal newUseNum = newUseNumMap.getOrDefault(policyId, BigDecimal.ZERO);
+            BigDecimal changeUseNum = newUseNum.subtract(oldUseNum);
+            if (changeUseNum.compareTo(BigDecimal.ZERO) > 0
+                    && !policyApi.checkPolicySurplusNum(policyId, voyageId, changeUseNum)) {
+                BigDecimal policySurplusNum = policyApi.getPolicySurplusNum(policyId, voyageId);
+                String policyName = policyNameMap.getOrDefault(policyId, String.valueOf(policyId));
+                throw exception(new ErrorCode(POLICY_OVER_NUM.getCode(),
+                        "营销政策-" + policyName
+                                + "剩余房间不足,当前剩余房间数量:" + policySurplusNum
+                                + ",本次新增使用房间数:" + changeUseNum));
+            }
+        }
+        for (Long policyId : policyIds) {
+            BigDecimal oldUseNum = oldUseNumMap.getOrDefault(policyId, BigDecimal.ZERO);
+            BigDecimal newUseNum = newUseNumMap.getOrDefault(policyId, BigDecimal.ZERO);
+            BigDecimal changeUseNum = newUseNum.subtract(oldUseNum);
+            if (changeUseNum.compareTo(BigDecimal.ZERO) > 0) {
+                policyApi.updatePolicySurplusNum(policyId, voyageId, changeUseNum);
+            }
+        }
+    }
+
+    private BigDecimal sumPolicyAmount(List<TradeOrderPolicyReqVO> policyList) {
+        return CollUtil.emptyIfNull(policyList).stream()
+                .map(TradeOrderPolicyReqVO::getAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
+
+    private void updateOrderPolicyAmount(Long orderId, BigDecimal realMoney, BigDecimal policyAmount) {
+        BigDecimal actualRealMoney = ObjectUtil.defaultIfNull(realMoney, BigDecimal.ZERO);
+        BigDecimal actualPolicyAmount = ObjectUtil.defaultIfNull(policyAmount, BigDecimal.ZERO);
+        tradeOrderMapper.update(Wrappers.<TradeOrderDO>lambdaUpdate()
+                .set(TradeOrderDO::getPayAmount, actualRealMoney.subtract(actualPolicyAmount))
+                .set(TradeOrderDO::getFreeAmount, actualPolicyAmount)
+                .set(TradeOrderDO::getUpdateTime, LocalDateTime.now())
+                .eq(TradeOrderDO::getId, orderId));
+    }
+
     /**
      * 保存历史优惠政策
      * @param policyList