package com.hys.app.service.erp.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hys.app.converter.erp.OrderConverter;
import com.hys.app.framework.database.BaseQueryParam;
import com.hys.app.framework.database.WebPage;
import com.hys.app.framework.database.mybatisplus.base.BaseServiceImpl;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.framework.util.BeanUtils;
import com.hys.app.mapper.erp.OrderMapper;
import com.hys.app.mapper.erp.WarehouseOutMapper;
import com.hys.app.mapper.goods.GoodsMapper;
import com.hys.app.model.erp.dos.*;
import com.hys.app.model.erp.dto.*;
import com.hys.app.model.erp.enums.*;
import com.hys.app.model.erp.vo.GoodsVO;
import com.hys.app.model.erp.vo.OrderSendItemVO;
import com.hys.app.model.erp.vo.OrderVO;
import com.hys.app.model.erp.vo.ProductVO;
import com.hys.app.model.goods.dos.GoodsGalleryDO;
import com.hys.app.service.erp.*;
import com.hys.app.service.goods.GoodsGalleryManager;
import com.hys.app.service.kuaidiniao.GaoDeUtil;
import com.hys.app.service.kuaidiniao.entity.PreOrderModelDTO;
import com.hys.app.service.kuaidiniao.entity.resReturnBackBase;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单业务层实现
 *
 * @author 张崧
 * 2024-01-24 15:58:31
 */
@Service
@AllArgsConstructor
public class OrderManagerImpl extends BaseServiceImpl<OrderMapper, OrderDO> implements OrderManager {

    private OrderConverter converter;
    private GoodsMapper goodsMapper;
    private OrderItemManager orderItemManager;
    private ProductStockManager productStockManager;
    private NoGenerateManager noGenerateManager;
    private WarehouseOutMapper warehouseOutMapper;
    private WarehouseOutItemManager warehouseOutItemManager;
    private ProductManager productManager;
    private OrderSendManager orderSendManager;
    private OrderSendItemManager orderSendItemManager;
    private WarehouseManager warehouseManager;
    private ItemSnCodeManager itemSnCodeManager;
    private GoodsSnManager goodsSnManager;
    private LockedStockDetailManager lockedStockDetailManager;

    @Override
    public WebPage<OrderVO> list(OrderQueryParams queryParams) {
        WebPage<OrderDO> page = baseMapper.selectPage(queryParams);
        return converter.convertPage(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long add(OrderDTO orderDTO) {
        if (OrderTypeEnum.TO_C.equals(orderDTO.getType())) {
            if (ObjectUtil.isNull(orderDTO.getStartTime())) {
                throw new ServiceException("租用时间不能为空");
            }
        }
        GaoDeUtil.getLongitudeLatitude(orderDTO.getProvinceCityAreaAddress());
        OrderDO orderDO = BeanUtil.copyProperties(orderDTO, OrderDO.class);
        orderDO.setSn(noGenerateManager.generate(NoBusinessTypeEnum.Order, orderDO.getDeptId()));
        // 保存订单
        save(orderDO);
        // 保存订单项
        List<OrderItemDO> itemList = BeanUtils.toBean(orderDTO.getItemList(), OrderItemDO.class);
        //校验库存
//        checkStock(orderDO,itemList);
        itemList.forEach(item -> item.setOrderId(orderDO.getId()));
        orderItemManager.saveBatch(itemList);
        return orderDO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(OrderDTO orderDTO) {
        if (OrderTypeEnum.TO_C.equals(orderDTO.getType())) {
            if (ObjectUtil.isNull(orderDTO.getStartTime())) {
                throw new ServiceException("租用时间不能为空");
            }
        }
        GaoDeUtil.getLongitudeLatitude(orderDTO.getProvinceCityAreaAddress());
        OrderDO orderDO = BeanUtil.copyProperties(orderDTO, OrderDO.class);
        // 更新订单
        updateById(orderDO);
        // 更新订单项
        List<OrderItemDO> itemList = BeanUtils.toBean(orderDTO.getItemList(), OrderItemDO.class);

        itemList.forEach(item -> item.setOrderId(orderDO.getId()));
        orderItemManager.remove(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, orderDTO.getId()));
        orderItemManager.saveBatch(itemList);
    }

    @Override
    public OrderVO getDetail(Long id) {
        OrderDO orderDO = getById(id);
        OrderVO orderVO = BeanUtil.copyProperties(orderDO, OrderVO.class);
        List<OrderItemDO> list = orderItemManager.list(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, id));
        List<Long> goodIdlist = list.stream().map(OrderItemDO::getProductId).collect(Collectors.toList());
        // 查询订单项
        List<OrderItemDTO> itemList = BeanUtils.toBean(list, OrderItemDTO.class);
        //所有的商品信息
        List<ProductDO> productDOList = productManager.list(new LambdaQueryWrapper<ProductDO>().in(ProductDO::getId, goodIdlist));
        for (OrderItemDTO dto : itemList) {
            ProductVO productVO = BeanUtil.copyProperties(productDOList.stream().filter(item -> item.getId().equals(dto.getProductId())).findFirst().get(), ProductVO.class);
            dto.setProductVO(productVO);
            GoodsVO goodsVO = BeanUtil.copyProperties(goodsMapper.selectById(productVO.getGoodsId()), GoodsVO.class);
            dto.setGoodsVO(goodsVO);
            dto.setUsableStock(productStockManager.getById(dto.getProductStockId()).getUsableStock());

        }
        orderVO.setItemList(itemList);
        return orderVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        OrderDO aDo = getById(id);
        if ("Y".equals(aDo.getHasSubmit())) {
            throw new ServiceException("该商品已确认");
        }
        removeById(id);
        //删除子项
        orderItemManager.remove(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, id));
    }

