package com.bonus.core.order.common.business.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.constant.LeConstants;
import com.bonus.constant.RetCodeEnum;
import com.bonus.core.allocation.canteen.dto.AllocCanteenDeliveryDTO;
import com.bonus.core.allocation.canteen.dto.AllocCanteenDeliveryModel;
import com.bonus.core.common.enums.DeliveryTypeEnum;
import com.bonus.core.common.enums.MetadataModelTypeEnum;
import com.bonus.core.common.redis.RedisUtil;
import com.bonus.core.common.utils.LogUtil;
import com.bonus.core.drp.api.DrpServiceApi;
import com.bonus.core.drp.constant.DrpOutInventoryTypeEnum;
import com.bonus.core.drp.dto.AndroidSupermarketOutDTO;
import com.bonus.core.drp.dto.AndroidSupermarketOutDetailDTO;
import com.bonus.core.drp.dto.SupermarketInventoryRepairDTO;
import com.bonus.core.marketing.coupon.api.MktCouponApi;
import com.bonus.core.marketing.coupon.constants.MktCouponTypeEnum;
import com.bonus.core.marketing.coupon.model.MktCouponMacPayModel;
import com.bonus.core.marketing.coupon.model.MktCouponPayModel;
import com.bonus.core.marketing.v2.api.MarketApi;
import com.bonus.core.marketing.v2.rule.price.dto.*;
import com.bonus.core.menu.api.MenuDishesApi;
import com.bonus.core.menu.api.MenuRecipeApi;
import com.bonus.core.menu.dto.MenuRecipeChangeSurplusNum;
import com.bonus.core.menu.dto.OrderRecipeDishesDto;
import com.bonus.core.menu.model.AllocMealtimeModel;
import com.bonus.core.order.client.OrderModuleClient;
import com.bonus.core.order.client.po.MealtimeCheckNowParam;
import com.bonus.core.order.client.po.MealtimeQueryParam;
import com.bonus.core.order.client.po.MetaDataValueParam;
import com.bonus.core.order.client.po.OrderConfigQueryParam;
import com.bonus.core.order.common.business.OrderPlaceBusiness;
import com.bonus.core.order.common.constants.*;
import com.bonus.core.order.common.model.OrderAmountChange;
import com.bonus.core.order.common.model.OrderDelivery;
import com.bonus.core.order.common.model.OrderDetail;
import com.bonus.core.order.common.model.OrderInfo;
import com.bonus.core.order.common.service.*;
import com.bonus.core.order.common.vo.OrderDeliveryResultVO;
import com.bonus.core.order.custom.OrderCustomBusiness;
import com.bonus.core.order.mq.po.OrderSavePO;
import com.bonus.core.order.utils.LeNumUtil;
import com.bonus.core.pay.api.PayApi;
import com.bonus.core.pay.api.dto.UnifyPayDTO;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.common.constants.PayChannelEnum;
import com.bonus.core.pay.common.constants.PayChannelSelectEnum;
import com.bonus.core.pay.common.constants.PayTypeEnum;
import com.bonus.core.pay.common.vo.PayChannelSplitVO;
import com.bonus.core.supermarket.api.SupermarketApi;
import com.bonus.core.supermarket.dto.SmtCheckProductLimitBuyDTO;
import com.bonus.core.supermarket.dto.SmtCheckProductLimitBuyDetailDTO;
import com.bonus.core.supermarket.dto.SupermarketQueryProductInfoDTO;
import com.bonus.core.supermarket.model.SupermarketInfo;
import com.bonus.core.supermarket.vo.SupermarketQueryProductInfoVO;
import com.bonus.i18n.I18n;
import com.bonus.core.order.common.vo.*;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class OrderPlaceBusinessImpl implements OrderPlaceBusiness {
   private static final Logger log = LoggerFactory.getLogger(OrderPlaceBusinessImpl.class);
   @Autowired
   @Lazy
   protected OrderCustomBusiness orderCustomBusiness;
//   @Autowired
//   @Lazy
//   protected OrderDishesAndroidBusiness orderDishesAndroidBusiness;
   @Autowired
   @Lazy
   protected OrderInfoService orderInfoService;
   @Autowired
   @Lazy
   protected OrderDetailService orderDetailService;
   @Autowired
   @Lazy
   protected OrderDeliveryService orderDeliveryService;
   @Autowired
   @Lazy
   protected OrderAmountChangeService orderAmountChangeService;
   @Autowired
   @Lazy
   protected OrderAmountDetailService orderAmountDetailService;
   @Autowired
   @Lazy
   protected OrderModuleClient orderModuleClient;
   @Autowired
   @Lazy
   protected SupermarketApi supermarketApi;
   @Autowired
   @Lazy
   protected MenuRecipeApi menuRecipeApi;
   @Autowired
   @Lazy
   protected MenuDishesApi menuDishesApi;
   @Autowired
   @Lazy
   protected DrpServiceApi drpServiceApi;
   @Autowired
   @Lazy
   protected PayApi payApi;
//   @Autowired
//   @Lazy
//   protected TradeRecordApi tradeRecordApi;
   @Autowired
   @Lazy
   protected MarketApi marketApi;
   @Autowired
   @Lazy
   protected MktCouponApi mktCouponApi;
//   @Autowired
//   @Lazy
//   protected DeviceApi deviceApi;
//   @Autowired
//   @Lazy
//   protected AllocStallApi allocStallApi;
//   @Autowired
//   @Lazy
//   protected AccTradeApi accTradeApi;

   public void checkOrderSubmitted(String repeatedId) {
      if (!CharSequenceUtil.isEmpty(repeatedId)) {
         String repeatedKey = OrderCacheConstants.orderSubmitRepeatKey(repeatedId);
         if (!RedisUtil.setNx(repeatedKey, LeConstants.COMMON_YES, 2)) {
            log.info("[下单]重复提交：{}", repeatedId);
            throw new ServiceException(I18n.getMessage("order.mac.repeated-submit", new Object[0])
                    , RetCodeEnum.SUCC_MAC_ORD.getKey());
         }
      }
   }

//   public void checkMacOrderId(String macOrderId, boolean checkTradeRecord) {
//      if (!CharSequenceUtil.isBlank(macOrderId)) {
//         log.info("[下单检查]检查设备订单号是否存在 {}", macOrderId);
//         boolean existFlag = this.orderInfoService.existMacOrderId(macOrderId, !checkTradeRecord);
//         if (!existFlag && checkTradeRecord) {
//            existFlag = this.tradeRecordApi.checkMacOrderId(macOrderId);
//         }
//
//         if (existFlag) {
//            log.info("[下单检查]设备订单号已存在 macOrdId {} ", macOrderId);
//            throw new LeException(RetCodeEnum.SUCC_MAC_ORD, I18n.getMessage("order.mac.repeated-submit", new Object[0]));
//         } else {
//            log.info("[下单检查]检查设备订单号是否存在 结束 {}", macOrderId);
//         }
//      }
//   }

   public void checkWaitPlaceOrder(List<OrderInfo> orderInfoList) {
      if (this.orderCustomBusiness.place().willCheckWaitPalaceOrder(orderInfoList)) {
         this.orderInfoService.existWaitPlaceOrder(((OrderInfo)orderInfoList.get(0)).getCustId(), ((OrderInfo)orderInfoList.get(0)).getSourceType());
      }

   }

   public void orderHandlerLock(String lockId, int lockSecond) {
      String lockKey = OrderCacheConstants.orderHandleLockKey(lockId);
      if (!RedisUtil.setNx(lockKey, LeConstants.COMMON_YES, lockSecond)) {
         log.info("[订单处理中] 订单处理中 {} ", lockId);
         throw new ServiceException(I18n.getMessage("order.mac.processing", new Object[0]), RetCodeEnum.PAY_QRCODE_ING.getKey());
      } else {
         log.info("[订单处理中] 加锁 {} {}", lockId, lockSecond);
      }
   }

   public void orderHandlerUnLock(String lockId) {
      String lockKey = OrderCacheConstants.orderHandleLockKey(lockId);
      RedisUtil.delete(lockKey);
      log.info("[订单处理中] 解锁 {}", lockKey);
   }
//
//   public void saveCache(OrderSavePO orderSavePO, boolean saveToDiskAsync) {
//      log.info("[订单缓存]保存订单缓存 {} {}", orderSavePO.getMacOrderId(), saveToDiskAsync);
//      RedisUtil.setString(OrderCacheConstants.orderCacheKey(orderSavePO.getMacOrderId()), JacksonUtil.writeValueAsString(orderSavePO), OrderCacheConstants.WEIGHT_CACHE_SECONDS);
//      if (saveToDiskAsync) {
//         OrderMessageSend.orderV3AsyncSaveWeight(orderSavePO.getMacOrderId());
//      }
//
//   }
//
//   public void cleanCache(String macOrderId) {
//      log.info("[订单缓存]删除订单缓存 {}", macOrderId);
//      RedisUtil.delete(OrderCacheConstants.orderCacheKey(macOrderId));
//   }

   public AllocMealtimeModel checkMealtime(Integer mealtimeType, Long canteenId, Long stallId) {
      return this.checkMealtime(mealtimeType, null, canteenId, stallId);
   }

   @NotNull
   public AllocMealtimeModel checkMealtime(@Nullable Integer mealtimeType, @Nullable LocalDateTime orderTime, @Nullable Long canteenId, @Nullable Long stallId) {
      log.info("[订单餐次]检查餐次 {} {} {} {}", new Object[]{mealtimeType, orderTime, canteenId, stallId});
      AllocMealtimeModel availableMealtime;
      if (mealtimeType != null) {
         availableMealtime = this.orderModuleClient.mealtimeQuery(MealtimeQueryParam.ofMealtimeType(mealtimeType, canteenId, stallId));
      } else if (orderTime != null) {
         availableMealtime = this.orderModuleClient.mealtimeQuery(MealtimeQueryParam.ofAssignTime(orderTime.toLocalTime(), canteenId, stallId));
      } else {
         availableMealtime = this.orderModuleClient.mealtimeCheckNow(MealtimeCheckNowParam.of(canteenId, stallId));
      }

      if (availableMealtime == null) {
         throw new ServiceException(I18n.getMessage("order.mobile.no-mealtime", new Object[0]));
      } else {
         log.info("[订单餐次]检查餐次 返回 {}", availableMealtime);
         return availableMealtime;
      }
   }

   public void checkOrderPermission(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList) {
      LogUtil.infoFields("订单权限校验", orderInfoList, OrderInfo.logFieldsRelated());
      if (this.orderCustomBusiness.place().willCheckOrderPermission(orderInfoList, orderDetailList)) {
         if (CollUtil.isEmpty(orderInfoList)) {
            throw new ServiceException(OrderTips.noOrder());
         } else {
            boolean isOnline = LeConstants.COMMON_YES.equals(((OrderInfo)orderInfoList.get(0)).getIfOnline());
            if (isOnline) {
               RulePriceDTO rulePriceDTO = this.packageRulePriceDTO(orderInfoList, orderDetailList, false);
               if (this.orderCustomBusiness.place().willCallApiCheckOrderPermission(orderInfoList, orderDetailList, rulePriceDTO)) {
                  this.marketApi.ruleMealCompute(rulePriceDTO);
               }

            }
         }
      }
   }

   public void fillOrderDetailPrice(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList) {
      LogUtil.infoFieldsX("价格组装-订单", orderInfoList, OrderInfo.logFieldsRelated(), orderDetailList, OrderDetail.logFieldsGoods());
      if (this.orderCustomBusiness.place().willFillOrderDetailPrice(orderInfoList, orderDetailList)) {
         Map<String, AllocMealtimeModel> mealtimeMap = MapUtil.newHashMap();
         Iterator var4 = orderInfoList.iterator();

         while(var4.hasNext()) {
            OrderInfo orderInfo = (OrderInfo)var4.next();
            List<OrderDetail> orderDetailListByOrderId = (List)orderDetailList.stream().filter((orderDetailx) -> {
               return orderDetailx.getOrderId().equals(orderInfo.getOrderId());
            }).collect(Collectors.toList());
            Iterator var7 = orderDetailListByOrderId.iterator();

            while(var7.hasNext()) {
               OrderDetail orderDetail = (OrderDetail)var7.next();
               if (DetailTypeEnum.isProductType(orderDetail.getDetailType())) {
                  SupermarketQueryProductInfoDTO productInfoDTO = new SupermarketQueryProductInfoDTO();
                  productInfoDTO.setGoodsId(orderDetail.getGoodsDishesId());
                  productInfoDTO.setDetailId(orderDetail.getMenuDetailId());
                  SupermarketQueryProductInfoVO productInfoVO = this.supermarketApi.queryProductInfo(productInfoDTO);
                  if (productInfoVO == null) {
                     throw new ServiceException(I18n.getMessage("order.mobile.dishes-not-found", new Object[0]));
                  }

                  LogUtil.info("明细价格组装-商品", productInfoVO);
                  orderDetail.setSalePrice(productInfoVO.getSalePrice() != null ? BigDecimal.valueOf((long)productInfoVO.getSalePrice()) : BigDecimal.ZERO);
                  orderDetail.setPrefPrice(productInfoVO.getPrefPrice() != null ? BigDecimal.valueOf((long)productInfoVO.getPrefPrice()) : BigDecimal.ZERO);
               } else if (DetailTypeEnum.isDishesCategory(orderDetail.getDetailType())) {
                  OrderRecipeDishesDto orderDishesDetail = this.menuRecipeApi.getOrderDishesDetail(orderDetail.getMenuDetailId(), orderDetail.getGoodsDishesId());
                  if (orderDishesDetail == null) {
                     throw new ServiceException(I18n.getMessage("order.mobile.dishes-not-found", new Object[0]));
                  }

                  LogUtil.info("明细价格组装-菜品 {}", orderDishesDetail);
                  orderDetail.setSalePrice(orderDishesDetail.getPrice() != null ? BigDecimal.valueOf((long)orderDishesDetail.getPrice()) : BigDecimal.ZERO);
                  orderDetail.setPrefPrice(orderDishesDetail.getSalePrice() != null ? BigDecimal.valueOf((long)orderDishesDetail.getSalePrice()) : BigDecimal.ZERO);
               } else if (DetailTypeEnum.isBookType(orderDetail.getDetailType())) {
                  Integer var10000 = orderInfo.getMealtimeType();
                  String mealTimeKey = "" + var10000 + "_" + orderInfo.getCanteenId() + "_" + orderInfo.getStallId();
                  AllocMealtimeModel mealtime = (AllocMealtimeModel)mealtimeMap.getOrDefault(mealTimeKey, this.orderModuleClient.mealtimeQuery(MealtimeQueryParam.ofMealtimeType(orderInfo.getMealtimeType(), orderInfo.getCanteenId(), orderInfo.getStallId())));
                  if (mealtime != null) {
                     mealtimeMap.put(mealTimeKey, mealtime);
                     orderDetail.setSalePrice(mealtime.getBookAmount() != null ? mealtime.getBookAmount() : BigDecimal.ZERO);
                     orderDetail.setPrefPrice(orderDetail.getSalePrice());
                  }
               } else {
                  orderDetail.setSalePrice(orderDetail.getSalePrice() != null ? orderDetail.getSalePrice() : BigDecimal.ZERO);
                  orderDetail.setPrefPrice(orderDetail.getPrefPrice() != null ? orderDetail.getPrefPrice() : orderDetail.getSalePrice());
               }
            }
         }

         this.orderCustomBusiness.place().didFillOrderDetailPrice(orderInfoList, orderDetailList);
      }
   }

   public List<OrderAmountChange> calcNeedPayAmount(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList) {
      LogUtil.infoFieldsX("金额计算-订单", orderInfoList, OrderInfo.logFieldsAmount(), orderDetailList, OrderDetail.logFieldsAmount());
      List<OrderAmountChange> amountChangeList = CollUtil.newArrayList(new OrderAmountChange[0]);
      if (!this.orderCustomBusiness.place().willCalcNeedPayAmount(orderInfoList, orderDetailList, amountChangeList)) {
         this.orderCustomBusiness.place().didCalcNeedPayAmount(orderInfoList, orderDetailList, amountChangeList);
         return amountChangeList;
      } else {
         Iterator var4 = orderInfoList.iterator();

         OrderInfo orderInfo;
         while(var4.hasNext()) {
            orderInfo = (OrderInfo)var4.next();
            OrderInfo finalOrderInfo = orderInfo;
            List<OrderDetail> targetOrderDetails = orderDetailList.stream().filter((s) -> {
               return s.getOrderId().equals(finalOrderInfo.getOrderId());
            }).collect(Collectors.toList());
            this.calcOrderAndDetailTotalAmount(orderInfo, targetOrderDetails);
         }

         var4 = orderInfoList.iterator();

         while(var4.hasNext()) {
            orderInfo = (OrderInfo)var4.next();
            OrderInfo finalOrderInfo1 = orderInfo;
            BigDecimal dishesDiscountAmount = orderDetailList.stream().filter((s) -> {
               return s.getOrderId().equals(finalOrderInfo1.getOrderId());
            }).map((s) -> {
               return s.getTotalAmount().subtract(s.getCalcTotalAmount());
            }).reduce(BigDecimal.ZERO, BigDecimal::add);
            orderInfo.setDiscountsAmount(BigDecimal.ZERO);
            if (dishesDiscountAmount.compareTo(BigDecimal.ZERO) > 0) {
               amountChangeList.add(this.addAmountChange(orderInfo, dishesDiscountAmount, ChangeDetailTypeEnum.DISHES_DISCOUNTS, (String)null));
            }

            if (orderInfo.getDeliveryAmount().compareTo(BigDecimal.ZERO) > 0) {
               amountChangeList.add(this.addAmountChange(orderInfo, orderInfo.getDeliveryAmount().negate(), ChangeDetailTypeEnum.DELIVERY, (String)null));
            }

            if (orderInfo.getPackingAmount().compareTo(BigDecimal.ZERO) > 0) {
               amountChangeList.add(this.addAmountChange(orderInfo, orderInfo.getPackingAmount().negate(), ChangeDetailTypeEnum.PACKING, (String)null));
            }
         }

         this.orderCustomBusiness.place().didCalcNeedPayAmount(orderInfoList, orderDetailList, amountChangeList);
         LogUtil.infoFieldsX("金额计算-订单-结果", orderInfoList, OrderInfo.logFieldsAmount(), orderDetailList, OrderDetail.logFieldsAmount(), amountChangeList, OrderAmountChange.logFields());
         return amountChangeList;
      }
   }

   public OrderAmountChange addAmountChange(OrderInfo orderInfo, BigDecimal changeAmount, ChangeDetailTypeEnum type, String remark) {
      LogUtil.info("添加金额变动", orderInfo.getOrderId(), orderInfo.getPayableAmount(), orderInfo.getDiscountsAmount(), changeAmount, type, remark);
      OrderAmountChange orderAmountChange = this.orderCustomBusiness.place().willAddAmountChange(orderInfo, changeAmount, type);
      if (orderAmountChange != null) {
         orderAmountChange = this.orderCustomBusiness.place().didAddAmountChange(orderInfo, changeAmount, type, orderAmountChange);
         return orderAmountChange;
      } else {
         if (changeAmount != null && changeAmount.compareTo(BigDecimal.ZERO) != 0) {
            orderAmountChange = OrderAmountChange.newInstance(orderInfo.getOrderId(), orderInfo.getOrderDate(), type, changeAmount, remark);
            orderInfo.plusDiscountAmount(changeAmount);
         }

         orderAmountChange = this.orderCustomBusiness.place().didAddAmountChange(orderInfo, changeAmount, type, orderAmountChange);
         LogUtil.infoFieldsX("添加金额变动-结果", orderAmountChange, OrderAmountChange.logFields());
         return orderAmountChange;
      }
   }
//
//   public List<OrderAmountChange> customNeedPayAmount(List<OrderInfo> orderInfoList, BigDecimal customAmount) {
//      LogUtil.infoFieldsX("指定待支付金额计算", orderInfoList, OrderInfo.logFieldsAmount());
//      List<OrderAmountChange> amountChangeList = CollUtil.newArrayList(new OrderAmountChange[0]);
//      if (!this.orderCustomBusiness.place().willCustomNeedPayAmount(orderInfoList, customAmount, amountChangeList)) {
//         this.orderCustomBusiness.place().didCustomNeedPayAmount(orderInfoList, customAmount, amountChangeList);
//         return amountChangeList;
//      } else {
//         BigDecimal needPayAmount = (BigDecimal)orderInfoList.stream().map(OrderInfo::calcNeedPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//         if (needPayAmount.compareTo(customAmount) != 0) {
//            log.info("[指定金额计算]人工指定待支付金额 {} {}", needPayAmount, customAmount);
//            LeOrderUtil.calcOrderAmount(orderInfoList, needPayAmount.subtract(customAmount), (orderInfo, discountAmount) -> {
//               if (discountAmount.compareTo(BigDecimal.ZERO) != 0) {
//                  amountChangeList.add(this.addAmountChange(orderInfo, discountAmount, ChangeDetailTypeEnum.OTHER, (String)null));
//               }
//
//            });
//         }
//
//         this.orderCustomBusiness.place().didCustomNeedPayAmount(orderInfoList, customAmount, amountChangeList);
//         LogUtil.infoFieldsX("指定待支付金额计算-结果", orderInfoList, OrderInfo.logFieldsAmount(), amountChangeList, OrderAmountChange.logFields());
//         return amountChangeList;
//      }
//   }

   public List<OrderAmountChange> calcRuleAmount(UnifyPayDTO unifyPayDTO, List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, boolean isTrail) {
      LogUtil.infoFieldsX("消费规则计算", orderInfoList, OrderInfo.logFieldsAmount(), orderDetailList, OrderDetail.logFieldsAmount());
      List<OrderAmountChange> amountChangeList = CollUtil.newArrayList(new OrderAmountChange[0]);
      if (!this.orderCustomBusiness.place().willCalcRuleAmount(unifyPayDTO, orderInfoList, orderDetailList, amountChangeList, isTrail)) {
         this.orderCustomBusiness.place().didCalcRuleAmount(unifyPayDTO, orderInfoList, orderDetailList, amountChangeList, isTrail);
         return amountChangeList;
      } else {
         Map<Long, OrderInfo> orderInfoMap = orderInfoList.stream().collect(Collectors.toMap(OrderInfo::getOrderId, Function.identity()));
         RulePriceDTO rulePriceDTO = this.packageRulePriceDTO(orderInfoList, orderDetailList, isTrail);
         rulePriceDTO = this.orderCustomBusiness.place().didPackageRulePriceDTO(unifyPayDTO, orderInfoList, orderDetailList, amountChangeList, isTrail, rulePriceDTO);
         RulePriceResultDTO rulePriceResult = this.marketApi.rulePriceCompute(rulePriceDTO);
         LogUtil.info("订单金额计算-结果", rulePriceResult);
         unifyPayDTO.setAmount(rulePriceResult.getRealAmount());
         unifyPayDTO.setRulePriceResult(rulePriceResult);
         if (CollUtil.isEmpty(rulePriceResult.getOrderResults())) {
            return amountChangeList;
         } else {
            Iterator var9 = rulePriceResult.getOrderResults().iterator();

            while(var9.hasNext()) {
               RulePriceResultOrderDTO orderResult = (RulePriceResultOrderDTO)var9.next();
               OrderInfo orderInfo = (OrderInfo)orderInfoMap.get(orderResult.getOrderId());
               if (orderInfo != null && !CollUtil.isEmpty(orderResult.getRuleRecord())) {
                  List<OrderAmountChange> orderAmountChanges = orderResult.getRuleRecord().stream().filter((s) -> {
                     return !NumberUtil.equals(s.getDiscountsAmount(), BigDecimal.ZERO);
                  }).map((s) -> {
                     return this.addAmountChange(orderInfo, s.getDiscountsAmount(), ChangeDetailTypeEnum.RULE_DISCOUNT, s.getRuleTypeText());
                  }).collect(Collectors.toList());
                  amountChangeList.addAll(orderAmountChanges);
               }
            }

            this.orderCustomBusiness.place().didCalcRuleAmount(unifyPayDTO, orderInfoList, orderDetailList, amountChangeList, isTrail);
            return amountChangeList;
         }
      }
   }

   public MktCouponPayModel checkCoupon(UnifyPayDTO unifyPayDTO, List<OrderInfo> orderInfoList) {
      LogUtil.infoFieldsX("检查餐券", unifyPayDTO, UnifyPayDTO.logFieldsAmount(), orderInfoList, OrderInfo.logFieldsAmount());
      MktCouponPayModel couponPayModel = null;
      if (!this.orderCustomBusiness.place().willCheckCouponV3(unifyPayDTO, orderInfoList)) {
         couponPayModel = this.orderCustomBusiness.place().didCheckCouponV3(unifyPayDTO, orderInfoList, (MktCouponPayModel)null);
         return couponPayModel;
      } else {
         List<Integer> supportAutoCouponScenario = CollUtil.toList(new Integer[]{PayChannelSelectEnum.DEVICE_CONSUME.getKey()
                 , PayChannelSelectEnum.DEVICE_OFFLINE_CONSUME.getKey(), PayChannelSelectEnum.OPEN_CONSUME.getKey()});
         boolean autoCoupon = supportAutoCouponScenario.contains(unifyPayDTO.getScenario()) && !unifyPayDTO.containsRuleWalletDetail()
                 && LeConstants.COMMON_YES.toString().equals(this.orderModuleClient
                 .metadataGetValue(MetaDataValueParam.ofMerchant(MetadataModelTypeEnum.MOBILE, "ifAutoDeductElecCoupon")));
         MktCouponMacPayModel mktSearchParam = new MktCouponMacPayModel();
         mktSearchParam.setOrderType((Integer)LeNumUtil.reduceField(orderInfoList, OrderInfo::getOrderType, (Object)null));
         mktSearchParam.setCanteenIds(orderInfoList.stream().map(OrderInfo::getCanteenId).filter(LeNumUtil::isValidId).collect(Collectors.toSet()));
         mktSearchParam.setStallIds(orderInfoList.stream().map(OrderInfo::getStallId).filter(LeNumUtil::isValidId).collect(Collectors.toSet()));
         mktSearchParam.setMealtimeIds(orderInfoList.stream().map(OrderInfo::getMealtimeType).filter(LeNumUtil::isValidId).map(Long::valueOf).collect(Collectors.toSet()));
         if (CharSequenceUtil.split(unifyPayDTO.getCouponId(), ",", true, true).size() > 1) {
            log.warn("[餐券支付]不支持多张餐券支付 {}", unifyPayDTO.getCouponId());
            throw new ServiceException(I18n.getMessage("order.mac.coupon-unusable", new Object[0]));
         } else {
            if (CharSequenceUtil.isNotBlank(unifyPayDTO.getCouponId())) {
               mktSearchParam.setCouponNum(Long.valueOf(unifyPayDTO.getCouponId()));
               couponPayModel = this.mktCouponApi.getCouponAmountForMacPay(mktSearchParam);
               LogUtil.info("通过餐券号查询餐券结果", mktSearchParam, couponPayModel);
               if (couponPayModel == null) {
                  throw new ServiceException(I18n.getMessage("order.mac.coupon-unusable", new Object[0]));
               }
            } else if (autoCoupon && LeNumUtil.isValidId(unifyPayDTO.getCustId())) {
               mktSearchParam.setCustId(unifyPayDTO.getCustId());
               mktSearchParam.setOrderAmount(unifyPayDTO.getAmount());
               mktSearchParam.setCouponType(MktCouponTypeEnum.ELECTRON_COUPON.getKey());
               couponPayModel = this.mktCouponApi.getCouponAmountForMacPay(mktSearchParam);
               LogUtil.info("自动抵扣查询餐券结果", mktSearchParam, couponPayModel);
               if (couponPayModel != null) {
                  unifyPayDTO.setCouponId(couponPayModel.getCouponNum().toString());
                  unifyPayDTO.getPayChannelSplits().add(0, PayChannelSplitVO.of(PayTypeEnum.COUPON.getKey()
                          , PayChannelEnum.COUPON.getKey()));
               }
            }

            if (couponPayModel != null && (PayTypeEnum.COUPON.getKey().equals(unifyPayDTO.getPayType()) || unifyPayDTO.containsRuleWalletDetail())) {
               BigDecimal couponAmount = couponPayModel.getCouponAmount().multiply(BigDecimal.valueOf(100L));
               log.info("[券计算]订单金额{}, 餐券金额{}", unifyPayDTO.getAmount(), couponAmount);
               if (unifyPayDTO.getAmount().compareTo(couponAmount) > 0) {
                  throw new ServiceException(I18n.getMessage("order.mac.coupon-amount-not-enough", new Object[0]));
               }
            }

            couponPayModel = this.orderCustomBusiness.place().didCheckCouponV3(unifyPayDTO, orderInfoList, couponPayModel);
            return couponPayModel;
         }
      }
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void inventoryDeduct(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList) {
      LogUtil.infoFieldsX("库存扣减", orderInfoList, OrderInfo.logFieldsRelated(), orderDetailList, OrderDetail.logFieldsGoods());
      if (this.orderCustomBusiness.place().willInventoryDeduct(orderInfoList, orderDetailList)) {
         List<SupermarketInventoryRepairDTO> shopRepairList = CollUtil.newArrayList(new SupermarketInventoryRepairDTO[0]);
         List<MenuRecipeChangeSurplusNum> dishRepairList = CollUtil.newArrayList(new MenuRecipeChangeSurplusNum[0]);

         try {
            Iterator var5 = orderInfoList.iterator();

            while(var5.hasNext()) {
               OrderInfo orderInfo = (OrderInfo)var5.next();
               List<OrderDetail> targetOrderDetails = (List)orderDetailList.stream().filter((s) -> {
                  return s.getOrderId().equals(orderInfo.getOrderId());
               }).collect(Collectors.toList());
               if (OrderTypeEnum.isShopCategory(orderInfo.getOrderType())) {
                  this.shopLimitHandler(orderInfo, targetOrderDetails);
                  this.shopInventoryHandler(orderInfo, targetOrderDetails, shopRepairList);
               } else {
                  Set<Long> goodsIdsForThisOrder = this.dishesInventoryHandler(orderInfo, targetOrderDetails, dishRepairList);
                  if (CollUtil.isNotEmpty(goodsIdsForThisOrder)) {
                     throw new ServiceException(I18n.getMessage("order.mac.change-surplus-num", new Object[0]));
                  }
               }
            }

         } catch (Exception var9) {
            orderInfoList.forEach((s) -> {
               s.setInventoryOutId((String)null);
            });
            throw var9;
         }
      }
   }

   public void inventoryRestore(OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
      if (!CollUtil.isEmpty(orderDetailList)) {
         if (!CharSequenceUtil.isBlank(orderInfo.getInventoryOutId())) {
            LogUtil.infoFieldsX("库存恢复", orderInfo, OrderInfo.logFieldsRelated(), orderDetailList, OrderDetail.logFieldsGoods());
            if (this.orderCustomBusiness.place().willInventoryRepair(orderInfo, orderDetailList)) {
               try {
                  if (OrderTypeEnum.SHOP.getKey().equals(orderInfo.getOrderType())) {
                     SupermarketInventoryRepairDTO repairDTO = new SupermarketInventoryRepairDTO();
                     repairDTO.setOrdId(orderInfo.getOrderId());
                     repairDTO.setSupermarketId(orderInfo.getCanteenId());
                     repairDTO.setOutId(orderInfo.getInventoryOutId());
                     if (this.orderCustomBusiness.place().willShopInventoryRepair(orderInfo, orderDetailList, repairDTO)) {
                        this.drpServiceApi.supermarketInventoryRepair(repairDTO, orderInfo.getCanteenId());
                     }
                  } else {
                     List<MenuRecipeChangeSurplusNum> changeList = orderDetailList.stream().filter((s) -> {
                        return DetailTypeEnum.isDishesCategory(s.getDetailType());
                     }).map((detail) -> {
                        MenuRecipeChangeSurplusNum recover = new MenuRecipeChangeSurplusNum();
                        recover.setDetailId(detail.getMenuDetailId());
                        recover.setProductId(detail.getGoodsDishesId());
                        recover.setSaleNum(-detail.getQuantity());
                        return recover;
                     }).collect(Collectors.toList());
                     if (CollUtil.isEmpty(changeList)) {
                        return;
                     }

                     if (this.orderCustomBusiness.place().willDishesInventoryRepair(orderInfo, orderDetailList, changeList)) {
                        this.menuDishesApi.changeSurplusNum(changeList, (Long)null, (Integer)null, (LocalDate)null);
                     }
                  }
               } catch (Exception var4) {
                  log.info("[恢复库存]恢复库存失败", var4);
               }

            }
         }
      }
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void save(OrderSavePO orderSavePO, boolean removeDetails, boolean removeAmountChanges) {
      LogUtil.info("订单保存", orderSavePO);
      if (!this.orderCustomBusiness.place().willSaveOrder(orderSavePO, removeDetails, removeAmountChanges)) {
         this.orderCustomBusiness.place().didSaveOrder(orderSavePO, removeDetails, removeAmountChanges);
      } else {
         List<Long> orderIds = orderSavePO.getOrderInfoList().stream().map(OrderInfo::getOrderId).collect(Collectors.toList());
         Map<Long, LocalDate> orderDateMapByOrderId = orderSavePO.getOrderInfoList().stream().collect(Collectors.toMap(OrderInfo::getOrderId, OrderInfo::getOrderDate));
         if (removeDetails) {
            this.orderDetailService.removeByOrderIds(orderIds, orderDateMapByOrderId.values());
         }

         if (removeAmountChanges) {
            this.orderAmountChangeService.deleteByOrderIds(orderIds, orderDateMapByOrderId.values());
         }

         if (CollUtil.isNotEmpty(orderSavePO.getOrderInfoList())) {
            this.orderInfoService.saveList(orderSavePO.getOrderInfoList());
         }

         if (CollUtil.isNotEmpty(orderSavePO.getOrderDetailList())) {
            orderSavePO.getOrderDetailList().stream().filter((s) -> {
               return s.getOrderDate() == null;
            }).forEach((s) -> {
               s.setOrderDate((LocalDate)orderDateMapByOrderId.get(s.getOrderId()));
            });
            this.orderDetailService.saveList(orderSavePO.getOrderDetailList());
         }

         if (CollUtil.isNotEmpty(orderSavePO.getOrderDeliveryList())) {
            orderSavePO.getOrderDeliveryList().stream().filter((s) -> {
               return s.getOrderDate() == null;
            }).forEach((s) -> {
               s.setOrderDate((LocalDate)orderDateMapByOrderId.get(s.getOrderId()));
            });
            this.orderDeliveryService.deleteByOrderIds(orderIds, orderDateMapByOrderId.values());
            this.orderDeliveryService.insertList(orderSavePO.getOrderDeliveryList());
         }

         if (CollUtil.isNotEmpty(orderSavePO.getAmountChangeList())) {
            orderSavePO.getAmountChangeList().stream().filter((s) -> {
               return s.getOrderDate() == null;
            }).forEach((s) -> {
               s.setOrderDate((LocalDate)orderDateMapByOrderId.get(s.getOrderId()));
            });
            this.orderAmountChangeService.saveList(orderSavePO.getAmountChangeList());
         }

         if (CollUtil.isNotEmpty(orderSavePO.getAmountDetailList())) {
            orderSavePO.getAmountDetailList().stream().filter((s) -> {
               return s.getOrderDate() == null;
            }).forEach((s) -> {
               s.setOrderDate((LocalDate)orderDateMapByOrderId.get(s.getOrderId()));
            });
            this.orderAmountDetailService.deleteByOrderIds(orderIds, orderDateMapByOrderId.values());
            this.orderAmountDetailService.insertList(orderSavePO.getAmountDetailList());
         }

         this.orderCustomBusiness.place().didSaveOrder(orderSavePO, removeDetails, removeAmountChanges);
      }
   }

   public UnifyPayVO pay(UnifyPayDTO unifyPayDTO, List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList) {
      UnifyPayVO customPayVO = this.orderCustomBusiness.place().willOrderPayV2(unifyPayDTO, orderInfoList, orderDetailList);
      if (customPayVO != null) {
         return customPayVO;
      } else {
         unifyPayDTO.setOrderList((List)orderInfoList.stream().map(UnifyPayDTO.Order::of).collect(Collectors.toList()));
         unifyPayDTO.setDetailList((List)orderDetailList.stream().map(UnifyPayDTO.Detail::of).collect(Collectors.toList()));
         return this.payApi.pay(unifyPayDTO);
      }
   }
//
//   public List<OrderDetail> removeDetailDishes(List<OrderDetail> orderDetailList, List<OrderDetailRefundDTO> removeList) {
//      List<OrderDetail> removedDetails = CollUtil.newArrayList(new OrderDetail[0]);
//      if (CollUtil.isEmpty(removeList)) {
//         return removedDetails;
//      } else {
//         LogUtil.infoFieldsX("扣减菜品", orderDetailList, OrderDetail.logFieldsAmount(), removeList, OrderDetailRefundDTO.logFields());
//         Iterator var4 = removeList.iterator();
//
//         while(var4.hasNext()) {
//            OrderDetailRefundDTO orderDetailRefundDTO = (OrderDetailRefundDTO)var4.next();
//            OrderDetail orderDetail = (OrderDetail)orderDetailList.stream().filter((s) -> {
//               return s.getDetailId().equals(orderDetailRefundDTO.getDetailId());
//            }).findFirst().orElse((Object)null);
//            if (orderDetail != null) {
//               if (orderDetailRefundDTO.getQuantity().compareTo(orderDetail.calcUnRefundGoodsNum()) > 0) {
//                  throw new LeException(I18n.getMessage("order.refund.refund-times-limit", new Object[0]));
//               }
//
//               orderDetail.setQuantity(NumberUtil.sub(orderDetail.getQuantity(), orderDetailRefundDTO.getQuantity()).intValue());
//               OrderDetail removedOrderDetail = (OrderDetail)BeanUtil.copyProperties(orderDetail, OrderDetail.class, new String[0]);
//               removedOrderDetail.setQuantity(orderDetailRefundDTO.getQuantity());
//               removedDetails.add(removedOrderDetail);
//            }
//         }
//
//         orderDetailList.removeIf((s) -> {
//            return s.getQuantity() == 0;
//         });
//         return removedDetails;
//      }
//   }
//
   protected Set<Long> dishesInventoryHandler(OrderInfo orderInfo, List<OrderDetail> orderDetailList, List<MenuRecipeChangeSurplusNum> alreadyChangeSurplusNumList) {
      Set<Long> goodIds = CollUtil.newHashSet(new Long[0]);
      if (CollUtil.isEmpty(orderDetailList)) {
         return goodIds;
      } else {
         List<MenuRecipeChangeSurplusNum> changeSurplusNumList = orderDetailList.stream().filter((s) -> {
            return DetailTypeEnum.isDishesCategory(s.getDetailType());
         }).map((detail) -> {
            MenuRecipeChangeSurplusNum changeSurplusNum = new MenuRecipeChangeSurplusNum();
            changeSurplusNum.setProductId(detail.getGoodsDishesId());
            changeSurplusNum.setSaleNum(detail.getQuantity());
            changeSurplusNum.setDetailId(detail.getMenuDetailId());
            return changeSurplusNum;
         }).collect(Collectors.toList());
         if (!CollUtil.isNotEmpty(changeSurplusNumList)) {
            return (Set)goodIds;
         } else {
            try {
               if (this.orderCustomBusiness.place().willDishesInventoryDeduct(orderInfo, orderDetailList, changeSurplusNumList, (Set)goodIds)) {
                  goodIds = this.menuDishesApi.changeSurplusNum(changeSurplusNumList, orderInfo.getCustId(), orderInfo.getMealtimeType(), orderInfo.getOrderDate());
               }
            } catch (Exception var7) {
               log.error("调用菜品扣减库存接口异常", var7);
               if (CollUtil.isNotEmpty(alreadyChangeSurplusNumList)) {
                  alreadyChangeSurplusNumList.forEach((s) -> {
                     s.setSaleNum(-s.getSaleNum());
                  });
                  this.menuDishesApi.changeSurplusNum(alreadyChangeSurplusNumList, (Long)null, (Integer)null, (LocalDate)null);
               }

               throw var7;
            }

            if (CollUtil.isNotEmpty((Collection)goodIds)) {
               log.error("调用菜品扣减库存失败: {}", goodIds);
               if (CollUtil.isNotEmpty(alreadyChangeSurplusNumList)) {
                  alreadyChangeSurplusNumList.forEach((s) -> {
                     s.setSaleNum(-s.getSaleNum());
                  });
                  this.menuDishesApi.changeSurplusNum(alreadyChangeSurplusNumList, (Long)null, (Integer)null, (LocalDate)null);
               }
            } else {
               alreadyChangeSurplusNumList.addAll(changeSurplusNumList);
               orderInfo.setInventoryOutId(orderInfo.getOrderId().toString());
            }

            return (Set)goodIds;
         }
      }
   }

   protected void shopLimitHandler(OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
      List<Long> goodsIdList = orderDetailList.stream().filter((s) -> {
         return DetailTypeEnum.isProductType(s.getDetailType());
      }).map(OrderDetail::getGoodsDishesId).collect(Collectors.toList());
      if (!CollUtil.isEmpty(goodsIdList)) {
         Map<Long, List<OrderDetail>> detailGroupByGoodsId = orderDetailList.stream().collect(Collectors.groupingBy(OrderDetail::getGoodsDishesId));
         Map<Long, Integer> detailQuantityMap = this.orderDetailService.getQuantityByCustId(orderInfo.getCustId(), orderInfo.getOrderDate(),
                null, goodsIdList).stream().collect(Collectors.toMap(OrderGoodsNumVO::getGoodsDishesId, (orderDetail) -> {
            return orderDetail.getQuantity() - orderDetail.getGoodsRefundNum();
         }));
         SmtCheckProductLimitBuyDTO checkDTO = new SmtCheckProductLimitBuyDTO();
         checkDTO.setSupermarketId(orderInfo.getCanteenId());
         checkDTO.setDetailList(detailGroupByGoodsId.keySet().stream().map((s) -> {
            List<OrderDetail> orderDetails = detailGroupByGoodsId.get(s);
            SmtCheckProductLimitBuyDetailDTO detailDTO = new SmtCheckProductLimitBuyDetailDTO();
            detailDTO.setOrderDate(orderInfo.getOrderDate());
            detailDTO.setProductId(s);
            detailDTO.setProductName(((OrderDetail)orderDetails.get(0)).getGoodsDishesName());
            detailDTO.setCurrentProductNum(LeNumUtil.sumFieldInt(orderDetails, OrderDetail::getQuantity));
            detailDTO.setTodayProductNum((Integer)detailQuantityMap.getOrDefault(s, 0));
            return detailDTO;
         }).collect(Collectors.toList()));
         if (this.orderCustomBusiness.place().willShopInventoryLimit(orderInfo, orderDetailList, checkDTO)) {
            this.supermarketApi.checkProductLimitBuy(checkDTO);
         }

      }
   }

   protected void shopInventoryHandler(OrderInfo orderInfo, List<OrderDetail> orderDetailList, List<SupermarketInventoryRepairDTO> alreadyOutList) {
      if (OrderTypeEnum.SHOP.getKey().equals(orderInfo.getOrderType())) {
         List<Long> goodsIdList = orderDetailList.stream().filter((s) -> {
            return DetailTypeEnum.isProductType(s.getDetailType());
         }).map(OrderDetail::getGoodsDishesId).collect(Collectors.toList());
         if (!CollUtil.isEmpty(goodsIdList)) {
            List<AndroidSupermarketOutDetailDTO> inventoryList = orderDetailList.stream().filter((s) -> {
               return DetailTypeEnum.isProductType(s.getDetailType());
            }).map((orderDetail) -> {
               AndroidSupermarketOutDetailDTO outDetailDTO = new AndroidSupermarketOutDetailDTO();
               outDetailDTO.setSupermarketDetailId(orderDetail.getMenuDetailId());
               outDetailDTO.setFetchNum(BigDecimal.valueOf((long)orderDetail.getQuantity()));
               outDetailDTO.setSalesMode(orderDetail.getSalesMode());
               if (CharSequenceUtil.isNotBlank(orderDetail.getInventoryId())) {
                  outDetailDTO.setInventoryId(Long.valueOf(orderDetail.getInventoryId()));
               }

               return outDetailDTO;
            }).collect(Collectors.toList());
            if (!CollUtil.isEmpty(inventoryList)) {
               AndroidSupermarketOutDTO outDTO = new AndroidSupermarketOutDTO();
               outDTO.setSupermarketId(orderInfo.getCanteenId());
               outDTO.setOutDate(LocalDateTime.now());
               outDTO.setOutType(DrpOutInventoryTypeEnum.SUPERMARKET_OUT.key());
               outDTO.setOrdId(orderInfo.getOrderId());
               outDTO.setDetailList(inventoryList);
               RLock lock = RedisUtil.getLock(OrderCacheConstants.mobileShopInventoryLockKey(orderInfo.getCanteenId()));
               lock.lock();

               try {
                  if (this.orderCustomBusiness.place().willShopInventoryDeduct(orderInfo, orderDetailList, outDTO)) {
                     String outId = this.drpServiceApi.outInventoryBySupermarketPay(outDTO);
                     orderInfo.setInventoryOutId(outId);
                     SupermarketInventoryRepairDTO repairDTO = new SupermarketInventoryRepairDTO();
                     repairDTO.setOrdId(outDTO.getOrdId());
                     repairDTO.setOutId(outId);
                     repairDTO.setSupermarketId(outDTO.getSupermarketId());
                     alreadyOutList.add(repairDTO);
                  }
               } catch (Exception var18) {
                  Iterator var9 = alreadyOutList.iterator();

                  while(var9.hasNext()) {
                     SupermarketInventoryRepairDTO repairDTO = (SupermarketInventoryRepairDTO)var9.next();
                     this.drpServiceApi.supermarketInventoryRepair(repairDTO, repairDTO.getSupermarketId());
                  }

                  throw var18;
               } finally {
                  try {
                     if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                        lock.unlock();
                     }
                  } catch (Exception var17) {
                     log.error("解锁异常", var17);
                  }

               }

            }
         }
      }
   }

   public OrderDeliveryResultVO fillOrderDeliveryAmount(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList
           , List<OrderDelivery> orderDeliveryList) {
      LogUtil.infoFields("订单计算配送费", orderInfoList, "orderId", "custId", "canteenId", "stallId", "orderType", "deliveryType");
      OrderDeliveryResultVO resultVO = OrderDeliveryResultVO.successInstance();
      if (!this.orderCustomBusiness.place().willFillOrderDeliveryAmountV2(orderInfoList, orderDetailList, orderDeliveryList, resultVO)) {
         return this.orderCustomBusiness.place().didFillOrderDeliveryAmountV2(orderInfoList, orderDetailList, orderDeliveryList, resultVO);
      } else {
         try {
            Iterator var5 = orderInfoList.iterator();

            while(var5.hasNext()) {
               OrderInfo orderInfo = (OrderInfo)var5.next();
               if (OrderTypeEnum.isShopCategory(orderInfo.getOrderType()) && orderInfo.getCanteenId() != null
                       && DeliveryTypeEnum.MERCHANT.getKey().equals(orderInfo.getDeliveryType())) {
                  SupermarketInfo supermarketInfo = this.supermarketApi.getSupermarketInfoById(orderInfo.getCanteenId());
                  if (supermarketInfo != null && supermarketInfo.getDeliveryCost() != null) {
                     orderInfo.setDeliveryAmount(BigDecimal.valueOf((long)supermarketInfo.getDeliveryCost()));
                  }
               } else if (OrderTypeEnum.isCurrMealType(orderInfo.getOrderType()) || OrderTypeEnum.isReserveMealType(orderInfo.getOrderType())) {
                  AllocCanteenDeliveryModel deliveryModel = this.orderModuleClient.metadataQueryDeliveryConfig(OrderConfigQueryParam.of(orderInfo.getCanteenId(), orderInfo.getStallId()));
                  AllocCanteenDeliveryDTO deliveryDTO = deliveryModel.deliveryDetailByType(orderInfo.getDeliveryType());
                  if (deliveryDTO != null) {
                     orderInfo.setDeliveryAmount(deliveryDTO.calcDeliveryAmountForOrder());
                     orderInfo.setPackingAmount(deliveryDTO.calcPackingAmountForOrder());
                  }

                  if (DeliveryTypeEnum.isNeedDeliveryType(orderInfo.getDeliveryType())) {
                     Integer minAmountForDelivery = deliveryModel.getWholeMinDeliveryFee(orderInfo.getMealtimeType());
                     if (minAmountForDelivery > 0) {
                        List<OrderDetail> targetOrderDetails = orderDetailList.stream().filter((s) -> {
                           return s.getOrderId().equals(orderInfo.getOrderId());
                        }).collect(Collectors.toList());
                        this.calcOrderAndDetailTotalAmount(orderInfo, targetOrderDetails);
                        if (orderInfo.getPayableAmount().compareTo(BigDecimal.valueOf((long)minAmountForDelivery)) < 0) {
                           resultVO.saveLessAmountInfo(orderInfo.getOrderId(), BigDecimal.valueOf((long)minAmountForDelivery).subtract(orderInfo.getPayableAmount()));
                        }
                     }
                  }
               }
            }
         } catch (Exception var11) {
            log.error("订单计算配送费异常", var11);
            return OrderDeliveryResultVO.failedInstance(var11);
         }

         return this.orderCustomBusiness.place().didFillOrderDeliveryAmountV2(orderInfoList, orderDetailList, orderDeliveryList, resultVO);
      }
   }
//
//   public List<OrderAmountDetail> calcOrderRealAmount(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, List<OrderAmountChange> orderAmountChangeList, BigDecimal payAmount, List<TradeChannelVO> channelDetailList) {
//      List<OrderAmountDetail> orderAmountDetailList = CollUtil.newArrayList(new OrderAmountDetail[0]);
//      if (!this.orderCustomBusiness.place().willCalcOrderRealAmount(orderInfoList, orderDetailList, payAmount, channelDetailList, orderAmountDetailList)) {
//         this.orderCustomBusiness.place().didCalcOrderRealAmount(orderInfoList, orderDetailList, payAmount, channelDetailList, orderAmountDetailList);
//         return orderAmountDetailList;
//      } else {
//         LeOrderUtil.calcOrderAmount(orderInfoList, payAmount, OrderInfo::setRealAmount);
//         this.fillAccChannelPayDetailIfNecessary(channelDetailList);
//         Iterator var7 = channelDetailList.iterator();
//
//         while(var7.hasNext()) {
//            TradeChannelVO tradeChannelVO = (TradeChannelVO)var7.next();
//            if (PayStateEnum.isPaidState(tradeChannelVO.getTradeState())) {
//               LeOrderUtil.calcOrderAmount(orderInfoList, tradeChannelVO.getAmount(), (orderInfox, amount) -> {
//                  orderAmountDetailList.add(tradeChannelVO.convertToOrderAmountDetail(orderInfox.getOrderId(), orderInfox.getOrderDate(), (Long)null, amount, OrderAmountDetailTypeEnum.PAY));
//                  if (PayChannelEnum.ACC.getKey().equals(tradeChannelVO.getPayChannel())) {
//                     orderInfox.setAccPayAmount(amount);
//                  } else if (PayChannelEnum.COUPON.getKey().equals(tradeChannelVO.getPayChannel())) {
//                     orderInfox.setCouponAmount(amount);
//                  } else {
//                     orderInfox.setOutPayAmount(amount);
//                  }
//
//               });
//               tradeChannelVO.shareAccPayResult(orderAmountDetailList);
//               if (PayChannelEnum.COUPON.getKey().equals(tradeChannelVO.getPayChannel())) {
//                  String couponId = tradeChannelVO.getParam() != null ? tradeChannelVO.getParam().path("couponId").asText() : "";
//                  if (CharSequenceUtil.isNotEmpty(couponId)) {
//                     orderInfoList.forEach((s) -> {
//                        s.setCouponId(couponId);
//                     });
//                  }
//               }
//            }
//         }
//
//         var7 = orderInfoList.iterator();
//
//         while(var7.hasNext()) {
//            OrderInfo orderInfo = (OrderInfo)var7.next();
//            BigDecimal detailRealAmount = orderInfo.getRealAmount();
//            if (CollUtil.isNotEmpty(orderAmountChangeList)) {
//               BigDecimal additionalFee = (BigDecimal)orderAmountChangeList.stream().filter((s) -> {
//                  return s.getOrderId().equals(orderInfo.getOrderId()) && ChangeDetailTypeEnum.ifAdditionalFee(s.getChangeDetailType());
//               }).map((s) -> {
//                  return NumberUtil.null2Zero(s.getChangeAmount()).abs();
//               }).reduce(BigDecimal.ZERO, BigDecimal::add);
//               detailRealAmount = detailRealAmount.subtract(additionalFee);
//            }
//
//            if (detailRealAmount.compareTo(BigDecimal.ZERO) < 0) {
//               detailRealAmount = BigDecimal.ZERO;
//            }
//
//            List<OrderDetail> detailList = (List)orderDetailList.stream().filter((s) -> {
//               return s.getOrderId().equals(orderInfo.getOrderId());
//            }).collect(Collectors.toList());
//            LeNumUtil.calcShareAmount(detailList, detailRealAmount, OrderDetail::getCalcTotalAmount, OrderDetail::setRealAmount);
//         }
//
//         this.orderCustomBusiness.place().didCalcOrderRealAmount(orderInfoList, orderDetailList, payAmount, channelDetailList, orderAmountDetailList);
//         return orderAmountDetailList;
//      }
//   }
//
//   public void updateOrderFieldAfterPay(OrderInfo orderInfo, OrderDidPayInfoDTO didPayInfoDTO) {
//      orderInfo.setPayState(didPayInfoDTO.getPayState());
//      orderInfo.setPayTime(didPayInfoDTO.getPayTime() != null ? didPayInfoDTO.getPayTime() : LocalDateTime.now());
//      orderInfo.setPayType(didPayInfoDTO.getPayType());
//      orderInfo.setPayChannel(didPayInfoDTO.getPayChannel());
//      this.orderDishesAndroidBusiness.initOrderMealCode(orderInfo);
//      boolean callFlag = this.ifUseCall(orderInfo);
//      OrderStateEnum orderStateEnum = OrderStateEnum.PLACE;
//      DishesStateEnum dishesStateEnum = DishesStateEnum.UN_MAKE;
//      if (OrderTypeEnum.isAndroidType(orderInfo.getOrderType())) {
//         if (this.ifMealtimeAfterCurrent(orderInfo)) {
//            log.info("[当餐点餐下单] 当前餐次之后的订单");
//         } else if (callFlag) {
//            dishesStateEnum = DishesStateEnum.MAKING;
//         } else if (DeliveryTypeEnum.isNeedDeliveryType(orderInfo.getDeliveryType())) {
//            dishesStateEnum = DishesStateEnum.WAIT_DELIVERY;
//         } else {
//            dishesStateEnum = DishesStateEnum.ALREADY_TAKE;
//            orderStateEnum = OrderStateEnum.FINISH;
//         }
//      } else if (OrderTypeEnum.isCurrMealType(orderInfo.getOrderType())) {
//         if (callFlag) {
//            dishesStateEnum = DishesStateEnum.MAKING;
//         } else if (DeliveryTypeEnum.isNeedDeliveryType(orderInfo.getDeliveryType())) {
//            dishesStateEnum = DishesStateEnum.WAIT_DELIVERY;
//         } else {
//            dishesStateEnum = DishesStateEnum.WAIT_TAKE;
//         }
//      } else if (OrderTypeEnum.isShopType(orderInfo.getOrderType())) {
//         if (SourceTypeEnum.getAppTypeList().contains(orderInfo.getSourceType())) {
//            dishesStateEnum = DishesStateEnum.WAIT_TAKE;
//         } else {
//            orderStateEnum = OrderStateEnum.FINISH;
//            dishesStateEnum = DishesStateEnum.ALREADY_TAKE;
//         }
//      } else if (OrderTypeEnum.isBuffetType(orderInfo.getOrderType()) || OrderTypeEnum.isRoomCategory(orderInfo.getOrderType()) || OrderTypeEnum.isMobileScanCategory(orderInfo.getOrderType())) {
//         orderStateEnum = OrderStateEnum.FINISH;
//         dishesStateEnum = DishesStateEnum.ALREADY_TAKE;
//      }
//
//      if (!OrderStateEnum.isFinishState(orderInfo.getOrderState())) {
//         orderInfo.setOrderState(orderStateEnum.getKey());
//         orderInfo.setDishesState(dishesStateEnum.getKey());
//      }
//
//      this.orderCustomBusiness.place().didUpdateOrderFieldAfterPay(orderInfo, didPayInfoDTO);
//   }
//
//   public boolean ifUseCall(OrderInfo orderInfo) {
//      if (LocalDate.now().isAfter(orderInfo.getOrderDate())) {
//         log.warn("[叫号] 今天之前的订单不叫号");
//      } else if ((OrderTypeEnum.isAndroidType(orderInfo.getOrderType()) || OrderTypeEnum.isCurrMealType(orderInfo.getOrderType())) && LeNumUtil.isValidId(orderInfo.getStallId())) {
//         AllocStall allocStall = this.allocStallApi.getAllocStall(orderInfo.getStallId());
//         if (allocStall != null && LeConstants.COMMON_YES.equals(allocStall.getIfUseCallNum())) {
//            log.info("[当餐点餐下单] 开启叫号");
//            return true;
//         }
//      }
//
//      return false;
//   }

   protected void calcOrderAndDetailTotalAmount(OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
      boolean usePrefPrice = !OrderTypeEnum.isShopCategory(orderInfo.getOrderType()) || this.supermarketApi.ifSupermarketMember(orderInfo.getCustId(), orderInfo.getCanteenId());
      Iterator var4 = orderDetailList.iterator();

      while(var4.hasNext()) {
         OrderDetail orderDetail = (OrderDetail)var4.next();
         this.orderDetailService.orderDetailHandler(orderDetail, usePrefPrice);
      }

      orderInfo.setPayableAmount((BigDecimal)orderDetailList.stream().map(OrderDetail::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
   }
//
//   protected void fillAccChannelPayDetailIfNecessary(List<TradeChannelVO> channelDetailList) {
//      List<Long> lacksAccPayDetailChannelIds = (List)channelDetailList.stream().filter(TradeChannelVO::ifLacksAccPayDetail).map(TradeChannelVO::getTradeChannelId).collect(Collectors.toList());
//      if (CollUtil.isNotEmpty(lacksAccPayDetailChannelIds)) {
//         Map<Long, AccTradeOrderBalanceVO> accPayDetailMap = this.accTradeApi.listOrderAccPayDetail(lacksAccPayDetailChannelIds);
//         channelDetailList.stream().filter(TradeChannelVO::ifLacksAccPayDetail).forEach((s) -> {
//            s.setAccPayResultVO(AccPayResultVO.of((AccTradeOrderBalanceVO)accPayDetailMap.get(s.getTradeChannelId())));
//         });
//      }
//
//   }
//
//   protected OrderAmountChange packageOrderAmountChange(Long orderId, LocalDate orderDate, BigDecimal changeAmount, ChangeDetailTypeEnum changeDetailType) {
//      return this.packageOrderAmountChange(orderId, orderDate, changeAmount, changeDetailType, (String)null);
//   }
//
//   protected OrderAmountChange packageOrderAmountChange(Long orderId, LocalDate orderDate, BigDecimal changeAmount, ChangeDetailTypeEnum changeDetailType, String remark) {
//      return OrderAmountChange.newInstance(orderId, orderDate, changeDetailType, changeAmount, remark);
//   }

   protected RulePriceDTO packageRulePriceDTO(List<OrderInfo> orderInfoList, List<OrderDetail> orderDetailList, boolean isTrail) {
      RulePriceDTO rulePriceDTO = new RulePriceDTO();
      rulePriceDTO.setTryFlag(isTrail ? LeConstants.COMMON_YES : LeConstants.COMMON_NO);
      rulePriceDTO.setVerifyFlag(LeConstants.COMMON_NO);
      List<RulePriceOrderDTO> ruleOrderList = (List<RulePriceOrderDTO>)orderInfoList.stream().map((orderInfo) -> {
         RulePriceOrderDTO orderDTO = (new RulePriceOrderDTO()).setOrderId(orderInfo.getOrderId()).setMacOrderId(orderInfo.getMacOrderId()).setCustId(LeNumUtil.isValidId(orderInfo.getCustId()) ? orderInfo.getCustId() : LeConstants.DATA_DEFAULT_LONG).setOrderType(orderInfo.getOrderType()).setDeviceSn(orderInfo.getMachineSn()).setMealtimeType(orderInfo.getMealtimeType()).setOrderDate(orderInfo.getOrderDate()).setOrderTime(orderInfo.getOrderTime()).setCanteenId(orderInfo.getCanteenId()).setStallId(orderInfo.getStallId()).setPayableAmount(orderInfo.calcNeedPayAmount()).setIfOnline(orderInfo.getIfOnline());
         List<RulePriceOrderDetailDTO> detailDtoList = (List<RulePriceOrderDetailDTO>)orderDetailList.stream().filter((s) -> {
            return s.getOrderId().equals(orderDTO.getOrderId());
         }).map((s) -> {
            return (new RulePriceOrderDetailDTO()).setDetailId(s.getDetailId()).setGoodsDishesId(s.getGoodsDishesId()).setPrice(s.getPrice()).setQuantity(s.getQuantity()).setCalcTotalAmount(s.getCalcTotalAmount());
         }).collect(Collectors.toList());
         orderDTO.setDetails(detailDtoList);
         return orderDTO;
      }).collect(Collectors.toList());
      rulePriceDTO.setOrders(ruleOrderList);
      rulePriceDTO.setCustId(LeNumUtil.isValidId(((OrderInfo)orderInfoList.get(0)).getCustId()) ? ((OrderInfo)orderInfoList.get(0)).getCustId() : LeConstants.DATA_DEFAULT_LONG);
      rulePriceDTO.setPayChannel(((OrderInfo)orderInfoList.get(0)).getPayChannel());
      return rulePriceDTO;
   }
//
//   protected boolean ifMealtimeAfterCurrent(OrderInfo orderInfo) {
//      if (orderInfo.getOrderDate().isBefore(LocalDate.now())) {
//         return false;
//      } else if (orderInfo.getOrderDate().isAfter(LocalDate.now())) {
//         return true;
//      } else {
//         AllocMealtimeModel currentMealtime = this.orderModuleClient.mealtimeQuery(MealtimeQueryParam.ofAssignTime(orderInfo.getOrderTime().toLocalTime(), orderInfo.getCanteenId(), orderInfo.getStallId()));
//         return currentMealtime != null && currentMealtime.getMealtimeType().compareTo(orderInfo.getMealtimeType()) < 0;
//      }
//   }
}
