package cn.iocoder.yudao.module.order.service.orderWarehouseAdjust;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.apollo.core.event.box.BoxCheckOrderDestWarehouseEvent;
import cn.iocoder.yudao.framework.apollo.core.event.box.BoxCheckOrderSchedulingEvent;
import cn.iocoder.yudao.framework.apollo.core.event.Order.OrderApprovalTypeCheckEvent;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.framework.i18n.core.I18nMessage;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.bpm.enums.WorkFlowEmus;
import cn.iocoder.yudao.module.order.convert.orderWarehouseAdjust.OrderWarehouseAdjustConvert;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderLocation.OrderLocationDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderWarehouseAdjust.OrderWarehouseAdjustDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderWarehouseApproval.OrderWarehouseApprovalDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderWarehouseIn.OrderWarehouseInDO;
import cn.iocoder.yudao.module.order.dal.mysql.orderWarehouseAdjust.OrderWarehouseAdjustMapper;
import cn.iocoder.yudao.module.order.enums.*;
import cn.iocoder.yudao.module.order.service.order.*;
import cn.iocoder.yudao.module.order.service.orderException.OrderExceptionService;
import cn.iocoder.yudao.module.order.service.orderWarehouseApproval.OrderWarehouseApprovalService;
import cn.iocoder.yudao.module.order.service.orderWarehouseIn.OrderWarehouseInService;
import cn.iocoder.yudao.module.order.service.orderWarehousePicture.OrderWarehousePictureService;
import cn.iocoder.yudao.module.order.vo.orderException.OrderExceptionCreateReqVO;
import cn.iocoder.yudao.module.order.vo.orderException.OrderExceptionDescVO;
import cn.iocoder.yudao.module.order.vo.orderLocation.OrderLocationCreateReqVO;
import cn.iocoder.yudao.module.order.vo.orderWarehouseAdjust.*;
import cn.iocoder.yudao.module.order.vo.orderWarehouseApproval.OrderWarehouseApprovalBackVO;
import cn.iocoder.yudao.module.order.vo.orderWarehouseIn.OrderWarehouseInAdjustCancelRequestVO;
import cn.iocoder.yudao.module.order.vo.orderWarehouseIn.OrderWarehouseInQueryVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.order.enums.OrderApprovalTypeEnum.WAREHOUSE_ADJUST;

/**
 * 调仓记录 Service 实现类
 *
 * @author yanghao
 */
@Service
@Validated
public class OrderWarehouseAdjustServiceImpl extends AbstractService<OrderWarehouseAdjustMapper, OrderWarehouseAdjustDO> implements OrderWarehouseAdjustService {

    @Resource
    private OrderWarehouseAdjustMapper warehouseAdjustMapper;

    @Resource
    private OrderWarehouseApprovalService orderWarehouseApprovalService;

    @Resource
    private OrderWarehousePictureService orderWarehousePictureService;

    @Resource
    private OrderService orderService;
    @Resource
    private OrderBusinessService orderBusinessService;
    @Resource
    private OrderQueryService orderQueryService;

    @Resource
    private OrderExceptionService orderExceptionService;

    @Resource
    private OrderLocationService orderLocationService;

    @Resource
    private OrderWarehouseInService orderWarehouseInService;

    @Resource
    private OrderItemService orderItemService;

