package com.prolog.eis.service.out.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.prolog.eis.api.StrategyApi;
import com.prolog.eis.constants.base.AbcTypeConstant;
import com.prolog.eis.constants.base.ContainerTaskStatusConstants;
import com.prolog.eis.constants.base.OrderStatusConstants;
import com.prolog.eis.constants.redisKey.RedisKey;
import com.prolog.eis.constants.sys.SysParamConstants;
import com.prolog.eis.constants.wms.WmsConstants;
import com.prolog.eis.dao.out.OrderLogMapper;
import com.prolog.eis.dto.item.ItemSyncVO;
import com.prolog.eis.dto.outbound.HitNotificationDTO;
import com.prolog.eis.dto.outbound.HitNotificationReqDTO;
import com.prolog.eis.dto.outbound.HitNotificationResDTO;
import com.prolog.eis.dto.strategy.*;
import com.prolog.eis.model.container.ContainerTask;
import com.prolog.eis.model.out.BizOutboundTaskDetailDismantle;
import com.prolog.eis.model.out.ContainerTaskDismantle;
import com.prolog.eis.model.outbound.BizOutboundTask;
import com.prolog.eis.model.outbound.BizOutboundTaskDetail;
import com.prolog.eis.model.outbound.OrderLog;
import com.prolog.eis.model.outbound.PrintTask;
import com.prolog.eis.model.shelves.GridInfo;
import com.prolog.eis.service.feign.FeignGoodsService;
import com.prolog.eis.service.logic.LogicService;
import com.prolog.eis.service.out.*;
import com.prolog.eis.service.shelves.GridInfoService;
import com.prolog.eis.service.shelves.ItemService;
import com.prolog.eis.service.wms.WmsHitNotificationService;
import com.prolog.eis.utils.GoodsPropertyUtils;
import com.prolog.eis.utils.PalletDismantlePosStrategyConfig;
import com.prolog.framework.beans.BeanUtils;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.prolog.eis.constants.base.BaseBillTypeConstants.OUTBOUND_TYPE;
import static com.prolog.eis.constants.base.BaseBillTypeConstants.REPLENISH_TYPE;