    @Override
    public void warehouseOutShip(WarehouseOutShipDTO shipDTO) {
        lambdaUpdate()
                .set(OrderDO::getStatus, OrderStatusEnum.COMPLETE)
                .set(OrderDO::getLogisticsTrackingNumber, shipDTO.getTrackingNumber())
                .eq(OrderDO::getWarehouseOutId, shipDTO.getId())
                .update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(Long id) {
        OrderDO aDo = getById(id);
        if (!SaleOrderStatusEnum.TO_BE_COMMIT.equals(aDo.getStatus())) {
            throw new ServiceException("该订单已确认");
        }
        List<OrderItemDO> dos = orderItemManager.list(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, id));

        Set<Long> set = dos.stream().map(OrderItemDO::getWarehouseId).collect(Collectors.toSet());
        for (Long warehouseId : set) {
            //如果允许负库存 把所有不够库存的做成一个发货单打上标记，剩下的做成一个发货单
            List<OrderItemDO> collect = dos.stream().filter(item -> item.getWarehouseId().equals(warehouseId)).collect(Collectors.toList());
            List<Long> stockIds = collect.stream().map(OrderItemDO::getProductStockId).collect(Collectors.toList());
            List<ProductStockDO> list = productStockManager.list(new LambdaQueryWrapper<ProductStockDO>().in(ProductStockDO::getId, stockIds));
            List<OrderItemDO> arrayList = new ArrayList<>();
            if (aDo.getSubtractStock()) {
                for (OrderItemDO itemDO : collect) {
                    ProductStockDO stockDO = list.stream().filter(item -> item.getId().equals(itemDO.getProductStockId())).findFirst().get();
                    if (itemDO.getNum() - stockDO.getUsableStock() > 0) {
                        OrderItemDO orderItemDO = new OrderItemDO();
                        BeanUtil.copyProperties(itemDO, orderItemDO);
                        orderItemDO.setNum(itemDO.getNum() - stockDO.getUsableStock());
                        arrayList.add(orderItemDO);
                        itemDO.setNum(stockDO.getUsableStock());
                    }
                }
            }
            savaSendOrder(aDo, warehouseId, dos, false);
            if (CollUtil.isNotEmpty(arrayList)) {
                savaSendOrder(aDo, warehouseId, arrayList, true);
            }
        }
        //校验库存
        List<OrderItemDO> dos2 = orderItemManager.list(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, id));
        List<Long> collect = dos2.stream().map(OrderItemDO::getProductStockId).collect(Collectors.toList());
        List<ProductStockDO> list = productStockManager.list(new LambdaQueryWrapper<ProductStockDO>().in(ProductStockDO::getId, collect));
        List<StockDTO> arrayList = new ArrayList<>();
        //保存凍結库存明细
        List<LockedStockDetailDO> detailDOS = new ArrayList<>();
        for (OrderItemDO orderItemDO : dos2) {
            StockDTO stockDTO = new StockDTO();
            ProductStockDO byId = list.stream().filter(item -> item.getId().equals(orderItemDO.getProductStockId())).findFirst().get();
            if (!aDo.getSubtractStock()) {
                if (orderItemDO.getNum() > byId.getUsableStock()) {
                    throw new ServiceException(orderItemDO.getProductId() + "的可用库存数量不足");
                }
            }
            stockDTO.setId(byId.getId());
            stockDTO.setNum(orderItemDO.getNum());
            arrayList.add(stockDTO);
            LockedStockDetailDO detailDO = new LockedStockDetailDO();
            detailDO.setProductStockId(orderItemDO.getProductStockId());
            detailDO.setOrderId(id);
            detailDO.setOrderSn(aDo.getSn());
            detailDO.setOrderItemId(orderItemDO.getId());
            detailDO.setOrderType(DetailOrderTypeEnum.ORDER);
            detailDO.setLockedNum(orderItemDO.getNum());
            detailDO.setLockedTime(new Date());
            detailDOS.add(detailDO);
        }
        lockedStockDetailManager.saveBatch(detailDOS);
        productStockManager.updateLockedStock(arrayList);
        aDo.setStatus(SaleOrderStatusEnum.TO_BE_SEND);
        updateById(aDo);
    }

    private void savaSendOrder(OrderDO aDo, Long warehouseId, List<OrderItemDO> dos, Boolean subtractStock) {
        OrderSendDO orderSendDO = new OrderSendDO();
        if (OrderSendTypeEnum.SELF_PICKUP.equals(aDo.getSendType())) {
            Random random = new Random();
            orderSendDO.setSelfPickupNum(100000 + random.nextInt(900000));
        }
        orderSendDO.setOrderId(aDo.getId());
        orderSendDO.setSubtractStock(subtractStock);
        orderSendDO.setWarehouseId(warehouseId);
        orderSendDO.setOrderType(aDo.getType());
        orderSendDO.setSn(noGenerateManager.generate(NoBusinessTypeEnum.OrderSend, 86L));
        orderSendManager.save(orderSendDO);
        List<OrderItemDO> collect = dos.stream().filter(item -> item.getWarehouseId().equals(warehouseId)).collect(Collectors.toList());
        List<OrderSendItemDO> itemList = BeanUtils.toBean(collect, OrderSendItemDO.class);
        itemList.forEach(item -> {
            item.setOrderItemId(item.getId());//订单详情id
            item.setId(null);
            item.setOrderId(aDo.getId());
            item.setSendOrderId(orderSendDO.getId());
            item.setOrderType(orderSendDO.getOrderType());
            //如果是租赁订单把租赁表计和租赁返回时间塞入到发货列表详细里面，出库的时候统计在途库存会用到
        });
        orderSendItemManager.saveBatch(itemList);
    }

    @Override
    public IPage<OrderSendDO> hasSendOrder(OrderQueryParams queryParams) {
        Page<OrderSendDO> page = new Page<>(queryParams.getPageNo(), queryParams.getPageSize());
        LambdaQueryWrapper<OrderSendDO> wrapper = new LambdaQueryWrapper<OrderSendDO>()
                .eq(ObjectUtil.isNotNull(queryParams.getWarehouseId()), OrderSendDO::getWarehouseId, queryParams.getWarehouseId())
                .eq(StrUtil.isNotEmpty(queryParams.getSn()), OrderSendDO::getSn, queryParams.getSn());
        switch (queryParams.getSelectType()) {
            case "to_be_send":
                wrapper.in(OrderSendDO::getStatus, SaleOrderSendStatusEnum.TO_BE_SEND);
                break;
            case "sending":
                wrapper.ne(OrderSendDO::getStatus, SaleOrderSendStatusEnum.TO_BE_SEND);
                break;
            case "to_be_return":
                wrapper.eq(OrderSendDO::getOrderType, OrderTypeEnum.TO_C);
                wrapper.and(item->item.eq(OrderSendDO::getStatus, SaleOrderSendStatusEnum.SENDING)
                        .or()
                        .eq(OrderSendDO::getStatus, SaleOrderSendStatusEnum.TO_BE_SINGE)   );
                break;
        }
        Page<OrderSendDO> paged = orderSendManager.page(page, wrapper);
        paged.getRecords().forEach(item -> item.setOrderVo(getById(item.getOrderId())));
        return paged;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderSend(Long sendOrderId, PreOrderModelDTO orderSendDO) {
        OrderSendDO aDo = orderSendManager.getById(sendOrderId);
        OrderDO orderDO = getById(aDo.getOrderId());
        converter.copyProperties(aDo, orderSendDO, orderSendDO.getReceiver(), orderSendDO.getSender());
        //根据订单查找到这个订单的所有货物扣减库存
        List<OrderSendItemVO> list = orderSendDO.getOrderItemVOS();
        List<OrderSendItemDO> selectList = orderSendItemManager.list(new LambdaQueryWrapper<OrderSendItemDO>().eq(OrderSendItemDO::getSendOrderId, sendOrderId));
        if (list.size() != selectList.size()) {
            throw new ServiceException("发货商品不能修改");
        }
        for (OrderSendItemDO itemDO : selectList) {
            Optional<OrderSendItemVO> first = list.stream().filter(item -> item.getProductId().equals(itemDO.getProductId())).findFirst();
            if (!first.isPresent()) {
                throw new ServiceException("发货商品不能修改");
            }
            if (first.get().getNum() != itemDO.getNum()) {
                throw new ServiceException("发货数量不能修改");
            }
        }
        List<Long> productId = selectList.stream().map(OrderSendItemDO::getProductId).collect(Collectors.toList());
        //查找这些商品在指定仓库的库存，减去对应数量
        List<ProductStockDO> stockDOList = productStockManager.list(new LambdaQueryWrapper<ProductStockDO>()
                .eq(ProductStockDO::getWarehouseId, aDo.getWarehouseId()).in(ProductStockDO::getProductId, productId));
        List<StockDTO> arrayList = new ArrayList<>();
        for (ProductStockDO stockDO : stockDOList) {
            Integer num = list.stream().filter(item -> item.getProductId().equals(stockDO.getProductId())).findFirst().get().getNum();
            StockDTO dto = new StockDTO();
            dto.setId(stockDO.getId());
            dto.setNum(-num);
            arrayList.add(dto);
        }
        //更爱可用库存实际库存冻结库存
        productStockManager.updateActualStock(arrayList, null);
        productStockManager.updateLockedStock(arrayList);
        //更改在途库存
        if (OrderTypeEnum.TO_C.equals(aDo.getOrderType())) {
            //如果是出租商品增加在途库存
            arrayList.forEach(item -> item.setNum(-item.getNum()));
            productStockManager.updateTransitStock(arrayList);
        }
        productStockManager.updateBatchById(stockDOList);
        //生成出库单
        WarehouseOutDO outDO = new WarehouseOutDO();
        if (OrderTypeEnum.TO_C.equals(orderDO.getType())) {
            outDO.setType(WarehouseOutTypeEnum.HAIL_OUT);
        } else if (OrderTypeEnum.TO_B.equals(orderDO.getType())) {
            outDO.setType(WarehouseOutTypeEnum.SALE_OUT);
        }
        outDO.setOrderIdList(sendOrderId);
        outDO.setOrderId(aDo.getOrderId());
        outDO.setHasSubmit("Y");
        outDO.setWarehouseId(aDo.getWarehouseId());
        outDO.setNotes("发货单生成的出库单");
        outDO.setSn(noGenerateManager.generate(NoBusinessTypeEnum.WarehouseOut, 66L));
        warehouseOutMapper.insert(outDO);
        List<ItemSnCodeDO> itemSnCodeDOS = new ArrayList<>();
        //保存出库单明细
        List<WarehouseOutItemDO> beanList = BeanUtils.toBean(list, WarehouseOutItemDO.class);
        //保存发货单明细和序列号的关系
        List<GoodsSnDO> snDOS = new ArrayList<>();
        List<LockedStockDetailDO> detailDOS = new ArrayList<>();
        for (OrderSendItemVO sendItemVO : list) {
            LockedStockDetailDO one = lockedStockDetailManager.getOne(new LambdaQueryWrapper<LockedStockDetailDO>()
                    .eq(LockedStockDetailDO::getOrderId, orderDO.getId()).eq(LockedStockDetailDO::getOrderItemId, sendItemVO.getOrderItemId()));
            if (ObjectUtil.isNull(one)) {
                throw new ServiceException("未找到冻结记录");
            }
            one.setUnLockedTime(new Date());
            if (one.getLockedNum() == (sendItemVO.getNum()+one.getUnLockedNum())){
                one.setStatus(true);
            }
            one.setUnLockedNum(one.getUnLockedNum() + sendItemVO.getNum());
            detailDOS.add(one);
            //判断发货数量是不是和明细数量一致，不一样不让保存
            ProductDO byId = productManager.getById(sendItemVO.getProductId());
            if (byId.getHaveSn()) {
                if (CollUtil.isEmpty(sendItemVO.getSnCodeList())) {
                    throw new ServiceException("有序列号的商品出库必须录入序列号");
                }
                if (sendItemVO.getSnCodeList().size() != sendItemVO.getNum()) {
                    throw new ServiceException("录入的序列号数量和发货数量必须一样多");
                }
            }

            if (CollUtil.isNotEmpty(sendItemVO.getSnCodeList())) {
                snDOS.addAll(sendItemVO.getSnCodeList());
                for (GoodsSnDO snDO : sendItemVO.getSnCodeList()) {
                    //出库明细和序列号的关系
                    ItemSnCodeDO itemSnCodeDO = new ItemSnCodeDO();
                    itemSnCodeDO.setItemId(sendItemVO.getId());
                    itemSnCodeDO.setEntryOutHouseId(sendOrderId);
                    itemSnCodeDO.setType("send");
                    itemSnCodeDO.setSnCodeId(snDO.getId());
                    itemSnCodeDOS.add(itemSnCodeDO);
                }
            }
        }
        //更改冻结库存状态
        lockedStockDetailManager.updateBatchById(detailDOS);
        //更改序列号的状态
        if (CollUtil.isNotEmpty(snDOS)) {
            //更爱序列号状态
            for (GoodsSnDO snDO : snDOS) {
                snDO.setStatus(SnCodeStatusEnum.OUT_WAREHOUSE);
                snDO.setOutHouseId(outDO.getId());
            }
            goodsSnManager.updateBatchById(snDOS);
        }
        //保存出库单明细和序列号的关系
        beanList.forEach(item -> {
            item.setWarehouseOutId(outDO.getId());
            Integer num = list.stream().filter(it -> it.getProductId().equals(item.getProductId())).findFirst().get().getNum();
            item.setOutNum(num);
            //发货明细和sncode做关联
            if (CollUtil.isNotEmpty(item.getSnCodeList())) {
                for (GoodsSnDO snDO : item.getSnCodeList()) {
                    //出库明细和序列号的关系
                    ItemSnCodeDO itemSnCodeDO = new ItemSnCodeDO();
                    itemSnCodeDO.setItemId(item.getId());
                    itemSnCodeDO.setEntryOutHouseId(outDO.getId());
                    itemSnCodeDO.setType("out");
                    itemSnCodeDO.setSnCodeId(snDO.getId());
                    itemSnCodeDOS.add(itemSnCodeDO);
                }
            }
        });
        warehouseOutItemManager.saveBatch(beanList);
        //先删除序列号和子表的关系(发货单可能保存过)
        itemSnCodeManager.remove(new LambdaQueryWrapper<ItemSnCodeDO>()
                .eq(ItemSnCodeDO::getType, "send")
                .eq(ItemSnCodeDO::getEntryOutHouseId, sendOrderId));
        //保存序列号和子表的关系
        itemSnCodeManager.saveBatch(itemSnCodeDOS);
        //更改发货单状态
        aDo.setStatus(SaleOrderSendStatusEnum.SENDING);
        aDo.setWarehouseOutId(outDO.getId());
        orderSendManager.updateById(aDo);
        //更改订单状态
        orderDO.setStatus(SaleOrderStatusEnum.SENDING);
        updateById(orderDO);
    }

    @Override
    public OrderSendDO getSendOrderDetail(String id) {
        OrderSendDO byId = orderSendManager.getById(id);
        OrderDO aDo = getById(byId.getOrderId());
        byId.setWarehouseVO(warehouseManager.getById(byId.getWarehouseId()));
        List<OrderSendItemDO> list = orderSendItemManager.list(new LambdaQueryWrapper<OrderSendItemDO>().eq(OrderSendItemDO::getSendOrderId, id));
        List<OrderSendItemVO> bean = BeanUtils.toBean(list, OrderSendItemVO.class);
        for (OrderSendItemVO itemDO : bean) {
            itemDO.setProductVO(productManager.getById(itemDO.getProductId()));
            itemDO.setGoodsVO(BeanUtil.copyProperties(goodsMapper.selectById(itemDO.getGoodsId()), GoodsVO.class));
            ProductStockDO productStockDO = productStockManager.getById(itemDO.getProductStockId());
            itemDO.setUseAbleStock(productStockDO.getUsableStock());
            itemDO.setActualStock(productStockDO.getActualStock());
            List<ItemSnCodeDO> list2 = itemSnCodeManager.list(new LambdaQueryWrapper<ItemSnCodeDO>().eq(ItemSnCodeDO::getItemId, itemDO.getId()));
            if (CollUtil.isNotEmpty(list2)) {
                List<Long> collected = list2.stream().map(ItemSnCodeDO::getSnCodeId).collect(Collectors.toList());
                itemDO.setSnCodeList(goodsSnManager.list(new LambdaQueryWrapper<GoodsSnDO>().in(GoodsSnDO::getId, collected)));
            }
        }
        byId.setOrderVo(aDo);
        byId.setOrderItemVOS(bean);
        return byId;
    }

    @Override
    public OrderVO getOneBySn(String sn) {
        OrderDO orderDO = getOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getSn, sn));
        if (ObjectUtil.isNull(orderDO)) {
            throw new ServiceException("请录入正确的订单号");
        }
        OrderVO orderVO = BeanUtil.copyProperties(orderDO, OrderVO.class);

        if (SaleOrderStatusEnum.SALE_AFTER_ING.equals(orderDO.getStatus()) ||
                SaleOrderStatusEnum.SALE_AFTER_END.equals(orderDO.getStatus()) ||
                SaleOrderStatusEnum.SALE_AFTER_CANCEL.equals(orderDO.getStatus())) {
            orderVO.setScanOrderType("saleAfter");
            scanOrder(orderVO);
        }

        if (OrderTypeEnum.TO_C.equals(orderDO.getType()) && SaleOrderStatusEnum.SENDING.equals(orderDO.getStatus())) {
            orderVO.setScanOrderType("return");
            scanOrder(orderVO);
        }
        return orderVO;
    }

    private void scanOrder(OrderVO orderVO) {
        List<OrderItemDO> list = orderItemManager.list(new LambdaQueryWrapper<OrderItemDO>()
                .eq(OrderItemDO::getOrderId, orderVO.getId())
                .eq(orderVO.getScanOrderType().equals("saleAfter"), OrderItemDO::getHasSaleAfter, true));
        List<Long> goodIdlist = list.stream().map(OrderItemDO::getProductId).collect(Collectors.toList());
        // 查询订单项
        List<OrderItemDTO> itemList = BeanUtils.toBean(list, OrderItemDTO.class);
        //所有的商品信息
        List<ProductDO> productDOList = productManager.list(new LambdaQueryWrapper<ProductDO>().in(ProductDO::getId, goodIdlist));
        for (OrderItemDTO dto : itemList) {
            ProductVO productVO = BeanUtil.copyProperties(productDOList.stream().filter(item -> item.getId().equals(dto.getProductId())).findFirst().get(), ProductVO.class);
            dto.setProductVO(productVO);
            GoodsVO goodsVO = BeanUtil.copyProperties(goodsMapper.selectById(productVO.getGoodsId()), GoodsVO.class);
            dto.setGoodsVO(goodsVO);
            dto.setUsableStock(productStockManager.getById(dto.getProductStockId()).getUsableStock());
        }
        orderVO.setItemList(itemList);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void extension(Long orderId, OrderDTO orderDTO) {
        OrderDO aDo = getById(orderId);
        if (ObjectUtil.isNull(aDo)) {
            throw new ServiceException("未找到订单");
        }
        //订单延期次数+1
        aDo.setExtension(aDo.getExtension() + 1);
        aDo.setRealPrice(orderDTO.getRealPrice());
        aDo.setPayPrice(orderDTO.getPayPrice());
        updateById(aDo);
        //现在的商品减去原先的商品，额外的商品需要增加额外的发货单，
        List<OrderItemDO> list = orderItemManager.list(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, orderId));
        List<OrderItemDTO> sendList = new ArrayList<>();
        for (OrderItemDTO dto : orderDTO.getItemList()) {
            if (ObjectUtil.isNull(dto.getId())) {
                sendList.add(dto);
            } else {
                Integer num = list.stream().filter(item -> item.getId().equals(dto.getId())).findFirst().get().getNum();
                if (dto.getNum() < num) {
                    throw new ServiceException("延期商品的数量需大于或等于原订单的数量");
                }
                if (dto.getNum() - num > 0) {
                    dto.setNum(dto.getNum() - num);
                    sendList.add(dto);
                }
            }
        }

        List<OrderItemDO> sendNewList = BeanUtils.toBean(sendList, OrderItemDO.class);
        Set<Long> set = sendNewList.stream().map(OrderItemDO::getWarehouseId).collect(Collectors.toSet());
        for (Long warehouseId : set) {
            OrderSendDO orderSendDO = new OrderSendDO();
            orderSendDO.setOrderId(orderId);
            orderSendDO.setWarehouseId(warehouseId);
            orderSendDO.setOrderType(aDo.getType());
            orderSendDO.setSn(noGenerateManager.generate(NoBusinessTypeEnum.OrderSend, 86L));
            orderSendManager.save(orderSendDO);
            List<OrderItemDO> collect = sendNewList.stream().filter(item -> item.getWarehouseId().equals(warehouseId)).collect(Collectors.toList());
            List<OrderSendItemDO> itemList = BeanUtils.toBean(collect, OrderSendItemDO.class);
            itemList.forEach(item -> {
                item.setId(null);
                item.setOrderId(orderId);
                item.setSendOrderId(orderSendDO.getId());
            });
            orderSendItemManager.saveBatch(itemList);
        }
        List<OrderItemDO> itemList = BeanUtils.toBean(orderDTO.getItemList(), OrderItemDO.class);
        itemList.forEach(item -> item.setOrderId(orderId));
        orderItemManager.remove(new LambdaQueryWrapper<OrderItemDO>().eq(OrderItemDO::getOrderId, orderId));
        orderItemManager.saveBatch(itemList);
    }

    @Override
    public resReturnBackBase toBeSendOrder(BaseQueryParam queryParam) {


        return null;
    }

    @Override
    public void saveOrderSend(Long orderSendId, PreOrderModelDTO orderSendDO) {
        OrderSendDO aDo = orderSendManager.getById(orderSendId);
        converter.copyProperties(aDo, orderSendDO, orderSendDO.getReceiver(), orderSendDO.getSender());
        orderSendManager.updateById(aDo);
        List<ItemSnCodeDO> itemSnCodeDOS = new ArrayList<>();
        if (CollUtil.isNotEmpty(orderSendDO.getOrderItemVOS())) {
            for (OrderSendItemVO orderItemVO : orderSendDO.getOrderItemVOS()) {
                //判断发货数量是不是和明细数量一致，不一样不让保存
                ProductDO byId = productManager.getById(orderItemVO.getProductId());
                if (CollUtil.isNotEmpty(orderItemVO.getSnCodeList())) {
                    for (GoodsSnDO snDO : orderItemVO.getSnCodeList()) {
                        //出库明细和序列号的关系
                        ItemSnCodeDO itemSnCodeDO = new ItemSnCodeDO();
                        itemSnCodeDO.setItemId(orderItemVO.getId());
                        itemSnCodeDO.setEntryOutHouseId(orderSendId);
                        itemSnCodeDO.setType("send");
                        itemSnCodeDO.setSnCodeId(snDO.getId());
                        itemSnCodeDOS.add(itemSnCodeDO);
                    }
                }
            }
        }
        //保存序列号和子表的关系
        itemSnCodeManager.saveBatch(itemSnCodeDOS);
    }
}