    @Resource
    private ApplicationContext applicationContext;


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public String adjustApply(OrderWarehouseAdjustCreateReqVO createReqVO) {

        String orderIds = createReqVO.getOrderIds();
        String[] split = orderIds.split(",");
        List<Long> orderIdList = Arrays.asList(split).stream().map(Long::parseLong).collect(Collectors.toList());

        Set<Integer> orderStatusSet = new HashSet<>();
        Set<Long> lineIdSet = new HashSet<>();
        Set<Long> boxDestWarehouseIdSet = new HashSet<>();

        List<Long> adjustDirectList = new ArrayList<>();
        List<Long> adjustApplyList = new ArrayList<>();

        for (Long orderId : orderIdList) {
            OrderDO orderDO = orderService.getById(orderId);
            if (orderDO == null) {
                throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_NOT_EXISTS);
            }
            lineIdSet.add(orderDO.getLineId());

            //已入仓 就是起始地调仓，需要校验排单
            if (OrderStatusEnum.IN_WAREHOUSE.getValue().equals(orderDO.getStatus())) {
                //订单排单校验
                applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(orderId));

                //发起调仓申请
                adjustApplyList.add(orderId);
            }
            //已卸柜后 就是目的地调仓，不需要校验排单
            else if (OrderStatusEnum.UNLOADED_CABINET.getValue().equals(orderDO.getStatus())) {
                BoxCheckOrderDestWarehouseEvent boxCheckOrderDestWarehouseEvent = new BoxCheckOrderDestWarehouseEvent(orderId);
                applicationContext.publishEvent(boxCheckOrderDestWarehouseEvent);

                boxDestWarehouseIdSet.add(boxCheckOrderDestWarehouseEvent.getBoxDestWarehouseIdReturn());

                //已卸柜调仓分两种情况，
                if (boxCheckOrderDestWarehouseEvent.getIsSameDestWarehouseReturn()) {
                    // 2. 卸柜仓库与订单目的仓相同，调仓需要审核
                    adjustApplyList.add(orderId);
                } else {
                    // 1. 卸柜仓库与订单目的仓不同，调仓无需审核
                    adjustDirectList.add(orderId);
                }
            }
            if (orderDO == null) {
                throw exception(ORDER_NOT_EXISTS);
            }
            if (orderDO.getAbnormalState() != 0) {
                throw exception(ORDER_HAS_PENDING_EXCEPTION, orderDO.getOrderNo());
            }
            OrderApprovalTypeCheckEvent approvalTypeCheckEvent = new OrderApprovalTypeCheckEvent(orderDO.getOrderId(), null, WAREHOUSE_ADJUST.getValue(), null, false);
            applicationContext.publishEvent(approvalTypeCheckEvent);
            if (approvalTypeCheckEvent.getResult()) {
                throw exception(ORDER_IS_APPROVAL_IN_PROCESS);
            }
            orderStatusSet.add(orderDO.getStatus());
        }
        //判断是不是所有订单的状态都是一样的
        if (CollectionUtil.isNotEmpty(orderStatusSet) && orderStatusSet.size() != 1) {
            throw exception(ORDER_STATUS_NOT_SAME);
        }
        if (CollectionUtil.isNotEmpty(lineIdSet) && lineIdSet.size() != 1) {
            throw exception(WAREHOUSE_LINE_NOT_SAME);
        }
        if (CollectionUtil.isNotEmpty(boxDestWarehouseIdSet) && boxDestWarehouseIdSet.size() != 1) {
            throw exception(BOX_DEST_WAREHOUSE_NOT_SAME);
        }


        if (CollectionUtil.isNotEmpty(adjustApplyList)) {

            StringJoiner adjustIds = new StringJoiner(",");
            for (Long orderId : adjustApplyList) {
                OrderDO orderDO = orderService.getById(orderId);

                // 插入
                OrderWarehouseAdjustDO warehouseAdjust = OrderWarehouseAdjustConvert.INSTANCE.convert(createReqVO);
                warehouseAdjust.setOrderId(orderId);
                warehouseAdjust.setOrderNo(orderDO.getOrderNo());
                warehouseAdjustMapper.insert(warehouseAdjust);

                adjustIds.add(warehouseAdjust.getId().toString());

                // 更新订单状态: 调仓申请中
                Integer auditType = OrderApprovalTypeResultEnum.warehouse_adjust_processing.getType();
                orderService.updateStatus(orderId, null, null, null, OrderWarehouseInStatusEnum.adjust_applying.getValue(), null,
                        auditType, OrderApprovalTypeResultEnum.typeAndResultOf(auditType, 1).getDesc(), false);

                //纪录订单操作日志
                orderBusinessService.addOrderOperateLog(orderId, "仓库操作", (adjustApplyList.size() > 1 ? "批量" : "") + "提交调仓申请", "");
            }

            // 创建审批单
            OrderWarehouseApprovalDO orderWarehouseApprovalDO = new OrderWarehouseApprovalDO();
            orderWarehouseApprovalDO.setOrderIds(adjustIds.toString());
            orderWarehouseApprovalDO.setType(OrderWarehouseApprovalTypeEnum.WAREHOUSE_IN_TRANSFER.getValue());
            orderWarehouseApprovalDO.setFollowUpAdminId(WebFrameworkUtils.getLoginUserId());
            // 设置detail
            OrderWarehouseAdjustInfoDo orderWarehouseAdjustInfoDo = new OrderWarehouseAdjustInfoDo();
            orderWarehouseAdjustInfoDo.setWarehouseInId(createReqVO.getWarehouseInId());
            orderWarehouseAdjustInfoDo.setWarehouseOutId(createReqVO.getWarehouseOutId());
            orderWarehouseApprovalDO.setDetails(JSON.toJSONString(orderWarehouseAdjustInfoDo));
            orderWarehouseApprovalDO.setIsBatch(StringUtil.isNotEmpty(orderIds) && orderIds.contains(",") ? true : false);

            // 发起流程
            orderWarehouseApprovalService.applyAndCreate(orderWarehouseApprovalDO, WorkFlowEmus.ORDER_WAREHOUSE_TRANSFER, createReqVO.getCopyUserId());

            return I18nMessage.getMessage("warehouse.adjust.apply.success");
        }

        if (CollectionUtil.isNotEmpty(adjustDirectList)) {

            for (Long orderId : adjustDirectList) {
                OrderDO orderDO = orderService.getById(orderId);

                // 插入
                OrderWarehouseAdjustDO warehouseAdjust = OrderWarehouseAdjustConvert.INSTANCE.convert(createReqVO);
                warehouseAdjust.setOrderId(orderId);
                warehouseAdjust.setOrderNo(orderDO.getOrderNo());
                warehouseAdjustMapper.insert(warehouseAdjust);

                // 更新订单状态 11-调仓中
                orderService.updateStatus(orderId, null, OrderStatusEnum.WAREHOUSE_ADJUSTMENT.getValue(), null,
                        OrderWarehouseInStatusEnum.adjust_wait_out.getValue(), null, null, null, false);

                //纪录订单操作日志
                orderBusinessService.addOrderOperateLog(orderId, "仓库操作", "货柜目的仓与线路目的仓不一致，直接调仓", "");
            }

            return I18nMessage.getMessage("warehouse.adjust.direct.success");
        }

        return I18nMessage.getMessage("warehouse.adjust.undo");
    }

    @Override
    public OrderWarehouseAdjustLastStatusBackVO adjustLastWithStatus(Long orderId, Integer lang) {
        return orderWarehouseApprovalService.adjustLastWithStatus(orderId, lang);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelAdjust(OrderWarehouseInAdjustCancelRequestVO cancelApplyReqVO) {
        Long orderId = cancelApplyReqVO.getOrderId();

        // 批量调仓的 不可单独取消调仓
        OrderWarehouseAdjustLastStatusBackVO orderWarehouseAdjustLastStatusBackVO = orderWarehouseApprovalService.adjustLastWithStatus(orderId, 0);
        if (orderWarehouseAdjustLastStatusBackVO != null) {
            OrderWarehouseApprovalBackVO orderWarehouseApprovalBackVO = orderWarehouseAdjustLastStatusBackVO.getOrderWarehouseApprovalBackVO();
            if (orderWarehouseApprovalBackVO != null && orderWarehouseApprovalBackVO.getIsBatch()) {
                throw exception(WAREHOUSE_APPROVAL_BATCH_CANNOT_CANCEL);
            }
        }

        //需要将调仓修改为原始的值。 为了处理调仓后又再次调仓，取消后 需要还原为原调仓的值，所以需要查明细。当只有1条调仓纪录时，将toStartWarehouseId或toDestWarehouseId修改为null。多条时需要修改为调仓的历史纪录
        List<OrderWarehouseAdjustDO> orderWarehouseAdjustDOList = warehouseAdjustMapper.selectByOrderId(orderId, 0);
        if (CollectionUtil.isNotEmpty(orderWarehouseAdjustDOList)) {
            OrderDO orderDO = orderService.getById(orderId);

            //倒序
            orderWarehouseAdjustDOList.sort((o1, o2) -> o2.getId().compareTo(o1.getId()));

            //删除最近的这一条（目的是找历史）
            orderWarehouseAdjustDOList.remove(0);

            OrderWarehouseAdjustDO orderWarehouseAdjustDO = orderWarehouseAdjustDOList.stream().filter(t -> OrderWarehouseAdjustStatusEnum.arrivals.getValue().equals(t.getStatus())).findFirst().orElse(null);

            if (OrderStatusEnum.IN_WAREHOUSE.getValue().equals(orderDO.getOldStatus())) {
                orderDO.setAdjustToStartWarehouseId(orderWarehouseAdjustDO == null ? null : orderWarehouseAdjustDO.getWarehouseOutId());
                orderDO.setAdjustToDestWarehouseId(orderWarehouseAdjustDO == null ? null : orderWarehouseAdjustDO.getWarehouseInId());
                orderService.updateAdjustWarehouseId(orderId, orderDO.getAdjustToStartWarehouseId(), orderDO.getAdjustToDestWarehouseId());

            } else if (OrderStatusEnum.UNLOADED_CABINET.getValue().equals(orderDO.getOldStatus())) {
                orderDO.setDestAdjustToStartWarehouseId(orderWarehouseAdjustDO == null ? null : orderWarehouseAdjustDO.getWarehouseOutId());
                orderDO.setDestAdjustToDestWarehouseId(orderWarehouseAdjustDO == null ? null : orderWarehouseAdjustDO.getWarehouseInId());

                orderService.updateDestAdjustWarehouseId(orderId, orderDO.getAdjustToStartWarehouseId(), orderDO.getAdjustToDestWarehouseId());
            }
        }

        if (orderWarehouseAdjustLastStatusBackVO != null) {

            OrderWarehouseApprovalBackVO orderWarehouseApprovalBackVO = orderWarehouseAdjustLastStatusBackVO.getOrderWarehouseApprovalBackVO();
            if (orderWarehouseApprovalBackVO != null && orderWarehouseApprovalBackVO.getIsBatch()) {
                throw exception(WAREHOUSE_APPROVAL_BATCH_CANNOT_CANCEL);
            }

            // if (orderWarehouseApprovalBackVO != null) {
            //     //删除原调仓审核纪录
            //     orderWarehouseApprovalService.deleteOrderWarehouseApproval(orderWarehouseApprovalBackVO.getId());
            // }

            //取消原调仓纪录
            OrderWarehouseAdjustBackVO orderWarehouseAdjustBackVO = orderWarehouseAdjustLastStatusBackVO.getOrderWarehouseAdjustBackVO();
            if (orderWarehouseAdjustBackVO != null) {
                warehouseAdjustMapper.update(null,
                        new LambdaUpdateWrapper<OrderWarehouseAdjustDO>().eq(OrderWarehouseAdjustDO::getId, orderWarehouseAdjustBackVO.getId())
                                .set(OrderWarehouseAdjustDO::getStatus, OrderWarehouseAdjustStatusEnum.cancel.getValue()));
            }
        }

        // 更新订单状态 调仓-已取消
        OrderDO orderDO = orderService.getById(orderId);
        Integer auditType = OrderApprovalTypeResultEnum.warehouse_adjust_cancel.getType();

        OrderWarehouseInStatusEnum orderWarehouseInStatus = OrderWarehouseInStatusEnum.warehouse_finished;
        if (OrderStatusEnum.UNLOADED_CABINET.getValue().equals(orderDO.getOldStatus())) {
            orderWarehouseInStatus = OrderWarehouseInStatusEnum.unloaded_cabinet;
        }
        orderService.updateStatus(orderId, null, orderDO.getOldStatus(), null,
                orderWarehouseInStatus.getValue(), null, 0, OrderApprovalTypeResultEnum.typeAndResultOf(auditType, 4).getDesc(), false);

        //纪录操作日志
        orderBusinessService.addOrderOperateLog(orderId, "仓库操作", "取消调仓申请", "");

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adjustApplyCallback(String approvalId, Integer result) {
        // 调仓申请 - 回调

        OrderWarehouseApprovalDO orderWarehouseApprovalDO =
                orderWarehouseApprovalService.getById(Long.parseLong(approvalId));

        // 更新审核单状态
        orderWarehouseApprovalService.callbackUpdate(orderWarehouseApprovalDO, result);
        if (StringUtils.isNotEmpty(orderWarehouseApprovalDO.getOrderIds())) {
            String[] split = orderWarehouseApprovalDO.getOrderIds().split(",");
            for (String s : split) {
                long adjustId = Long.parseLong(s);
                OrderWarehouseAdjustDO orderWarehouseAdjustDO = warehouseAdjustMapper.selectById(adjustId);
                if (orderWarehouseAdjustDO == null) {
                    throw exception(WAREHOUSE_ADJUST_NOT_EXISTS);
                }
                Long orderId = orderWarehouseAdjustDO.getOrderId();
                OrderDO orderDO = orderService.getById(orderId);

                // 非处理中的都要更新状态
                if (!ApprovalResultStatusEnum.processing.getValue().equals(result)) {
                    // 更新申请纪录的状态
                    orderWarehouseAdjustDO.setStatus(result);
                    warehouseAdjustMapper.updateById(orderWarehouseAdjustDO);
                }

                String processingResults =
                        orderWarehouseApprovalDO.getProcessingResults();
                if (ApprovalResultStatusEnum.pass.getValue().equals(result)) {
                    //纪录订单操作日志
                    orderBusinessService.addOrderOperateLog(orderId, "仓库操作", "调仓申请通过", "");

                    // 更新订单状态 11-调仓中
                    Integer auditType = OrderApprovalTypeResultEnum.warehouse_adjust_pass.getType();
                    orderService.updateStatus(orderId, null, OrderStatusEnum.WAREHOUSE_ADJUSTMENT.getValue(), null,
                            OrderWarehouseInStatusEnum.adjust_wait_out.getValue(), null, 0, OrderApprovalTypeResultEnum.typeAndResultOf(auditType, result).getDesc(), false);

                    // 获取调仓信息
                    String details = orderWarehouseApprovalDO.getDetails();
                    if (StringUtils.isNotEmpty(details)) {

                        // 更新调仓信息
                        OrderWarehouseAdjustInfoDo orderWarehouseAdjustInfoDo = JSON.parseObject(details, OrderWarehouseAdjustInfoDo.class);
                        if (OrderStatusEnum.IN_WAREHOUSE.getValue().equals(orderDO.getStatus())) {
                            orderService.updateAdjustWarehouseId(orderId, orderWarehouseAdjustInfoDo.getWarehouseOutId(), orderWarehouseAdjustInfoDo.getWarehouseInId());
                        } else if (OrderStatusEnum.UNLOADED_CABINET.getValue().equals(orderDO.getStatus())) {
                            orderService.updateDestAdjustWarehouseId(orderId, orderWarehouseAdjustInfoDo.getWarehouseOutId(), orderWarehouseAdjustInfoDo.getWarehouseInId());
                        }

                    }
                }
                //拒绝 或  取消
                else if (ApprovalResultStatusEnum.reject.getValue().equals(result) || ApprovalResultStatusEnum.cancel.getValue().equals(result)) {

                    // 更新订单状态 调仓-已拒绝
                    Integer auditType = OrderApprovalTypeResultEnum.warehouse_adjust_reject.getType();
                    String msg = "调仓申请拒绝";

                    if (ApprovalResultStatusEnum.cancel.getValue().equals(result)) {
                        auditType = OrderApprovalTypeResultEnum.warehouse_adjust_cancel.getType();
                        msg = "调仓申请取消";
                    }

                    // 这里修改为 更新订单状态为上一个状态。因为起始地调仓是5完成入仓状态 - 202 ，目的地调仓为16已卸柜 - 218
                    OrderWarehouseInStatusEnum orderWarehouseInStatus = OrderWarehouseInStatusEnum.warehouse_finished;
                    if (OrderStatusEnum.UNLOADED_CABINET.getValue().equals(orderDO.getStatus())) {
                        orderWarehouseInStatus = OrderWarehouseInStatusEnum.unloaded_cabinet;
                    }
                    orderService.updateStatus(orderId, null, null, null,
                            orderWarehouseInStatus.getValue(), null, 0, OrderApprovalTypeResultEnum.typeAndResultOf(auditType, result).getDesc(), false);

                    //纪录订单操作日志
                    orderBusinessService.addOrderOperateLog(orderId, "仓库操作", msg, "");

                }
            }
        }


    }

    @Override
    public void updateWarehouseAdjustSendOut(OrderWarehouseAdjustSendOutVO sendOutVO) {
        // 校验存在
        OrderWarehouseAdjustDO orderWarehouseAdjustDO = warehouseAdjustMapper.selectById(sendOutVO.getId());
        if (orderWarehouseAdjustDO == null) {
            throw exception(WAREHOUSE_ADJUST_NOT_EXISTS);
        }
        // 更新
        BeanUtils.copyProperties(sendOutVO, orderWarehouseAdjustDO);

        // 已出仓状态
        orderWarehouseAdjustDO.setStatus(OrderWarehouseAdjustStatusEnum.deliveries.getValue());

        // 更新
        warehouseAdjustMapper.updateById(orderWarehouseAdjustDO);

        // 更新订单状态
        orderService.updateStatus(orderWarehouseAdjustDO.getOrderId(), null, null, null, OrderWarehouseInStatusEnum.adjust_wait_in.getValue(), null, null, null, false);

        // 出仓影像
        orderWarehousePictureService.createWarehousePictureBatch(sendOutVO.getUrls(), 2, orderWarehouseAdjustDO.getId());

        //纪录操作日志
        orderBusinessService.addOrderOperateLog(orderWarehouseAdjustDO.getOrderId(), "仓库操作", "调仓出仓", "");
    }

    @Override
    public void updateWarehouseAdjustSendOutBatch(OrderWarehouseAdjustSendOutBatchVO sendOutBatchVO) {

        List<Long> orderIdList = sendOutBatchVO.getOrderIdList();

        //查询订单的最近调仓纪录
        List<OrderWarehouseAdjustDO> orderWarehouseAdjustDOList = warehouseAdjustMapper.selectList(new LambdaQueryWrapperX<OrderWarehouseAdjustDO>()
                .eq(OrderWarehouseAdjustDO::getStatus, OrderWarehouseAdjustStatusEnum.passed.getValue())
                .in(OrderWarehouseAdjustDO::getOrderId, orderIdList));

        if (CollectionUtil.isNotEmpty(orderWarehouseAdjustDOList)) {
            long count = orderWarehouseAdjustDOList.stream().map(OrderWarehouseAdjustDO::getWarehouseOutId).distinct().count();
            if (count > 1) {
                throw exception(WAREHOUSE_ADJUST_BATCH_NOT_SAME_OUT);
            }
            count = orderWarehouseAdjustDOList.stream().map(OrderWarehouseAdjustDO::getWarehouseInId).distinct().count();
            if (count > 1) {
                throw exception(WAREHOUSE_ADJUST_BATCH_NOT_SAME_IN);
            }

            // 出仓
            orderWarehouseAdjustDOList.stream().forEach(orderWarehouseAdjustDO -> {

                // 更新
                BeanUtils.copyProperties(sendOutBatchVO, orderWarehouseAdjustDO);

                // 已出仓状态
                orderWarehouseAdjustDO.setStatus(OrderWarehouseAdjustStatusEnum.deliveries.getValue());

                // 更新
                warehouseAdjustMapper.updateById(orderWarehouseAdjustDO);

                // 更新订单状态
                orderService.updateStatus(orderWarehouseAdjustDO.getOrderId(), null, null, null, OrderWarehouseInStatusEnum.adjust_wait_in.getValue(), null, null, null, false);

                // 出仓影像
                orderWarehousePictureService.createWarehousePictureBatch(sendOutBatchVO.getUrls(), 2, orderWarehouseAdjustDO.getId());

                //纪录操作日志
                orderBusinessService.addOrderOperateLog(orderWarehouseAdjustDO.getOrderId(), "仓库操作", "批量调仓出仓", "");
            });

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWarehouseAdjustArrived(OrderWarehouseAdjustArrivedVO arrivedVO) {
        // 校验存在
        OrderWarehouseAdjustDO orderWarehouseAdjustDO = warehouseAdjustMapper.selectById(arrivedVO.getId());
        if (orderWarehouseAdjustDO == null) {
            throw exception(WAREHOUSE_ADJUST_NOT_EXISTS);
        }

        String note = "";
        // 转异
        Long orderId = orderWarehouseAdjustDO.getOrderId();
        String manualExceptionType = arrivedVO.getManualExceptionType();
        if (StringUtils.isNotEmpty(manualExceptionType)) {

            OrderDO orderDO = orderService.getById(orderId);
            // 异常
            String descZh = getDesc(arrivedVO, manualExceptionType, 0);
            String descEn = getDesc(arrivedVO, manualExceptionType, 1);

            OrderExceptionCreateReqVO orderExceptionCreateReqVO = genOrderException(orderId, null, orderDO,
                    OrderExceptionEnum.ORDER_OTHER_EXCEPTION,
                    descZh, descEn, arrivedVO.getExceptionUrls());
            orderExceptionService.createOrderException(orderExceptionCreateReqVO);

            note = "-转异";
        }

        boolean isUpdateOrderLocation = false;
        // 储位信息 删除老储位
        orderLocationService.deleteIfPresent(orderId, null, null);
        // 新增新储位
        List<OrderLocationCreateReqVO> orderLocationCreateReqVOList = arrivedVO.getOrderLocationCreateReqVOList();

        //调仓到仓储位还是针对订单，但修改后要同步到所有入仓记录
        List<OrderWarehouseInDO> orderWarehouseInDOList = orderWarehouseInService.getOrderWarehouseInList(new OrderWarehouseInQueryVO().setOrderId(orderId));
        if (CollectionUtil.isNotEmpty(orderWarehouseInDOList)) {

            Long loginUserId = WebFrameworkUtils.getLoginUserId();

            if (CollectionUtil.isNotEmpty(orderLocationCreateReqVOList)) {

                isUpdateOrderLocation = true;

                for (OrderWarehouseInDO orderWarehouseInDO : orderWarehouseInDOList) {
                    List<OrderLocationDO> orderLocationDOList = orderLocationCreateReqVOList.stream().map(orderLocationCreateReqVO -> new OrderLocationDO().setOrderId(orderId)
                            .setWareId(orderLocationCreateReqVO.getWareId())
                            .setAreaId(orderLocationCreateReqVO.getAreaId())
                            .setLocationId(orderLocationCreateReqVO.getLocationId())
                            .setOrderItemId(orderWarehouseInDO.getOrderItemId())
                            .setWarehouseInId(orderWarehouseInDO.getId())
                            .setAdminId(loginUserId)).collect(Collectors.toList());

                    orderLocationService.saveBatch(orderLocationDOList);
                }
            }

            //更新orderItem的入仓纪录
            Set<Long> orderItemIdSet = orderWarehouseInDOList.stream().map(OrderWarehouseInDO::getOrderItemId).collect(Collectors.toSet());
            orderItemService.updateOrderItemWarehouseInInfoLocation(orderId, orderItemIdSet);
        }

        // 已到仓状态
        orderWarehouseAdjustDO.setStatus(OrderWarehouseAdjustStatusEnum.arrivals.getValue());
        //备注
        orderWarehouseAdjustDO.setArrivalRemark(arrivedVO.getArrivalRemark());
        //到仓时间
        orderWarehouseAdjustDO.setArrivalDate(arrivedVO.getArrivalDate());
        // 更新
        warehouseAdjustMapper.updateById(orderWarehouseAdjustDO);

        // 更新订单状态 5 - 已入仓  16 已卸柜
        OrderDO orderDO = orderService.getById(orderId);
        orderService.updateStatus(orderId, null, orderDO.getOldStatus(), null, OrderWarehouseInStatusEnum.adjust_finished.getValue(), null, null, null, false);

        // 到仓影像
        orderWarehousePictureService.createWarehousePictureBatch(arrivedVO.getUrls(), 3, orderWarehouseAdjustDO.getId());

        //纪录操作日志
        orderBusinessService.addOrderOperateLog(orderWarehouseAdjustDO.getOrderId(), "仓库操作", "调仓到仓" + note, "");
        if (isUpdateOrderLocation) {
            orderBusinessService.addOrderOperateLog(orderWarehouseAdjustDO.getOrderId(), "仓库操作", "调仓到仓调整储位", "");
        }

    }



    private String getDesc(OrderWarehouseAdjustArrivedVO arrivedVO, String manualExceptionType, Integer lang) {
        StringBuffer stringBuffer = new StringBuffer();
        for (String value : manualExceptionType.split(",")) {
            DictDataRespDTO data = DictFrameworkUtils.getDictDataFromCache("manual_exception_type", value);
            if (data != null) {
                if (StringUtils.isNotEmpty(stringBuffer)) {
                    stringBuffer.append(",");
                }
                stringBuffer.append(lang == 0 ? data.getLabel() : data.getLabelEn());
            }
        }
        if (StringUtils.isNotEmpty(stringBuffer)) {
            stringBuffer.append(": ");
        }
        stringBuffer.append(lang == 0 ? arrivedVO.getDescZh() : arrivedVO.getDescEn());
        return stringBuffer.toString();
    }

    private OrderExceptionCreateReqVO genOrderException(Long orderId, Long orderItemId, OrderDO orderDO, OrderExceptionEnum orderSuperfluousBoxException, String descZh, String descEn, List<String> exceptionUrls) {
        OrderExceptionCreateReqVO orderExceptionCreateReqVO = new OrderExceptionCreateReqVO();
        orderExceptionCreateReqVO.setOrderId(orderId);
        orderExceptionCreateReqVO.setOrderItemId(orderItemId);
        orderExceptionCreateReqVO.setOrderNumber(orderDO.getOrderNo());
        orderExceptionCreateReqVO.setOrderExceptionType(orderSuperfluousBoxException.getKey());
        orderExceptionCreateReqVO.setOrderExceptionDescVO(OrderExceptionDescVO.builder().descZh(descZh).descEn(descEn).build());
        if (CollectionUtil.isNotEmpty(exceptionUrls)) {
            orderExceptionCreateReqVO.setOrderExceptionAttr(CollectionUtil.join(exceptionUrls, ","));
        }
        return orderExceptionCreateReqVO;
    }


    @Override
    public void deleteWarehouseAdjust(Long id) {
        // 校验存在
        this.validateWarehouseAdjustExists(id);
        // 删除
        warehouseAdjustMapper.deleteById(id);
    }

    private void validateWarehouseAdjustExists(Long id) {
        if (warehouseAdjustMapper.selectById(id) == null) {
            throw exception(WAREHOUSE_ADJUST_NOT_EXISTS);
        }
    }

    @Override
    public OrderWarehouseAdjustDO getWarehouseAdjust(Long id) {
        return warehouseAdjustMapper.selectById(id);
    }

    @Override
    public List<OrderWarehouseAdjustBackVO> getWarehouseAdjustByOrderId(Long orderId, Integer lang) {
        List<OrderWarehouseAdjustDO> orderWarehouseAdjustDOList = warehouseAdjustMapper.selectByOrderId(orderId, lang);

        List<OrderWarehouseAdjustBackVO> convert = OrderWarehouseAdjustConvert.INSTANCE.convertList(orderWarehouseAdjustDOList);
        return convert;
    }

    @Override
    public List<OrderWarehouseAdjustDO> getWarehouseAdjustList(Collection<Long> ids) {
        return warehouseAdjustMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderWarehouseAdjustDO> getWarehouseAdjustPage(OrderWarehouseAdjustQueryVO query, PageVO page) {
        return warehouseAdjustMapper.selectPage(page, query);
    }

    @Override
    public List<OrderWarehouseAdjustDO> getWarehouseAdjustList(OrderWarehouseAdjustQueryVO query) {
        return warehouseAdjustMapper.selectList(query);
    }
}