/**
 * @author zmr
 * @description: 出库任务表-服务实现类
 * @date 2023-07-06 11:36
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class TimeTaskServiceImpl implements TimeTaskService {

    private final BizOutboundTaskService bizOutboundTaskService;
    private final BizOutboundTaskDetailService bizOutboundTaskDetailService;
    private final BasicStoreStrategyService storeStrategyService;
    private final BizOutboundTaskDetailDismantleService bizOutboundTaskDetailDismantleService;
    private final ContainerTaskService containerTaskService;
    private final ContainerTaskDismantleService containerTaskDismantleService;
    private final ContainerInfoService containerInfoService;
    private final PrintTaskService printTaskService;
    private final LogicService logicService;
    private final GridInfoService gridInfoService;
    private final ItemService itemService;
    private final OrderLogMapper orderLogMapper;
    private final WmsHitNotificationService wmsHitNotificationService;
    private final RedisTemplate redisTemplate;
    private final FeignGoodsService feignGoodsService;

    /**
     * 绑定格口调度
     * 要求：格口分组绑定的订单均衡、订单未拣选品批整体重复度最高
     */
    @Override
    public void bindGirl() throws Exception {
        //判断是否要开启绑定格口的调度
        Boolean isBind = checkBindConditions();
        if (!isBind) {
            return;
        }
        while (true) {
            log.info("开始绑定格口");
            boolean isBindSuccess = logicService.bindGirl();
            if (!isBindSuccess) {
                return;
            }

        }
    }

    @Override
    public void checkStock() throws Exception {
        //查所有订单
        List<OrderDto> orderTempList = getOutboundTaskByWarehouseArea(WmsConstants.AGVL);
        if (CollectionUtils.isEmpty(orderTempList)) {
            System.out.println("检验库存，无可校验的订单库存");
            return;
        }
        //查所有运行中的任务
        List<ContainerTask> taskTempList = containerTaskService.findByMap(MapUtils.put("wmsLocationCode", WmsConstants.AGVL).getMap());
        //查所有可用库存
        List<ContainerInfoDto> stockTempList = containerInfoService.getContainerInfoDto(WmsConstants.AGVL);
        //根据库区校验订单库存
        try {
            //查出当前库区所有整托出库任务的子托盘号集合
            List<String> full = taskTempList.stream().filter(s -> s.getContainerType() == ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE || s.getContainerType() == ContainerTaskStatusConstants.MORE_FULL_TRAY_TYPE).map(ContainerTask::getContainerSubNo).distinct().collect(Collectors.toList());
            //过滤正在任务中的整托托盘
            stockTempList = stockTempList.stream().filter(containerInfoDto -> !full.contains(containerInfoDto.getContainerSubNo())).collect(Collectors.toList());
            //根据子托盘集合去除拼托的库存
            Map<String, BigDecimal> collect = taskTempList.stream().collect(Collectors.toMap(ContainerTask::getContainerSubNo, ContainerTask::getQty, BigDecimal::add));
            for (ContainerInfoDto containerInfoDto : stockTempList) {
                BigDecimal qty = collect.get(containerInfoDto.getContainerSubNo());
                if (Objects.nonNull(qty)) {
                    containerInfoDto.setQty(containerInfoDto.getQty().subtract(qty));
                }
            }
            Map<String, BigDecimal> storeMap = stockTempList.stream().collect(Collectors.toMap(o -> o.getBusinessProperty(), ContainerInfoDto::getQty, (k1, k2) -> k1.add(k2)));

            for (OrderDto orderDto : orderTempList) {
                HashMap<Integer, BigDecimal> map = new HashMap<>();
                List<OrderDetailDto> orderDetailDtoList = orderDto.getOrderDetailDtoList();
                for (OrderDetailDto detailDto : orderDetailDtoList) {
                    if (ObjectUtil.isNotEmpty(detailDto.getContainerNo())) {
                        ContainerInfoDto containerInfoDto = stockTempList.stream().filter(x -> x.getContainerSubNo().equals(detailDto.getContainerNo())).findFirst().orElse(null);
                        boolean present = Optional.ofNullable(containerInfoDto).isPresent();
                        if (!present) {
                            map.put(detailDto.getOrderDetailId(), BigDecimal.ZERO);
                            log.warn("订单明细id【{}】所需库存不足，库内不存在此托盘【{}】", detailDto.getOrderDetailId(), detailDto.getContainerNo());
                        }
                        continue;
                    }
                    BigDecimal storeQty = storeMap.get(detailDto.getBusinessProperty());
                    if (Objects.isNull(storeQty)) {
                        map.put(detailDto.getOrderDetailId(), detailDto.getPlanNum());
                        log.warn("订单明细id【{}】所需库存【{}】不足，可用库存为0", detailDto.getOrderDetailId(), detailDto.getPlanNum());
                        continue;
                    }
                    if (storeQty.compareTo(detailDto.getPlanNum()) < 0) {
                        map.put(detailDto.getOrderDetailId(), detailDto.getPlanNum().subtract(storeQty));
                        //storeMap.remove(detailDto.getBusinessProperty());
                        log.warn("订单明细id【{}】所需库存【{}】不足，可用库存为{}", detailDto.getOrderDetailId(), detailDto.getPlanNum(), storeQty);
                        continue;
                    }
                    if (storeQty.compareTo(detailDto.getPlanNum()) == 0) {
                        storeMap.remove(detailDto.getBusinessProperty());
                    } else {
                        storeMap.put(detailDto.getBusinessProperty(), storeQty.subtract(detailDto.getPlanNum()));
                    }
                }
                BizOutboundTask outboundTask = bizOutboundTaskService.findById(orderDto.getOrderId());
                if (map.size() > 0) {
                    outboundTask.setErrorMsg("库存不足");
                } else {
                    outboundTask.setErrorMsg(null);
                    outboundTask.setCheckStore(1);

                    Criteria criteria = new Criteria(BizOutboundTaskDetail.class);
                    criteria.setRestriction(Restrictions.eq("outboundId", outboundTask.getId()).and(Restrictions.eq("checkStore", 0)));
                    bizOutboundTaskDetailService.updateMapByCriteria(MapUtils.put("checkStore", 1).getMap(), criteria);

                    orderLogMapper.save(OrderLog.builder().orderId(orderDto.getOrderId().toString()).orderNo(outboundTask.getBillNo()).type("库存校验").remark("库存校验成功").createTime(new Date()).build());
                }
                outboundTask.setUpdateTime(LocalDateTime.now());
                bizOutboundTaskService.update(outboundTask);
            }
        } catch (Exception e) {
            log.warn(String.format("校验库存：【%s】库区校验库存失败，原因为：【%s】", WmsConstants.AGVL, e.getMessage()));
        }

    }

    public List<OrderDto> getOutboundTaskByWarehouseArea(String warehouseArea) throws Exception {
        List<OrderDto> orderDtoList = bizOutboundTaskService.getOutboundTaskByArea(warehouseArea);
        if (orderDtoList.isEmpty()) {
            return null;
        }
        List<OrderDetailDto> orderDetailDtoList = bizOutboundTaskDetailService.findDetailList(warehouseArea);
        if (orderDetailDtoList.isEmpty()) {
            return null;
        }
        Map<Integer, List<OrderDetailDto>> collect = orderDetailDtoList.stream().collect(Collectors.groupingBy(OrderDetailDto::getOrderId));

        Iterator<OrderDto> iterator = orderDtoList.iterator();
        while (iterator.hasNext()) {
            OrderDto orderDto = iterator.next();
            if (!collect.containsKey(orderDto.getOrderId())) {
                iterator.remove();
            }
            orderDto.setOrderDetailDtoList(collect.get(orderDto.getOrderId()));
        }
        return orderDtoList;
    }


    private Boolean checkBindConditions() throws ParseException {
        //格口空闲系数(百分比)
        String girlFreeSize = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.GIRL_FREE_SIZE));

        //剩余商品拣货数量（百分比）
        String residueItemSize = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.RESIDUE_ITEM_SIZE));
        //触发订单绑定格口间隔时间（分钟）
        String girlBindGapTime = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.GIRL_BIND_GAP_TIME));
        //上次订单绑定格口时间
        String girlBindTime = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.GIRL_BIND_TIME));
        //1.距离上次触发订单格口绑定超过1小时
        boolean isTimeOut = false;
        if (!StringUtils.isEmpty(girlBindTime)) {
            isTimeOut = (System.currentTimeMillis() - Long.parseLong(girlBindTime)) > (Integer.parseInt(girlBindGapTime) * 60 * 1000);
        }

        //2.格口空闲系数(百分比)（已绑订单格口数 < 总开发格口数X0.4(可配置)）
        boolean isBindGK = false;


        List<GridInfo> gridInfoList = gridInfoService.findByMap(MapUtils.put("isLock", 0).getMap());
        long useOrderCount = gridInfoList.stream().filter(o -> o.getOrderId() != null).count();
        long temp = new BigDecimal(gridInfoList.size() + "").multiply(new BigDecimal(girlFreeSize)).setScale(0, BigDecimal.ROUND_UP).longValue();
        if (useOrderCount < temp) {
            isBindGK = true;
        }

        //3.已出订单的所有商品  剩余商品拣货个数（百分比）（剩余Sku拣货数量低于于30%(可配置)）
        boolean isStartGkByPick = false;
        List<OrderDetailDto> detailList = bizOutboundTaskDetailService.findOutDetailList(String.valueOf(OUTBOUND_TYPE), WmsConstants.AGVL, WmsConstants.bind + "");
        long notCount = detailList.stream().filter(o -> o.getStatus() > 10 && o.getStatus() < 20).map(o -> GoodsPropertyUtils.getGoodsProperty(o.getItemId(), o.getLotId())).count();
        long totalCount = detailList.stream().filter(o -> o.getStatus() > 10).map(o -> GoodsPropertyUtils.getGoodsProperty(o.getItemId(), o.getLotId())).count();
        if (totalCount > 0) {
            BigDecimal configVal = new BigDecimal(residueItemSize);
            BigDecimal currVal = new BigDecimal(notCount + "").divide(new BigDecimal(totalCount + "")).setScale(2);
            if (currVal.compareTo(configVal) < 0) {
                isStartGkByPick = true;
            }
        }
        if (isBindGK || isTimeOut || isStartGkByPick) {
            log.info("是否触发格口空闲系数{}，格口空闲系数(百分比)（已绑订单格口数{} < 总开发格口数{}X配置系数{}）", isBindGK, useOrderCount, gridInfoList.size(), girlFreeSize);
            log.info("是否触发格口绑定时间{},当前时间{},上次触发时间{},间隔时间{}分钟,系统配置时间{}", isTimeOut, System.currentTimeMillis(), girlBindTime, System.currentTimeMillis() - Long.parseLong(girlBindTime), Integer.parseInt(girlBindGapTime) * 60 * 1000);
            log.info("是否触发剩余商品拣货个数（百分比）{},剩余商品拣货数量{}/已绑定总数量{}，系统配置{}", isStartGkByPick, notCount, totalCount, residueItemSize);
            return true;
        }
        return false;
    }

    /**
     * 找托盘调度（优先索取已在任务中的托盘做追加，保证出最少的托盘）
     * 1.根据库区查询出库订单
     * 2.组装出库订单集合
     * 3.查询库存集合（扣减已定位的托盘）
     * 4，遍历出库表数据（循环直至消费掉所有出库订单详情数量）
     * 5.优先找已定位的托盘做追加
     * 6.找到合适托盘保存出库拆零详情表（区分零发整和零散）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void findPallet(String billType) throws Exception {
        Date t1 = new Date();
        InitDto initDto = getInitDto(billType, WmsConstants.AGVL);
        Date t2 = new Date();
        if (Objects.isNull(initDto)) {
            return;
        }
        List<ContainerInfoDto> containerInfoDtoList = initDto.getContainerInfoDtoList();
        List<OrderDto> orderList = initDto.getOrderList();
        Map<Integer, String> strategyMap = initDto.getStrategyMap();
        orderList.sort(Comparator.comparing(OrderDto::getPriority, Comparator.nullsFirst(Integer::compare)).reversed().thenComparing(OrderDto::getWaveNo).thenComparing(OrderDto::getCreateTime));
        Map<String, BigDecimal> storeMap = initDto.getContainerInfoDtoList().stream().collect(Collectors.toMap(ContainerInfoDto::getBusinessProperty, ContainerInfoDto::getQty, (k1, k2) -> k1.add(k2)));
        Date t3 = new Date();
        List<OrderDto> orderDtoList = new ArrayList<>();
        for (OrderDto orderDto : orderList) {
            if (computeStore(orderDto, storeMap)) {
                orderDtoList.add(orderDto);
            }
        }
        if (orderDtoList.isEmpty()) {
            throw new Exception("所有订单库存不足");
        }
        Date t4 = new Date();
        List<ContainerTaskDto> containerTaskDtoList = getGroupList(orderDtoList, containerInfoDtoList, strategyMap);
        Date t5 = new Date();
        handleOrder(containerTaskDtoList, null, null);
        Date t6 = new Date();
        createContainerTaskBatch(containerTaskDtoList, orderDtoList);
        Date t7 = new Date();
        log.info(String.format("库存预占耗时：%s,%s,%s,%s,%s,%s", t2.getTime() - t1.getTime(), t3.getTime() - t2.getTime(), t4.getTime() - t3.getTime(), t5.getTime() - t4.getTime(), t6.getTime() - t5.getTime(), t7.getTime() - t6.getTime()));
    }


    private InitDto getInitDto(String billType, String warehouseArea) throws Exception {

        InitDto initDto = new InitDto();
        int billTypeInt = Integer.parseInt(billType);
        List<OrderDto> orderDtoList = null;
        switch (billTypeInt) {
            case REPLENISH_TYPE:
                orderDtoList = logicService.getOutboundTask(billType, warehouseArea);
                if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderDtoList)) {
                    log.warn("库区[{}],billType[{}]无可用订单", warehouseArea, billType);
                    return null;
                }
                break;
            case OUTBOUND_TYPE:
                orderDtoList = logicService.getOutboundTaskLS(billType, warehouseArea);
                if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderDtoList)) {
                    log.warn("库区[{}],billType[{}]无可用订单", warehouseArea, billType);
                    return null;
                }
                break;
            default:
                throw new Exception("不支持的billType");
        }
        initDto.setOrderList(orderDtoList);
        //获取库存
        List<ContainerInfoDto> containerInfoDtoList = getPartStrategyContainerInfo(warehouseArea);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(containerInfoDtoList)) {
            log.warn("billType[{}]初始化无可用库存", billType);
            return null;
        }

        storeStrategyService.getContainerLocation(containerInfoDtoList, warehouseArea);
        storeStrategyService.getAreaTask(containerInfoDtoList);
        initDto.setContainerInfoDtoList(containerInfoDtoList);

        //获取排序策略
        initDto.setStrategyMap(PalletDismantlePosStrategyConfig.getStrategyConfig());

        return initDto;
    }


    public void createContainerTaskBatch(List<ContainerTaskDto> containerTaskDtoList, List<OrderDto> orderDtoList) throws Exception {
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(containerTaskDtoList)) {
            throw new Exception("容器任务集合为空");
        }
        List<ContainerTask> containerTaskList = new ArrayList<>();
        for (ContainerTaskDto containerTaskDto : containerTaskDtoList) {
            //检验托盘是否已在运行中（同类型同波次同产成品才可保存）
            ContainerTask containerTask = new ContainerTask();
            containerTask.setContainerNo(containerTaskDto.getContainerNo());
            containerTask.setContainerSubNo(containerTaskDto.getContainerSubNo());
            containerTask.setContainerType(containerTaskDto.getContainerType());
            containerTask.setOutboundId(containerTaskDto.getOrderId());
            containerTask.setWaveNo(containerTaskDto.getWaveNo());
            containerTask.setCompanyId(containerTaskDto.getCompanyId());
            containerTask.setOutboundDetailId(containerTaskDto.getOrderDetailId());
            containerTask.setItemId(containerTaskDto.getItemId());
            containerTask.setLotId(containerTaskDto.getLotId());
            containerTask.setOwnerId(containerTaskDto.getOwnerId());
            containerTask.setPackId(containerTaskDto.getPackId());
            containerTask.setPickOrderId(containerTaskDto.getPickOrderId());
            containerTask.setTaskType(containerTaskDto.getTaskType());
            containerTask.setWarehouseArea(containerTaskDto.getWmsLocationCode());
            containerTask.setWmsLocationCode(containerTaskDto.getWmsLocationCode());
            containerTask.setStatus(0);
            containerTask.setQty(containerTaskDto.getBindingNum());
            containerTask.setCreateTime(LocalDateTime.now());
            containerTask.setPriorty(containerTaskDto.getPriority());
            containerTaskList.add(containerTask);
        }
        containerTaskService.saveBatch(containerTaskList);

        //保存拆零或零发整数据
        checkFullorDismantle(containerTaskList);
    }

    /**
     * @param containerTaskList
     * @throws Exception
     */
    private void checkFullorDismantle(List<ContainerTask> containerTaskList) throws Exception {
        String fullSwitch = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.FULL_SWITCH));
