package com.wms.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms.annotation.MyLog;
import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.PageDto;
import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.app.request.ExceptionStockHandleRequest;
import com.wms.entity.app.request.StockQuery;
import com.wms.entity.app.request.StockUpdateRecordQuery;
import com.wms.entity.app.vo.StockUpdateRecordVo;
import com.wms.entity.app.vo.StockVo;
import com.wms.entity.app.wcs.WcsStandTaskRequest;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import com.wms.utils.WmsUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.wms.config.InitLocalConfig.configMap;
import static com.wms.constants.WmsConstants.MYSQL_JSON_CI;
import static com.wms.utils.StringUtils.convertJsonString;

/**
 * WMS库存控制类
 *
 * @author 梁州
 * &#064;date  2023/2/14
 */
@Controller
@CrossOrigin
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/wms/stock")
public class StockController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 库存服务
     */
    private final StockService stockService;
    /**
     * 库存更新记录服务
     */
    private final IStockUpdateRecordService stockUpdateRecordService;
    /**
     * 库位服务
     */
    private final LocationService locationService;
    /**
     * 料箱服务
     */
    private final VehicleService vehicleService;
    /**
     * 拣选任务服务
     */
    private final PickTaskService pickTaskService;
    /**
     * 流转料箱服务
     */
    private final OutsideVehiclesService outsideVehiclesService;
    /**
     * 站台要料服务
     */
    private final GoodsToStationService goodsToStationService;
    /**
     * 日志服务
     */
    private final LogService logService;
    /**
     * 工作流服务
     */
    private final WorkFlowService workFlowService;
    /**
     * 请求头部信息
     */
    private final HttpServletRequest servletRequest;

    /**
     * 查找所有物料
     */
    @PostMapping("/getAllStocks")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getAllStocks(@RequestBody StockQuery stockQuery) {
        logger.info("接收到查询库存数据请求：{}，请求ip：{}", convertJsonString(stockQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            Page<Stock> page = stockQuery.toMpPage();
            Page<Stock> stockPage = stockService.page(page, new LambdaQueryWrapper<Stock>()
                    .like(StringUtils.isNotEmpty(stockQuery.getVehicleId()), Stock::getVehicleId, stockQuery.getVehicleId())
                    .like(StringUtils.isNotEmpty(stockQuery.getLocationId()), Stock::getLocationId, stockQuery.getLocationId())
                    .eq(stockQuery.getStockStatus() != null, Stock::getStockStatus, stockQuery.getStockStatus())
                    .apply(StringUtils.isNotEmpty(stockQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')" + MYSQL_JSON_CI, stockQuery.getGoodsId())
                    .apply(StringUtils.isNotEmpty(stockQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')" + MYSQL_JSON_CI, stockQuery.getGoodsName())
                    .orderByDesc(Stock::getLastUpdateTime));

            PageDto<StockVo> pageDto = PageDto.of(stockPage, StockVo::of);
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询库存成功");
            response.setReturnData(pageDto);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询库存发生异常：{}", convertJsonString(e));
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询库存发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 查询某个物料的库存总数
     */
    @PostMapping("/getStockNumByGoodsId")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public String getStockNumByGoodsId(@RequestBody StockQuery stockQuery) {
        logger.info("接收到查询物料库存总数请求：{}，请求ip：{}", convertJsonString(stockQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(stockQuery.getGoodsId())) {
                logger.error("查询料号不允许为空");
                response.setCode(ResponseCode.ERROR.getCode());
                response.setMessage("查询料号不允许为空");
                return convertJsonString(response);
            }
            // 返回实体
            StockVo stockVo = new StockVo();
            stockVo.setGoodsId(stockQuery.getGoodsId());
            // 查询库存
            List<Stock> stocks = stockService.list(new LambdaQueryWrapper<Stock>()
                    .apply(StringUtils.isNotEmpty(stockQuery.getGoodsId()), "goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, stockQuery.getGoodsId()));
            if (stocks == null || stocks.isEmpty()) {
                // 没有库存
                stockVo.setRemainNum(BigDecimal.ZERO);
                logger.info("物料{}无库存", stockQuery.getGoodsId());
            } else {
                BigDecimal sumNum = BigDecimal.ZERO;
                for (Stock stock : stocks) {
                    sumNum = sumNum.add(stock.getGoodsRelated().getRemainNum());
                }
                // 设定数量
                stockVo.setRemainNum(sumNum);
                logger.info("物料{}无库存", stockQuery.getGoodsId());
            }
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询物料" + stockQuery.getGoodsId() + "库存数量成功");
            response.setReturnData(stockVo);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询物料库存发生异常：{}", convertJsonString(e));
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询物料库存发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 更新库存信息
     *
     * @param stockQuery 库存
     * @return 结果
     */
    @PostMapping("/updateStockInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新库存信息", logMethod = "updateStockInfo")
    public String updateStockInfo(@RequestBody StockQuery stockQuery) {
        logger.info("接收到更新库存信息请求：{}，请求ip：{}", convertJsonString(stockQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(stockQuery.getStockId())) {// 库存编号为空，不允许执行
                logger.error("请求的库存编号为空，不允许修改");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求的库存编号为空，不允许修改");
                return convertJsonString(rsp);
            }
            LambdaQueryWrapper<Stock> stockLambdaQueryWrapper = new LambdaQueryWrapper<Stock>().eq(Stock::getStockId, stockQuery.getStockId());
            // 查询原有库存
            Stock stockBefore = stockService.getOne(stockLambdaQueryWrapper);
            if (stockQuery.getRemainNum().compareTo(BigDecimal.ZERO) <= 0) {
                if (stockService.remove(stockLambdaQueryWrapper)) {
                    // 判断这个箱子是否变成空箱
                    if (!stockService.exists(new LambdaQueryWrapper<Stock>()
                            .eq(Stock::getVehicleId, stockBefore.getVehicleId())
                            .ne(Stock::getStockId, stockBefore.getStockId()))) {
                        vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                                .set(Vehicle::getIsEmpty, 1)
                                .eq(Vehicle::getVehicleId, stockBefore.getVehicleId())
                                .eq(Vehicle::getIsEmpty, 0));
                    }
                    stockUpdateRecordService.addStockUpdateRecord(stockBefore, null, StockUpdateReasonEnum.DELETE_CLIENT.getReason(), stockQuery.getUserName(), stockBefore.getGoodsRelated().getRemainNum());
                    // 删除这个料箱对应的outside_vehicles
                    outsideVehiclesService.remove(new LambdaQueryWrapper<OutsideVehicles>()
                            .eq(OutsideVehicles::getVehicleId, stockBefore.getVehicleId())
                            .eq(OutsideVehicles::getGoodsId, stockBefore.getGoodsRelated().getGoodsId()));
                    // 返回成功
                    logger.info("数量为0，删除库存成功");
                    rsp.setCode(ResponseCode.OK.getCode());
                    rsp.setMessage("数量为0，删除库存成功");
                } else {
                    // 返回失败
                    logger.error("数量为0，删除库存失败");
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("数量为0，删除库存失败");
                }
            } else {
                // 更新库存---只能更新一部分列
                Stock updatingStock = BeanUtil.copyProperties(stockBefore, Stock.class);
                BigDecimal quantityBefore = stockBefore.getGoodsRelated().getRemainNum();
                updatingStock.setStockStatus(stockQuery.getStockStatus());
                if (StringUtils.isNotEmpty(stockQuery.getLocationId()) && locationService.exists(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, stockQuery.getLocationId()))) {
                    updatingStock.setLocationId(stockQuery.getLocationId());
                }
                updatingStock.setLastUpdateTime(LocalDateTime.now());
                updatingStock.setLastUpdateUser(stockQuery.getUserName());
                if (StringUtils.isNotEmpty(stockQuery.getGoodsId())) {
                    StockDetailInfo goodsRelated = updatingStock.getGoodsRelated();
                    goodsRelated.setRemainNum(stockQuery.getRemainNum());
                    goodsRelated.setGoodsStatus(stockQuery.getGoodsStatus());
                    updatingStock.setGoodsRelated(goodsRelated);
                }
                // 更新库存
                if (stockService.update(updatingStock, stockLambdaQueryWrapper)) {
                    stockUpdateRecordService.addStockUpdateRecord(stockBefore, updatingStock, StockUpdateReasonEnum.UPDATE_CLIENT.getReason(), stockQuery.getUserName(), quantityBefore);
                    // 返回成功
                    logger.info("更新库存信息成功");
                    rsp.setCode(ResponseCode.OK.getCode());
                    rsp.setMessage("更新库存信息成功");
                } else {
                    // 返回失败
                    logger.error("更新库存信息失败");
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("更新库存信息失败");
                }
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("更新库存信息发生异常：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("更新库存信息发生异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 新增库存
     *
     * @param stockQuery 库存
     * @return 结果
     */
    @PostMapping("/addNewStock")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "添加库存信息", logMethod = "addNewStock")
    public String addNewStock(@RequestBody StockQuery stockQuery) {
        logger.info("接收到添加信息请求：{}，请求ip：{}", convertJsonString(stockQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            Stock stockPo = stockQuery.toStockPo();
            stockPo.setStockId(WmsUtils.generateId("ST"));
            stockPo.setCreateTime(LocalDateTime.now());
            stockPo.setLastUpdateUser(stockQuery.getUserName());
            if (stockService.save(stockPo)) {
                // 如果这个箱子本来是空箱，那么设置为非空箱
                vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                        .set(Vehicle::getIsEmpty, 0)
                        .eq(Vehicle::getVehicleId, stockPo.getVehicleId())
                        .eq(Vehicle::getIsEmpty, 1));
                stockUpdateRecordService.addStockUpdateRecord(null, stockPo, StockUpdateReasonEnum.ADD_CLIENT.getReason(), stockQuery.getUserName(), BigDecimal.ZERO);
                // 返回成功
                logger.info("添加库存信息成功");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("添加库存信息成功");
            } else {
                // 返回失败
                logger.error("添加库存信息失败");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("添加库存信息失败");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("新增库存发生异常：{}", e.getMessage());
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage(e.getMessage());
            return convertJsonString(rsp);
        }
    }

    /**
     * 查询库存更新记录
     *
     * @param stockUpdateRecordQuery 记录查询参数
     * @return 查询结果
     */
    @PostMapping("/getStockUpdateRecord")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "查询库存更新记录", logMethod = "getStockUpdateRecord")
    public String getStockUpdateRecord(@RequestBody StockUpdateRecordQuery stockUpdateRecordQuery) {
        logger.info("接收到查询库存更新记录请求：{}，请求ip：{}", convertJsonString(stockUpdateRecordQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            Page<StockUpdateRecord> page = stockUpdateRecordQuery.toMpPage();
            Page<StockUpdateRecord> recordsPage = stockUpdateRecordService.page(page, new LambdaQueryWrapper<StockUpdateRecord>()
                    .like(StringUtils.isNotEmpty(stockUpdateRecordQuery.getReason()), StockUpdateRecord::getReason, stockUpdateRecordQuery.getReason())
                    .like(StringUtils.isNotEmpty(stockUpdateRecordQuery.getVehicleId()), StockUpdateRecord::getVehicleId, stockUpdateRecordQuery.getVehicleId())
                    .like(StringUtils.isNotEmpty(stockUpdateRecordQuery.getGoodsId()), StockUpdateRecord::getGoodsId, stockUpdateRecordQuery.getGoodsId())
                    .orderByDesc(StockUpdateRecord::getUpdateTime));
            PageDto<StockUpdateRecordVo> pageDto = PageDto.of(recordsPage, updateRecord -> BeanUtil.copyProperties(updateRecord, StockUpdateRecordVo.class));
            logger.info("查询库存更新记录成功。");
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询库存更新记录成功。");
            response.setReturnData(pageDto);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询库存更新记录发生异常：{}", convertJsonString(e));
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询库存更新记录发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 处理异常库存
     *
     * @param handleRequest 请求信息
     * @return 结果
     */
    @PostMapping("/handleExceptionStock")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "处理异常库存", logMethod = "handleExceptionStock")
    public String handleExceptionStock(@RequestBody ExceptionStockHandleRequest handleRequest) {
        logger.info("接收到处理异常库存请求：{}，请求ip：{}", convertJsonString(handleRequest), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (handleRequest == null || StringUtils.isEmpty(handleRequest.getVehicleId())
                    || StringUtils.isEmpty(handleRequest.getGoodsId()) || StringUtils.isEmpty(handleRequest.getStandId())) {
                logger.error("请求参数必须参数。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求参数必须参数。");
                return convertJsonString(rsp);
            }
            // 查询到当前处理的料箱
            Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>()
                    .eq(Vehicle::getVehicleId, handleRequest.getVehicleId())
                    .last("limit 1"));
            if (currentVehicle == null) {
                logger.error("请求处理的箱子不在立体库记录中。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求处理的箱子不在立体库记录中，请根据需要在入库界面入库。");
                return convertJsonString(rsp);
            }
            // 查询到当前处理的库存
            Stock currentStock = stockService.getOne(new LambdaQueryWrapper<Stock>()
                    .eq(Stock::getVehicleId, handleRequest.getVehicleId())
                    .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, handleRequest.getGoodsId())
                    .last("limit 1"));
            if (currentStock == null) {
                logger.error("当前箱子中没有当前料号的库存。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("当前箱子中没有当前料号的库存。");
                return convertJsonString(rsp);
            }

            // 找到当前箱子当前料对应的拣选任务-->取消拣选任务
            List<PickTask> pickTasks = pickTaskService.list(new LambdaQueryWrapper<PickTask>()
                    .eq(PickTask::getVehicleId, handleRequest.getVehicleId())
                    .ne(PickTask::getPickStatus, 2));
            List<GoodsToStation> updatedGoodsToStationList = new ArrayList<>();
            if (pickTasks != null && !pickTasks.isEmpty()) {
                List<String> standIds = pickTasks.stream().map(PickTask::getStandId).distinct().toList();
                List<String> otherGoodsStandIds = new ArrayList<>();
                List<String> currentGoodsStandIds = new ArrayList<>();
                // 找出当前料箱有没有其他料也需要用
                List<OutsideVehicles> otherOutsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
                        .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
                        .ne(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()));
                if (otherOutsideVehicles != null && !otherOutsideVehicles.isEmpty()) {
                    // 找出其需要的拣选任务
                    for (OutsideVehicles outsideVehicle : otherOutsideVehicles) {
                        // 找出这个料的对应的goodsToStation
                        List<GoodsToStation> goodsToStations = goodsToStationService.list(new LambdaQueryWrapper<GoodsToStation>()
                                .eq(GoodsToStation::getGoodsId, outsideVehicle.getGoodsId()));
                        for (GoodsToStation goodsToStation : goodsToStations) {
                            // 找出这个料对应的standId
                            if (standIds.contains(goodsToStation.getWorkStation())) {
                                if (!otherGoodsStandIds.contains(goodsToStation.getWorkStation())) {
                                    otherGoodsStandIds.add(goodsToStation.getWorkStation());
                                }
                            }
                        }
                    }
                }
                // 当前料
                OutsideVehicles currentOutsideVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper<OutsideVehicles>()
                        .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
                        .eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId())
                        .last("limit 1"));
                if (currentOutsideVehicle != null) {
                    // 已经分配的数量
                    BigDecimal distributedNum = currentStock.getGoodsRelated().getRemainNum().subtract(currentOutsideVehicle.getRemainNum());
                    // 将当前物料的所有goodsToStation
                    List<GoodsToStation> goodsToStations = goodsToStationService.list(new LambdaQueryWrapper<GoodsToStation>()
                            .eq(GoodsToStation::getGoodsId, currentOutsideVehicle.getGoodsId()));
                    for (GoodsToStation goodsToStation : goodsToStations) {
                        // 找出这个料对应的standId
                        if (standIds.contains(goodsToStation.getWorkStation())) {
                            if (!currentGoodsStandIds.contains(goodsToStation.getWorkStation())) {
                                currentGoodsStandIds.add(goodsToStation.getWorkStation());
                            }
                        }
                        if (distributedNum.compareTo(BigDecimal.ZERO) > 0) {
                            // 查询这个料对应的当前站台未完成工作流
                            List<WorkFlow> workFlows = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
                                    .eq(WorkFlow::getWorkStation, goodsToStation.getWorkStation())
                                    .eq(WorkFlow::getGoodsId, goodsToStation.getGoodsId())
                                    .eq(WorkFlow::getWorkStatus, 1));
                            BigDecimal recallNum = BigDecimal.ZERO;
                            for (WorkFlow workFlow : workFlows) {
                                // 分配数量无了
                                if (distributedNum.compareTo(BigDecimal.ZERO) <= 0) {
                                    break;
                                }
                                BigDecimal needNum = workFlow.getNeedNum().subtract(workFlow.getPickedNum());
                                if (needNum.compareTo(BigDecimal.ZERO) > 0) {
                                    recallNum = recallNum.add(needNum);
                                    distributedNum = distributedNum.subtract(needNum);
                                }
                            }
                            if (recallNum.compareTo(BigDecimal.ZERO) >0) {
                                goodsToStation.setDistributedNum(goodsToStation.getDistributedNum().subtract(recallNum));
                                goodsToStation.setDistributeStatus(1);
                                updatedGoodsToStationList.add(goodsToStation);
                            }
                        }
                    }
                }
                List<String> deleteStandIds = currentGoodsStandIds.stream().filter(s -> !otherGoodsStandIds.contains(s)).toList();
                // 生成需要取消的站台任务
                WcsStandTaskRequest requestSingle = new WcsStandTaskRequest();
                requestSingle.setTaskGroup(WmsUtils.generateId(currentVehicle.getVehicleId()));
                requestSingle.setTaskType(1);
                requestSingle.setVehicleNo(currentVehicle.getVehicleId());
                requestSingle.setLocation(deleteStandIds);
                requestSingle.setRemark("站台拣选任务");
                // 发送任务
                String url = configMap.get(ConfigMapKeyEnum.URL_WCS_CANCEL_PICK_TASK.getConfigKey());
                if (url != null) {
                    logger.info("向WCS发送取消拣选任务，地址：{}，请求详情：{}", url, convertJsonString(requestSingle));
                    ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(requestSingle)), ResponseEntity.class);
                    try {
                        logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送取消拣选任务", "setConveyTask", convertJsonString(requestSingle), convertJsonString(result), url, LocalDateTime.now(), handleRequest.getUserName()));
                    } catch (Exception e) {
                        logger.error("插入日志错误。");
                    }
                    if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
                        logger.info("发送取消拣选任务成功。");
                        pickTaskService.remove(new LambdaQueryWrapper<PickTask>()
                                .eq(PickTask::getVehicleId, handleRequest.getVehicleId())
                                .in(PickTask::getStandId, deleteStandIds));
                    } else {
                        logger.error("发送取消拣选任务错误：{}", convertJsonString(result));
                        rsp.setCode(ResponseCode.ERROR.getCode());
                        String returnMessage = "发送取消拣选任务错误。";
                        if (result != null) {
                            returnMessage += result.getMessage();
                        }
                        rsp.setMessage(returnMessage);
                        return convertJsonString(rsp);
                    }
                } else {
                    logger.error("WCS发送取消拣选任务地址为空。");
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("WCS发送取消拣选任务地址为空。");
                    return convertJsonString(rsp);
                }
            }
            // 更新站台要料表
            if (!updatedGoodsToStationList.isEmpty()) {
                goodsToStationService.updateBatchById(updatedGoodsToStationList);
            }
            // 移除流转物料
            outsideVehiclesService.remove(new LambdaQueryWrapper<OutsideVehicles>()
                    .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
                    .eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()));
            // 标记料箱
            vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                    .set(Vehicle::getVehicleStatus, VehicleStatus.EXCEPTION.getCode())
                    .eq(Vehicle::getVehicleId, handleRequest.getVehicleId())
                    .ne(Vehicle::getVehicleStatus, VehicleStatus.EXCEPTION.getCode()));
            // 删除库存
            stockService.removeById(currentStock);
            // 添加库存更新记录
            stockUpdateRecordService.addStockUpdateRecord(currentStock, null, StockUpdateReasonEnum.ADD_CLIENT.getReason(), handleRequest.getUserName(), currentStock.getGoodsRelated().getRemainNum());

            logger.info("处理异常库存成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("处理异常库存成功。");
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("处理异常库存发生异常：{}", e.getMessage());
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("处理异常库存发生异常：" + e.getMessage());
            return convertJsonString(rsp);
        }
    }
}