//        String fullSwitch = "1";
        List<ContainerTaskDismantle> containerTaskDismantleList = new ArrayList<>();
        if (fullSwitch.equals(SysParamConstants.FULL_SWITCH_OFF)) {
            //关闭零发整
            for (ContainerTask containerTask : containerTaskList) {
                setDismantleData(containerTask, containerTaskDismantleList, 2, containerTask.getQty());
            }
        } else {
            //开启零发整
            Map<String, BigDecimal> itemMap = new HashMap<>();
            for (ContainerTask containerTask : containerTaskList) {
                itemMap.put(containerTask.getItemId(), BigDecimal.ZERO);
            }
            List<ItemSyncVO> itemSyncVOList = itemService.queryItemMst(itemMap.keySet().stream().collect(Collectors.toList()));
            itemSyncVOList.forEach(itemSyncVO -> {
                if (itemMap.containsKey(itemSyncVO.getItemId())) {
                    itemMap.put(itemSyncVO.getItemId(), itemSyncVO.getUomList().get(0).getConversionRate());
                }
            });
            for (ContainerTask containerTask : containerTaskList) {
                if (itemMap.get(containerTask.getItemId()) != null) {
                    BigDecimal packSize = itemMap.get(containerTask.getItemId());
                    if (packSize.compareTo(containerTask.getQty()) == 0) {
                        setDismantleData(containerTask, containerTaskDismantleList, 1, containerTask.getQty());
                    } else if (packSize.compareTo(containerTask.getQty()) > 0) {
                        setDismantleData(containerTask, containerTaskDismantleList, 2, containerTask.getQty());
                    } else {
                        if (packSize.compareTo(BigDecimal.ZERO) == 0) {
                            throw new PrologException(String.format("商品id:%s包装含量不能为空或0", containerTask.getItemId()));
                        }
                        BigDecimal[] results = containerTask.getQty().divideAndRemainder(packSize);
                        for (int i = 0; i < results.length; i++) {
                            if (i == 0) {
                                results[i] = results[i].multiply(packSize);
                            }
                            if (results[i].compareTo(BigDecimal.ZERO) <= 0) {
                                continue;
                            }
                            setDismantleData(containerTask, containerTaskDismantleList, i == 0 ? 1 : 2, results[i]);
                        }
                    }
                }
            }
        }

        containerTaskDismantleService.saveBatch(containerTaskDismantleList);

        Map<String, BigDecimal> decimalMapGroup = containerTaskDismantleList.stream().collect(Collectors.groupingBy(item -> item.getOutboundDetailId() + "_" + item.getType(), Collectors.mapping(ContainerTaskDismantle::getPlanQty, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
        List<BizOutboundTaskDetailDismantle> outDismantleList = new ArrayList<>();
        List<ContainerTaskDismantle> tempList = new ArrayList<>();
        for (Map.Entry<String, BigDecimal> entry : decimalMapGroup.entrySet()) {
            ContainerTaskDismantle containerTaskDismantle = containerTaskDismantleList.stream().filter(item -> entry.getKey().equals(item.getOutboundDetailId() + "_" + item.getType())).findFirst().orElse(null);
            BizOutboundTaskDetailDismantle bizOutboundTaskDetailDismantle = new BizOutboundTaskDetailDismantle();
            //保存拆零详情数据
            BeanUtils.copyProperties(containerTaskDismantle, bizOutboundTaskDetailDismantle);
            bizOutboundTaskDetailDismantle.setPlanQty(entry.getValue());
            bizOutboundTaskDetailDismantle.setLackQty(BigDecimal.ZERO);
            bizOutboundTaskDetailDismantle.setSupplyQty(BigDecimal.ZERO);
            bizOutboundTaskDetailDismantle.setOfferQty(BigDecimal.ZERO);
            bizOutboundTaskDetailDismantle.setOfferShowQty(BigDecimal.ZERO);
            bizOutboundTaskDetailDismantle.setLackState(-1);
            bizOutboundTaskDetailDismantle.setHandOfferQty(BigDecimal.ZERO);
            outDismantleList.add(bizOutboundTaskDetailDismantle);
            tempList.add(containerTaskDismantle);
        }
        bizOutboundTaskDetailDismantleService.saveBatch(outDismantleList);

        //查询订单是否全为零发整
        List<Integer> orderIdList = outDismantleList.stream().map(BizOutboundTaskDetailDismantle::getOutboundId).distinct().collect(Collectors.toList());
        Criteria criteria = new Criteria(BizOutboundTaskDetailDismantle.class);
        criteria.setRestriction(Restrictions.in("outboundId", orderIdList.toArray()));
        List<BizOutboundTaskDetailDismantle> dismantleList = bizOutboundTaskDetailDismantleService.findByCriteria(criteria);
        Set<Integer> temSet = dismantleList.stream().filter(o -> o.getType() == 2).map(BizOutboundTaskDetailDismantle::getOutboundId).collect(Collectors.toSet());
        orderIdList = orderIdList.stream().filter(o -> !temSet.contains(Function.identity())).collect(Collectors.toList());
        Iterator<Integer> iterator = orderIdList.iterator();
        while (iterator.hasNext()) {
            Integer orderId = iterator.next();
            if (temSet.contains(orderId)) {
                iterator.remove();
            }
        }
        if (!CollectionUtils.isEmpty(orderIdList)) {
            criteria = new Criteria(BizOutboundTask.class);
            criteria.setRestriction(Restrictions.in("id", orderIdList.toArray()));
            bizOutboundTaskService.updateMapByCriteria(MapUtils.put("extend2", 1).put("isBindGrid", 1).getMap(), criteria);

            //全零发整订单释放格口
            List<BizOutboundTask> outboundTaskList = bizOutboundTaskService.findByCriteria(criteria);
            for (BizOutboundTask outboundTask : outboundTaskList) {
                GridInfo gridInfo = gridInfoService.findByMap(MapUtils.put("orderId", outboundTask.getId()).getMap()).stream().findFirst().orElse(null);
                if (Objects.nonNull(gridInfo)) {
                    orderLogMapper.save(OrderLog.builder().orderId(outboundTask.getId().toString()).orderNo(outboundTask.getBillNo()).type("格口释放").remark("全零发整订单 释放的格口：" + gridInfo.getGridNo()).createTime(new Date()).build());
                    gridInfo.setOrderId(null);
                    gridInfo.setApplyVolume(BigDecimal.ZERO);
                    gridInfo.setSupplyFlag(0);
                    gridInfo.setFallGrid(0);
                    gridInfo.setBillFlag(0);
                    gridInfo.setLastFlag(0);
                    gridInfo.setScanFinish(0);
                    gridInfoService.update(gridInfo);
                    redisTemplate.delete(RedisKey.GRID_BIND_KEY + gridInfo.getGridNo());
                }
            }

            //打印单据
            criteria = new Criteria(PrintTask.class);
            criteria.setRestriction(Restrictions.in("wmsOutTaskId", orderIdList.toArray()).and(Restrictions.eq("type", 4)));
            Set<Integer> orderSet = printTaskService.findByCriteria(criteria).stream().map(PrintTask::getWmsOutTaskId).collect(Collectors.toSet());

            PrintTask printTask = null;
            for (Integer orderId : orderIdList) {
                if (orderSet.contains(orderId)) {
                    continue;
                }
                printTask = new PrintTask();
                printTask.setPrintCount(0);
                printTask.setCreateTime(new Date());
                printTask.setStatus(0);
                printTask.setWmsOutTaskId(orderId);
                printTask.setType(4);
                printTaskService.save(printTask);
            }
        }
        for (ContainerTaskDismantle containerTaskDismantle : tempList) {
            redisTemplate.opsForHash().delete("CL:SUPPER:" + containerTaskDismantle.getOutboundId(), containerTaskDismantle.getOutboundDetailId().toString());
        }
    }


    public void setDismantleData(ContainerTask dismantleData, List<ContainerTaskDismantle> containerTaskDismantleList, int i, BigDecimal qty) {
        ContainerTaskDismantle containerTaskDismantle = new ContainerTaskDismantle();
        containerTaskDismantle.setContainerTaskId(dismantleData.getId());
        containerTaskDismantle.setPlanQty(qty);
        containerTaskDismantle.setActQty(new BigDecimal("0"));
        containerTaskDismantle.setOutQty(new BigDecimal("0"));
        containerTaskDismantle.setType(i);
        containerTaskDismantle.setStatus(0);
        containerTaskDismantle.setCreateTime(new Date());
        containerTaskDismantle.setOutboundId(dismantleData.getOutboundId());
        containerTaskDismantle.setOutboundDetailId(dismantleData.getOutboundDetailId());
        containerTaskDismantle.setItemId(dismantleData.getItemId());
        containerTaskDismantle.setOwnerId(dismantleData.getOwnerId());
        containerTaskDismantle.setLotId(dismantleData.getLotId());
        containerTaskDismantle.setPackId(dismantleData.getPackId());
        containerTaskDismantleList.add(containerTaskDismantle);
    }


    public void handleOrder(List<ContainerTaskDto> containerTaskDtoList, String stationId, List<OrderDto> orderDtoList) throws Exception {
        System.out.println("指定波次订单处理");
        Map<Integer, List<ContainerTaskDto>> orderMap = containerTaskDtoList.stream().collect(Collectors.groupingBy(ContainerTaskDto::getOrderId));
        List<BizOutboundTaskDetail> updateBizOutboundTaskDetailList = new ArrayList<>();
        List<BizOutboundTask> updateBizOutboundTaskList = new ArrayList<>();
        for (Map.Entry<Integer, List<ContainerTaskDto>> orderContainerTask : orderMap.entrySet()) {
            Integer orderId = orderContainerTask.getKey();
            List<ContainerTaskDto> containerTaskDtos = orderContainerTask.getValue();
            // 订单状态更新
            List<BizOutboundTaskDetail> bizOutboundTaskDetailList = bizOutboundTaskDetailService.findByMap(MapUtils.put("outboundId", orderId).getMap());
            BizOutboundTask bizOutboundTask = bizOutboundTaskService.findById(orderId);
            if (CompareUtil.compare(bizOutboundTask.getBillType(), REPLENISH_TYPE) == 0) {
                //超补订单处理
                handleOverSupplement(containerTaskDtoList, bizOutboundTask);
            }
            bizOutboundTaskDetailList.forEach(k -> {
                if (k.getStatus() == OrderStatusConstants.INIT_STATUS) {
                    k.setStatus(OrderStatusConstants.START_STATUS);
                    k.setUpdateTime(LocalDateTime.now());
                    updateBizOutboundTaskDetailList.add(k);
                }
            });
            if (bizOutboundTask.getStatus() == OrderStatusConstants.INIT_STATUS) {
                bizOutboundTask.setStatus(OrderStatusConstants.START_STATUS);
                bizOutboundTask.setUpdateTime(LocalDateTime.now());
                updateBizOutboundTaskList.add(bizOutboundTask);
            }
        }
        bizOutboundTaskDetailService.batchUpdateStatus(updateBizOutboundTaskDetailList.stream().map(BizOutboundTaskDetail::getId).collect(Collectors.toList()), OrderStatusConstants.START_STATUS);
        bizOutboundTaskService.batchUpdateStatus(updateBizOutboundTaskList.stream().map(BizOutboundTask::getId).collect(Collectors.toList()), OrderStatusConstants.START_STATUS);
//        bizOutboundTaskDetailService.batchUpdate(updateBizOutboundTaskDetailList);
//        bizOutboundTaskService.batchUpdate(updateBizOutboundTaskList);
    }


    /**
     * 增加超补逻辑
     */
    private void handleOverSupplement(List<ContainerTaskDto> containerTaskDtoList, BizOutboundTask bizOutboundTask) throws Exception {
        System.out.println("超补订单处理");
        List<HitNotificationDTO> list = new ArrayList<>();
        List<ContainerTaskDto> collect = containerTaskDtoList.stream().filter(x -> x.getOrderId().equals(bizOutboundTask.getId())).collect(Collectors.toList());

        List<ItemSyncVO> itemSyncVOS = feignGoodsService.queryItemMst(collect.stream().map(ContainerTaskDto::getItemId).distinct().collect(Collectors.toList()));

        for (ContainerTaskDto containerTaskDto : collect) {
            if (containerTaskDto.getAbcType().equals(AbcTypeConstant.TYPE_B) || containerTaskDto.getAbcType().equals(AbcTypeConstant.TYPE_C)) {
                //如果为BC品品，则需要判断是否满足超补条件
                Boolean superFill = containerSuperFill(containerTaskDto, itemSyncVOS);
                //如果不满足超补条件，则跳过
                if (!superFill) {
                    continue;
                }
            }
            HitNotificationDTO hitNotificationDTO = new HitNotificationDTO();
            hitNotificationDTO.setWorkType(bizOutboundTask.getWorkType());
            hitNotificationDTO.setBusinessType(bizOutboundTask.getBusinessType());
            hitNotificationDTO.setTaskId(bizOutboundTask.getUpperSystemTaskId());
            hitNotificationDTO.setBillNo(bizOutboundTask.getBillNo());
            hitNotificationDTO.setContainerNo(containerTaskDto.getContainerSubNo());
            hitNotificationDTO.setTaskLineId(containerTaskDto.getSeqNo());
            hitNotificationDTO.setOwnerId(containerTaskDto.getOwnerId());
            hitNotificationDTO.setItemId(containerTaskDto.getItemId());
            hitNotificationDTO.setLotId(containerTaskDto.getLotId());
            hitNotificationDTO.setPackId(containerTaskDto.getPackId());
            hitNotificationDTO.setWmsLocationCode(bizOutboundTask.getWmsLocationCode());
            hitNotificationDTO.setQty(containerTaskDto.getContainerInfoQyt().doubleValue());
            hitNotificationDTO.setLackQty(0.0);
            hitNotificationDTO.setExceedQyt(containerTaskDto.getContainerInfoQyt().subtract(containerTaskDto.getBindingNum()).doubleValue());
            list.add(hitNotificationDTO);
        }
        HitNotificationReqDTO hitNotificationReqDTO = new HitNotificationReqDTO();
        hitNotificationReqDTO.setSubList(list);
        hitNotificationReqDTO.setMsgId(UUID.randomUUID().toString());
        hitNotificationReqDTO.setWarehouseId(bizOutboundTask.getWmsWarehouseId());
        RestMessage<JSONObject> restMessage = wmsHitNotificationService.execute(hitNotificationReqDTO);
        if (!restMessage.isSuccess()) {
            log.error("超补订单【{}】处理失败：{}", collect, restMessage.getMessage());
            return;
        }
        HitNotificationResDTO hitNotificationResDTO = JSON.parseObject(restMessage.getData().toString(), HitNotificationResDTO.class);
        if (!Objects.isNull(hitNotificationResDTO) && CollectionUtil.isNotEmpty(hitNotificationResDTO.getExceedSubList())) {
            List<String> supercomplementList = hitNotificationResDTO.getExceedSubList().stream().map(HitNotificationDTO::getContainerNo).collect(Collectors.toList());
            // 修改容器任务状态状态
            containerTaskDtoList.forEach(x -> {
                if (supercomplementList.contains(x.getContainerSubNo())) {
                    // 修改对象属性
                    x.setBindingNum(x.getContainerInfoQyt());
                    x.setContainerType(ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE);
                }
            });
        }
    }


    /**
     * BC品容器超补判断
     */
    private Boolean containerSuperFill(ContainerTaskDto containerTaskDto, List<ItemSyncVO> itemSyncVOS) {
        String bcSuperConversion = String.valueOf(redisTemplate.opsForValue().get(SysParamConstants.SYSPRE_FIX + SysParamConstants.BC_SUPER_CONVERSION));
        BigDecimal remainQty = containerTaskDto.getContainerInfoQyt().subtract(containerTaskDto.getBindingNum());
        ItemSyncVO itemSyncVO = itemSyncVOS.stream().filter(x -> x.getItemId().equals(containerTaskDto.getItemId())).findFirst().orElse(null);
        BigDecimal conversionRate = itemSyncVO.getUomList().get(0).getConversionRate();
        BigDecimal divide = remainQty.divide(conversionRate, 0, RoundingMode.HALF_UP);
        if (divide.compareTo(new BigDecimal(bcSuperConversion)) > 0) {
            return false;
        }
        return true;
    }


    private List<ContainerTaskDto> getGroupList(List<OrderDto> orderDtoList, List<ContainerInfoDto> containerInfoDtoList, Map<Integer, String> strategyMap) throws Exception {
        List<OrderDetailDto> orderDetailDtoList = getAllOrderDetailList(orderDtoList);
        Map<String, List<OrderDetailDto>> detailMap = orderDetailDtoList.stream().collect(Collectors.groupingBy(group -> GoodsPropertyUtils.getGoodsProperty(group.getItemId(), group.getLotId(), group.getOwnerId(), group.getPackId())));
        List<ContainerTaskDto> containerTaskDtoList = new ArrayList<>();
        Set<Integer> orderSet = new TreeSet<>();
        for (String s : detailMap.keySet()) {
            List<OrderDetailDto> detailDtoList = detailMap.get(s);
            orderSet.addAll(getAllTask(orderDtoList, containerInfoDtoList, strategyMap, containerTaskDtoList, detailDtoList));
        }
        if (CollectionUtil.isNotEmpty(orderSet)) {
            containerTaskDtoList = containerTaskDtoList.stream().filter(x -> !orderSet.contains(x.getOrderId())).collect(Collectors.toList());
        }
        return containerTaskDtoList;
    }


    private List<OrderDetailDto> getAllOrderDetailList(List<OrderDto> orderDtoList) {
        List<OrderDetailDto> orderDetailDtoList = new ArrayList<>();
        for (OrderDto orderDto : orderDtoList) {
            orderDetailDtoList.addAll(orderDto.getOrderDetailDtoList());
        }
        return orderDetailDtoList;
    }


    public Set<Integer> getAllTask(List<OrderDto> orderDtos, List<ContainerInfoDto> containerInfoDtoList, Map<Integer, String> strategyMap, List<ContainerTaskDto> containerTaskDtoList, List<OrderDetailDto> detailDtoList) throws Exception {
//        List<BizOutboundTaskDetailDismantle> dismantleList = bizOutboundTaskDetailDismantleService.findByMap(MapUtils.put("status", 0).getMap());
        Set<Integer> orderSet = new TreeSet<>();
        for (OrderDetailDto orderDetailDto : detailDtoList) {
            List<ContainerInfoDto> collect = containerInfoDtoList.stream().filter(x -> Objects.equals(x.getBusinessProperty(), orderDetailDto.getBusinessProperty()) && x.getQty().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
            OrderDto orderDto = orderDtos.stream().filter(x -> x.getOrderId().equals(orderDetailDto.getOrderId())).findFirst().orElseThrow(() -> new PrologException("集合中没有找到订单id：" + orderDetailDto.getOrderId()));
            BigDecimal qty = orderDetailDto.getPlanNum();

            while (qty.compareTo(BigDecimal.ZERO) > 0) {
                ContainerTaskDto containerTaskDto = null;
                //剔除不可追加的托盘，（不同波次、不同订单类型）
//                delUseContainer(collect, orderDto, containerTaskDtoList);
                if (CollectionUtil.isEmpty(collect)) {
                    log.error("订单{} 剔除不可追加库存后无可用库存", orderDto.getBillNo());
                    orderSet.add(orderDto.getOrderId());
                    break;
                }
                //获取最佳托盘
                List<ContainerInfoDto> bestContainer = StrategyApi.getBestContainer(strategyMap, collect, qty);
                AssertUtils.isNotTrue(org.apache.commons.collections4.CollectionUtils.isEmpty(bestContainer), "订单ID：[%s]，订单详情ID:[%s],可出托盘正在任务中，不可追加任务");
                ContainerInfoDto containerInfoDto = containerInfoDtoList.stream().filter(x -> x.getContainerSubNo().equals(bestContainer.get(0).getContainerSubNo()) && x.getBusinessProperty().equals(bestContainer.get(0).getBusinessProperty())).findFirst().get();

                if (orderDetailDto.getIsSupply() == 1) {
                    //缺货补货任务  根据数量判断整件缺货或拆零缺货  整件必须找到整件库存  拆零必须找到拆零库存
//                    BizOutboundTaskDetailDismantle bizOutboundTaskDetailDismantle = dismantleList.stream().filter(o -> o.getOutboundDetailId().equals(orderDetailDto.getOrderDetailId())
//                            && o.getSupplyQty().compareTo(orderDetailDto.getPlanNum()) == 0).findFirst().orElseThrow(() -> new PrologException("当前拆零补货任务【%s】,补货数量为【%s】,未找到补货数据"));
//                    AssertUtils.isNotTrue(Objects.isNull(containerInfoDto),"订单ID：[%s]，订单详情ID:[%s],拆零补货数量和记录数量不一致");
                    if (orderDetailDto.getType() == 1) {
                        //零发整补货 找到库存充足的托盘
                        containerInfoDto = containerInfoDtoList.stream().filter(x -> x.getQty().compareTo(orderDetailDto.getPlanNum()) >= 0).findFirst().get();
                        AssertUtils.isNotTrue(Objects.isNull(containerInfoDto), "订单ID：[%s]，订单详情ID:[%s],拆零补货为整件补货，无满足数量的托盘");
                    }
                }

                //整托（托盘有锁定数量的时候不可整托出库）
                if (qty.compareTo(containerInfoDto.getQty()) >= 0 && containerInfoDto.getLockQty().compareTo(BigDecimal.ZERO) == 0) {
                    //查有无在途追加的托盘追加为整托的情况
                    ContainerInfoDto finalContainerInfoDto = containerInfoDto;
                    Long count = containerTaskDtoList.stream().filter(o -> o.getContainerSubNo().equals(finalContainerInfoDto.getContainerSubNo())).count();
                    int type = ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE;
                    if (containerInfoDto.getOrderNum() > 0 || count > 0) {
                        type = ContainerTaskStatusConstants.MORE_FULL_TRAY_TYPE;
                    }
                    containerTaskDto = computeTask(orderDto, orderDetailDto, containerInfoDto, qty, type);
                    qty = qty.subtract(containerInfoDto.getQty());
                    containerInfoDto.setQty(BigDecimal.ZERO);
                    collect.remove(bestContainer.get(0));
                } else {
                    //拼托
                    containerTaskDto = computeTask(orderDto, orderDetailDto, containerInfoDto, qty, ContainerTaskStatusConstants.HALF_TRAY_TYPE);
                    containerInfoDto.setQty(containerInfoDto.getQty().subtract(qty));
                    qty = BigDecimal.ZERO;
                }
                containerTaskDtoList.add(containerTaskDto);
                computerStoreTaskNum(collect, bestContainer.get(0));
            }
        }
        return orderSet;
    }

    public void computerStoreTaskNum(List<ContainerInfoDto> containerTaskDtoList, ContainerInfoDto bestContainer) {
        containerTaskDtoList.stream().filter(x -> Objects.equals(x.getAreaNo(), bestContainer.getAreaNo())).forEach(x -> x.setTaskNum(x.getTaskNum() + 1));
    }


    public ContainerTaskDto computeTask(OrderDto orderDto, OrderDetailDto orderDetailDto, ContainerInfoDto containerInfoDto, BigDecimal qty, int type) {
        ContainerTaskDto containerTaskDto = new ContainerTaskDto();
        containerTaskDto.setOrderId(orderDetailDto.getOrderId());
        containerTaskDto.setOrderDetailId(orderDetailDto.getOrderDetailId());
        containerTaskDto.setContainerType(type);
        containerTaskDto.setBizPropertyId(containerInfoDto.getBizPropertyId());
        containerTaskDto.setContainerSubNo(containerInfoDto.getContainerSubNo());
        containerTaskDto.setContainerNo(containerInfoDto.getContainerNo());
        containerTaskDto.setTaskType(orderDto.getBillType());
        containerTaskDto.setCompanyId(orderDto.getCompanyId());
        containerTaskDto.setWaveNo(orderDto.getWaveNo());
        containerTaskDto.setTargetArea(orderDetailDto.getTargetArea());
        containerTaskDto.setPriority(orderDto.getPriority());
        containerTaskDto.setWmsLocationCode(orderDto.getWmsLocationCode());
        containerTaskDto.setItemId(containerInfoDto.getItemId());
        containerTaskDto.setLotId(containerInfoDto.getLotId());
        containerTaskDto.setOwnerId(containerInfoDto.getOwnerId());
        containerTaskDto.setPackId(containerInfoDto.getPackId());
        containerTaskDto.setSeqNo(orderDetailDto.getSeqNo());
        containerTaskDto.setContainerInfoQyt(containerInfoDto.getQty());
        containerTaskDto.setAbcType(orderDetailDto.getAbcType());
        switch (type) {
            case ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE:
                containerTaskDto.setBindingNum(containerInfoDto.getQty());
                break;
            case ContainerTaskStatusConstants.MORE_FULL_TRAY_TYPE:
                containerTaskDto.setBindingNum(containerInfoDto.getQty());
                break;
            case ContainerTaskStatusConstants.HALF_TRAY_TYPE:
                containerTaskDto.setBindingNum(qty);
                break;
            default:
        }
        return containerTaskDto;
    }

    public void delUseContainer(List<ContainerInfoDto> collect, OrderDto orderDto, List<ContainerTaskDto> containerTaskDtoList) {
        Criteria criteria = new Criteria(ContainerTask.class);
        criteria.setRestriction(Restrictions.in("containerSubNo", collect.stream().map(ContainerInfoDto::getContainerSubNo).collect(Collectors.toList()).toArray()));
        List<ContainerTask> containerTasks = containerTaskService.findByCriteria(criteria);
        List<ContainerTaskInfoDto> tempList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(containerTasks)) {
            containerTasks.forEach(o -> {
                ContainerTaskInfoDto container = new ContainerTaskInfoDto();
                BeanUtils.copyProperties(o, container);
                tempList.add(container);
            });
        }
        if (!CollectionUtils.isEmpty(containerTaskDtoList)) {
            containerTaskDtoList.forEach(o -> {
                ContainerTaskInfoDto container = new ContainerTaskInfoDto();
                BeanUtils.copyProperties(o, container);
                tempList.add(container);
            });
        }
        if (!CollectionUtils.isEmpty(tempList)) {
            Map<String, Long> orderNum = tempList.stream().filter(o -> o.getTaskType().equals(orderDto.getBillType())).collect(Collectors.groupingBy(ContainerTaskInfoDto::getContainerSubNo, Collectors.counting()));
            collect.forEach(o -> {
                if (orderNum.containsKey(o.getContainerSubNo())) {
                    o.setOrderNum(Integer.parseInt(orderNum.get(o.getContainerSubNo()) + ""));
                }
            });
        }
//        if(!CollectionUtils.isEmpty(containerTasks)){
//            Set<String> set = containerTasks.stream().filter(o -> !orderDto.getBillType().equals(o.getTaskType())).map(ContainerTask::getContainerSubNo).distinct().collect(Collectors.toSet());
//            if(set != null && set.size() > 0){
//                collect.remove(collect.stream().filter(o -> set.contains(o.getContainerSubNo())).findFirst().orElse(null));
//            }
//        }
    }


    public boolean computeStore(OrderDto orderDto, Map<String, BigDecimal> storeMap) {
        Map<String, BigDecimal> tempMap = storeMap;
        List<OrderDetailDto> orderDetailDtoList = orderDto.getOrderDetailDtoList();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderDetailDtoList)) {
            log.warn("订单id【{}】下无对应订单明细", orderDto.getOrderId());
            return false;
        }
        for (OrderDetailDto orderDetailDto : orderDetailDtoList) {
            BigDecimal qty = tempMap.get(orderDetailDto.getBusinessProperty());
            if (Objects.isNull(qty)) {
                log.warn("订单明细【{}】所需的品种【{}】库存数【{}】不足", orderDetailDto.getOrderDetailId(), orderDetailDto.getBusinessProperty(), orderDetailDto.getPlanNum(), qty);
                return false;
            }
            if (qty.compareTo(orderDetailDto.getPlanNum()) < 0) {
                log.warn("订单明细【{}】所需的品种【{}】所需数量【{}】库存数【{}】不足", orderDetailDto.getOrderDetailId(), orderDetailDto.getBusinessProperty(), orderDetailDto.getPlanNum(), qty);
                return false;
            } else if (qty.equals(orderDetailDto.getPlanNum())) {
                tempMap.remove(orderDetailDto.getBizPropertyId());
            } else {
                tempMap.put(orderDetailDto.getBusinessProperty(), qty.subtract(orderDetailDto.getPlanNum()));
            }
        }
        storeMap = tempMap;
        System.out.println(storeMap);
        return true;
    }


    public List<ContainerInfoDto> getPartStrategyContainerInfo(String warehouseArea) {
        Criteria criteria = new Criteria(ContainerTask.class);
        criteria.restrictionBuilder().eq(ContainerTask::getWmsLocationCode, warehouseArea).build();
        List<ContainerTask> containerTaskList = containerTaskService.findByCriteria(criteria);
        List<ContainerInfoDto> containerInfoDtoList = containerInfoService.getContainerInfoLsDto(warehouseArea);

        List<String> full = containerTaskList.stream().filter(s -> s.getContainerType() == ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE || s.getContainerType() == ContainerTaskStatusConstants.MORE_FULL_TRAY_TYPE).map(ContainerTask::getContainerNo).distinct().collect(Collectors.toList());
//        List<String> containerNoList = containerTaskList.stream().filter(s -> s.getStatus() >= 2).map(ContainerTask :: getContainerNo).distinct().collect(Collectors.toList());
        containerInfoDtoList = containerInfoDtoList.stream().filter(containerInfoDto -> !full.contains(containerInfoDto.getContainerSubNo())).collect(Collectors.toList());
//        containerInfoDtoList = containerInfoDtoList.stream().filter(containerInfoDto -> !containerNoList.contains(containerInfoDto.getContainerNo())).collect(Collectors.toList());
        Map<String, BigDecimal> collect = containerTaskList.stream().collect(Collectors.toMap(ContainerTask::getContainerSubNo, ContainerTask::getQty, BigDecimal::add));
        for (ContainerInfoDto containerInfoDto : containerInfoDtoList) {
            BigDecimal qty = collect.get(containerInfoDto.getContainerSubNo());
            if (Objects.nonNull(qty)) {
                containerInfoDto.setQty(containerInfoDto.getQty().subtract(qty));
            }
        }
        return containerInfoDtoList;
    }
}
