package com.youchain.businessdata.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.StockService;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.service.*;
import com.youchain.exception.BadRequestException;
import com.youchain.modules.quartz.utils.TimeNumberUtils;
import com.youchain.modules.system.domain.Dict;
import com.youchain.modules.system.repository.DictRepository;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class KMReServiceImpl implements KMReService {
    private final DictRepository dictRepository;
    private final PickService pickService;
    private final StockService stockService;
    private final PointService pointService;
    private final AsnDetailService asnDetailService;
    private final TaskService taskService;
    private final AgvTaskService agvTaskService;
    private final InventoryService inventoryService;
    private final InventoryLogService inventoryLogService;
    private final StockTypeToAreaMap stockTypeToAreaMap;


    /**
     * 容器入场Json
     *
     * @param containerCode 容器编号
     * @param position      点位
     */
    @Override
    public String containerInJson(String containerCode, String position) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        //请求 id
        jsonObject.put("requestId", String.valueOf(System.currentTimeMillis()));
        //容器类型
        jsonObject.put("containerType", "");
        //容器编号
        jsonObject.put("containerCode", containerCode);
        //容器当前位置
        jsonObject.put("position", position);
        //角度
        jsonObject.put("enterOrientation", "");
        return jsonObject.toString();
    }

    /**
     * 容器入场
     *
     * @param containerCode 容器
     * @param position      点位
     * @param itemCode      物料
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void containerIn(String containerCode, String position, String itemCode) {
        //验证容器是否存在
        Stock stock = stockService.validateStock(containerCode);

        //验证点位是否存在
        Point point = pointService.validatePoint(position);

        //入空车
        this.handleEmptyContainer(stock, point);

        //下发任务
        this.sendAgvTaskToContainer(UrlApi.containerIn(), this.containerInJson(containerCode, position));
    }

    /**
     * 容器出场Json
     *
     * @param containerCode 容器编号
     */
    @Override
    public String containerOutJson(String containerCode) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        //请求 id
        jsonObject.put("requestId", String.valueOf(System.currentTimeMillis()));
        //容器类型
        jsonObject.put("containerType", "");
        //容器编号
        jsonObject.put("containerCode", containerCode);
        //容器当前位置
        jsonObject.put("position", "");
        return jsonObject.toJSONString();
    }

    /**
     * 容器出场
     *
     * @param containerCode 容器
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void containerOut(String containerCode) {
        //验证容器
        Stock stock = stockService.validateStock(containerCode);

        //清空库存
        inventoryService.clearInventory(stock);

        //释放点位
        Point point = stock.getPoint();
        if (point != null) {
            pointService.freePoint(point);
        }

        //释放容器
        stockService.usedStock(stock, null, BaseStatus.FREE);

        //下发任务
        this.sendAgvTaskToContainer(UrlApi.containerOut(), this.containerOutJson(containerCode));

    }

    /**
     * 入空车
     *
     * @param stock 容器
     * @param point 点位
     */
    public void handleEmptyContainer(Stock stock, Point point) {
        //占用点位
        pointService.usedPoint(point);

        //占用容器
        stockService.usedStock(stock, point, BaseStatus.FREE);
    }


    /**
     * 下发容器入场或容器出场
     *
     * @param url  接口地址
     * @param json 接口json
     */
    @Override
    public synchronized void sendAgvTaskToContainer(String url, String json) {
        Dict dict = dictRepository.findDictByDescription("OPEN");
        if (dict != null) {
            String resultJson = HttpPostUtil.sendPostReq(url, json);
            if (StringUtils.isEmpty(resultJson)) {
                throw new RuntimeException("AGV返回信息:接口调用失败!");
            }
            JSONObject resultObject = JSON.parseObject(resultJson);
            if (resultObject == null) {
                throw new RuntimeException("AGV返回信息:接口数据返回为空!");
            }
            String code = resultObject.getString("code");
            String message = resultObject.getString("message");
            if (!"0".equals(code)) {
                throw new RuntimeException("AGV返回信息:接口调用失败!" + message);
            }
        }

    }

    /**
     * 叉车任务Json
     *
     * @param agvTasks 任务
     */
    @Override
    public synchronized String sendAgvTaskCcJson(AgvTask agvTasks) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());

        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", agvTasks.getId());//库存组织 ID
        objMap.put("requestId", agvTasks.getId());//请求 id
        objMap.put("missionCode", agvTasks.getId());//任务编号
        objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
        objMap.put("viewBoardType", "");//
        objMap.put("containerCode", agvTasks.getStockCode());//
        objMap.put("robotType", "FORKLIFT");//机器人功能类型
        objMap.put("priority", "1");//数值越小，优先级越高，默认是 1
        JSONArray missionDataArray = new JSONArray();
        JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
        missionDataMap.put("sequence", 1);//序号
        missionDataMap.put("position", agvTasks.getStartSlotCode());//点位
        String nodeType = "NODE_POINT";
        if (BizStatus.PICK.equals(agvTasks.getType())) {
            nodeType = "NODE_SLOT";
        }
        missionDataMap.put("nodeType", nodeType);//
        missionDataMap.put("stackNumber", 0);
        missionDataMap.put("actionConfirm", false);
        missionDataObj.putAll(missionDataMap);
        missionDataArray.add(missionDataObj);

        JSONObject missionDataObj2 = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
        missionDataMap2.put("sequence", 2);//序号
        missionDataMap2.put("position", agvTasks.getEndSlotCode());//目标点
        String nodeType2 = "NODE_SLOT";
        if (BizStatus.PICK.equals(agvTasks.getType())) {
            nodeType2 = "NODE_POINT";
        }
        missionDataMap2.put("nodeType", nodeType2);//
        missionDataMap2.put("stackNumber", 0);
        missionDataMap2.put("actionConfirm", false);
        missionDataObj2.putAll(missionDataMap2);
        missionDataArray.add(missionDataObj2);

        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        return jsonObject.toJSONString();
    }

    /**
     * 货架任务Json
     *
     * @param agvTasks 任务
     */
    @Override
    public synchronized String sendAgvTaskHjJson(AgvTask agvTasks) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());

        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", agvTasks.getId());//库存组织 ID
        objMap.put("requestId", agvTasks.getId());//请求 id
        objMap.put("missionCode", agvTasks.getId());//任务编号
        objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
        objMap.put("viewBoardType", "");//IDENTIFY_REQUIRE
        objMap.put("robotType", "LIFT");//机器人功能类型
        objMap.put("priority", "1");//数值越小，优先级越高，默认是 1
        JSONArray missionDataArray = new JSONArray();
        JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
        missionDataMap.put("sequence", 1);//序号
        missionDataMap.put("containerCode", agvTasks.getStockCode());//容器
        missionDataMap.put("startPosition", agvTasks.getStartSlotCode());//点位
        missionDataMap.put("startPositionType", "NODE_POINT");//
        missionDataMap.put("endPosition", agvTasks.getEndSlotCode());//点位
        missionDataMap.put("endPositionType", "NODE_POINT");//
        missionDataObj.putAll(missionDataMap);
        missionDataArray.add(missionDataObj);

        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        return jsonObject.toJSONString();
    }

    @Override
    public synchronized String sendAgvTaskGtJson(AgvTask agvTask) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", agvTask.getId());//库存组织 ID(或工厂代码，供应商代码)
        objMap.put("requestId", agvTask.getId());//请求 id
        objMap.put("missionCode", agvTask.getId());//任务编号
        objMap.put("missionType", "ROLLER_MOVE");//任务类型 ：滚筒
        objMap.put("viewBoardType", "");//上视识别类型:
        objMap.put("robotType", "ROLLER");
        objMap.put("priority", "1");
        objMap.put("lockRobotAfterFinish", false);
        JSONArray missionDataArray = new JSONArray();

        JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
        missionDataMap.put("sequence", 1);//序号
        missionDataMap.put("position", agvTask.getStartSlotCode());//起点
        missionDataMap.put("type", "NODE_POINT");//
        missionDataMap.put("actionType", "ROLLER_RECEIVE");//
        missionDataMap.put("binCode", "");//容器
        missionDataMap.put("rollerLevel", 1);//
        missionDataMap.put("deviceCode", agvTask.getStartSlotCode());//设备编号
        missionDataMap.put("actionConfirm", true);//
        missionDataMap.put("passStrategy", "AUTO");//
        missionDataObj.putAll(missionDataMap);
        missionDataArray.add(missionDataObj);

        JSONObject missionDataObj2 = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
        missionDataMap2.put("sequence", 2);//序号
        missionDataMap2.put("position", "FX001");//中转点
        missionDataMap2.put("type", "NODE_POINT");//
        missionDataMap2.put("actionType", "");//
        missionDataMap2.put("binCode", "");//容器
        missionDataMap2.put("rollerLevel", 1);//
        missionDataMap2.put("deviceCode", "");//
        missionDataMap2.put("actionConfirm", false);//
        missionDataMap2.put("passStrategy", "MANUAL");//
        missionDataObj2.putAll(missionDataMap2);
        missionDataArray.add(missionDataObj2);

        JSONObject missionDataObj3 = new JSONObject(new LinkedHashMap<>());
        Map<String, Object> missionDataMap3 = new LinkedHashMap<>();
        missionDataMap3.put("sequence", 3);//序号
        missionDataMap3.put("position", agvTask.getEndSlotCode());//终点
        missionDataMap3.put("type", "NODE_POINT");//
        missionDataMap3.put("actionType", "ROLLER_SEND");//
        missionDataMap3.put("binCode", "");//容器
        missionDataMap3.put("rollerLevel", 1);//
        missionDataMap3.put("deviceCode", agvTask.getEndSlotCode());//终点
        missionDataMap3.put("actionConfirm", true);//
        missionDataMap3.put("passStrategy", "AUTO");//
        missionDataObj3.putAll(missionDataMap3);
        missionDataArray.add(missionDataObj3);

        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        return jsonObject.toJSONString();
    }

    @Override
    public synchronized void sendAgvTask(AgvTask agvTasks, String json) {
        Dict dict = dictRepository.findDictByName("OPEN");
        String resultJson = "";
        if (dict != null) {
            resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), json);
            if (StringUtils.isEmpty(resultJson)) {
                throw new BadRequestException("AGV返回信息:下发任务接口调用失败!");
            }
            JSONObject resulObject = JSON.parseObject(resultJson);
            if (resulObject == null) {
                throw new BadRequestException("AGV返回信息:下发任务接口返回为空!");
            }

            String code = resulObject.getString("code");
            String message = resulObject.getString("message");
            if (!"0".equals(code)) {
                throw new BadRequestException("AGV返回消息:" + message);
            }
        }

        agvTasks.setJobForce(agvTasks.getId().toString());
        agvTasks.setJobForceAsc((1));
        agvTasks.setStatus(BizStatus.ATCALL);
        agvTasks.setJobMessage(resultJson);
        agvTasks.setReqMessage(json);
        agvTasks.setStartTime(new Timestamp(System.currentTimeMillis()));
        agvTaskService.update(agvTasks);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void missionStateCallback(AgvTask agvTask, String status, String containerCode) {
        Stock stock = stockService.findByCode(containerCode);
        //顶升的是起点；其它终点；
        Point point;
        String pointCode;
        if ("UP_CONTAINER".equals(status) || "FORK_UP".equals(status)) {
            pointCode = agvTask.getStartSlotCode();
        } else {
            pointCode = agvTask.getEndSlotCode();
        }
        point = pointService.queryPoint(pointCode, null, null, null);
        switch (status) {
            case "UP_CONTAINER":
            case "FORK_UP":
                handleUpContainer(agvTask, stock, point);//容器顶升
                break;
            case "FORK_DOWN":
                handleForkDownContainer(agvTask, stock);//容器放下
                break;
            case "COMPLETED":
                handleComContainer(agvTask, stock, point);//搬运任务完成
                break;
            case "CANCELED":
                handleCanceledTask(agvTask, stock, point);//容器取消
                break;
            case "RESEND":
                handleResendTask(agvTask);//重新发送
                break;
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void returnFBAgvTask(Point srcPoint, Stock stock, Item item) {
        String areaCode = stockTypeToAreaMap.getValueByKey(item.getGoodType());

        //获取终点
        List<Point> endPointList = pointService.queryPoints(null, BaseStatus.FREE, BaseStatus.STORAGE, areaCode);
        if (endPointList.isEmpty()) {
            throw new BadRequestException(areaCode + "没有空闲点位!");
        }
        Point endPoint = endPointList.get(0);

        //创建任务
        AgvTask agvTask = agvTaskService.createAgvTask(BizStatus.FB_RETURN, stock, srcPoint.getCode(), endPoint.getCode(), "FORKLIFT_MOVE");

        //点位占用
        pointService.usedPoint(endPoint);

        //下发任务
        this.sendAgvTask(agvTask, this.sendAgvTaskCcJson(agvTask));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void operationFeedback(String code) {

    }

    /**
     * 容器顶升
     *
     * @param agvTask 任务
     * @param stock   容器
     */
    private void handleUpContainer(AgvTask agvTask, Stock stock, Point startPoint) {
        //翻包返库时，起点有多条容器任务则释放点位 否则释放点位

        if (BizStatus.FB_RETURN.equals(agvTask.getType())) {
            //查询起点是否还有未完成的任务
            int count = agvTaskService.existsBySrcPoint(agvTask.getId(), startPoint.getCode());
            if (count == 0) {
                pointService.freePoint(startPoint);
            }
        } else {
            pointService.freePoint(startPoint);
        }

        agvTask.setStockCode(stock == null ? null : stock.getCode());
        agvTask.setStatus(BizStatus.UP_CONTAINER);
        agvTaskService.update(agvTask);

    }

    /**
     * 容器放下
     *
     * @param agvTask 任务
     * @param stock   容器
     */
    private void handleForkDownContainer(AgvTask agvTask, Stock stock) {
        switch (agvTask.getType()) {
            case BizStatus.ASN:
                List<Task> taskList = taskService.findTaskByAgvTask(agvTask.getId());
                //原材料入库
                this.handleXJDJ(taskList, stock);
                break;
            case BizStatus.FB_RETURN:
                //翻包返库
                this.handleFbReturn(agvTask, stock);
                break;
        }
        //更新状态
        this.updateAgvTaskStatus(agvTask, stock, BizStatus.FINISH);
    }

    /**
     * 任务完成
     *
     * @param agvTask 任务
     * @param stock   容器
     */
    private void handleComContainer(AgvTask agvTask, Stock stock, Point endPoint) {
        //任务完成；根据AGV任务的目标点位走对应流程
        switch (agvTask.getType()) {
            case BizStatus.PICK:
                handleFbq(stock, endPoint, agvTask);//备料完成
                break;
            case BizStatus.CALL_PICK:
                handleJl(stock, endPoint, agvTask);//叫料完成
                break;
            case BizStatus.CALL_RETURN:
            case BizStatus.Cp_Off_Up:
                handleJlFkAndCpSx(endPoint, stock);//叫料返空完成;成品上线完成
                break;
            case BizStatus.Cp_Off_Line:
                handleCpOffLine(endPoint, stock);//成品下线完成
                break;
            case BizStatus.Fx_Off_Line:
                handleFxOffLine(agvTask);//返修
                break;
        }

        //更新任务状态
        this.updateAgvTaskStatus(agvTask, stock, BizStatus.FINISH);

    }

    /**
     * 任务取消完成
     *
     * @param agvTask 任务
     * @param stock   容器
     */
    private void handleCanceledTask(AgvTask agvTask, Stock stock, Point endPoint) {
        if (BizStatus.ASN.equals(agvTask.getType())) {
            //取消入库
            handleFBFCCancel(agvTask, endPoint, stock);
        }

        //更新任务状态
        this.updateAgvTaskStatus(agvTask, stock, BizStatus.CANCEL);


    }

    /**
     * 重新发送任务
     *
     * @param agvTask 任务
     */
    private synchronized void handleResendTask(AgvTask agvTask) {
        List<AgvTask> repeatList = agvTaskService.findRepeat(agvTask.getStockCode(), agvTask.getStartSlotCode(), agvTask.getEndSlotCode());
        if (!repeatList.isEmpty()) {
            throw new BadRequestException("任务已重新生成，请勿重复操作! ");
        }
        AgvTask newAgvTask = new AgvTask();
        newAgvTask.setStockCode(agvTask.getStockCode());
        newAgvTask.setStartSlotCode(agvTask.getStartSlotCode());
        newAgvTask.setEndSlotCode(agvTask.getEndSlotCode());
        newAgvTask.setSlotCode(agvTask.getSlotCode());
        newAgvTask.setStatus(BizStatus.OPEN);
        newAgvTask.setType(agvTask.getType());
        newAgvTask.setJobType(agvTask.getJobType());
        newAgvTask.setJobPriority(1);
        newAgvTask.setLineSlotCode(agvTask.getLineSlotCode());
        agvTaskService.create(newAgvTask);

        List<Task> taskList;
        if (BizStatus.CALL_PICK.equals(agvTask.getType())) {
            taskList = taskService.findTaskByCallAgvTask(agvTask.getId());
        } else {
            taskList = taskService.findTaskByAgvTask(agvTask.getId());
        }
        for (Task task : taskList) {
            if (BizStatus.CALL_PICK.equals(agvTask.getType())) {
                task.setCallAgvTaskId(newAgvTask.getId());
            } else {
                task.setAgvTask(newAgvTask);
            }
            taskService.update(task);
        }


        // 根据任务类型发送不同的实现
        switch (agvTask.getJobType()) {
            case "FORKLIFT_MOVE":
                sendAgvTask(newAgvTask, sendAgvTaskCcJson(newAgvTask));
                break;
            case "RACK_MOVE":
                sendAgvTask(newAgvTask, sendAgvTaskHjJson(newAgvTask));
                break;
            case "ROLLER_MOVE":
                sendAgvTask(newAgvTask, sendAgvTaskGtJson(newAgvTask));
                break;
            default:
                throw new BadRequestException("任务类型不支持: " + agvTask.getJobType());
        }


    }

    /**
     * 入库取消
     *
     * @param agvTask  任务
     * @param endPoint 点位
     * @param stock    容器
     */
    private void handleFBFCCancel(AgvTask agvTask, Point endPoint, Stock stock) {
        //回存储区取消任务，不生成库存 入库任务取消即可
        List<Task> taskList = taskService.findTaskByAgvTask(agvTask.getId());
        for (Task task : taskList) {
            AsnDetail ad = task.getAsnDetail();
            ad.setStatus(BizStatus.CANCEL);
            asnDetailService.update(ad);

            task.setTaskStatus(BizStatus.CANCEL);
            taskService.update(task);
        }
        //起点点位释放
        Point srcPoint = pointService.queryPoint(agvTask.getStartSlotCode(), null, null, null);
        pointService.freePoint(srcPoint);

        //容器释放
        stockService.usedStock(stock, srcPoint, BaseStatus.FREE);

        //线边点位释放
        pointService.freePoint(endPoint);
    }


    /**
     * 备料完成
     *
     * @param stock    容器
     * @param endPoint 点位
     * @param agvTask  任务
     */
    private void handleFbq(Stock stock, Point endPoint, AgvTask agvTask) {
        //将托盘上所有箱号移动到备料库位;
        List<Inventory> inventoryList = inventoryService.findByStockCode(stock.getCode());
        for (Inventory inventory : inventoryList) {
            inventory.setPoint(endPoint);
            inventory.setPointCode(endPoint.getCode());
            inventoryService.update(inventory);
        }
        List<Task> taskList = taskService.findTaskByAgvTask(agvTask.getId());
        for (Task task : taskList) {
            //更新Task任务状态
            task.setTaskStatus(BizStatus.ARRIVED);
            taskService.update(task);
        }

        //终点占用
        pointService.usedPoint(endPoint);

        //容器占用
        stockService.usedStock(stock, endPoint, BaseStatus.USED);

    }

    /**
     * 叫料完成
     *
     * @param stock 容器
     */
    private void handleJl(Stock stock, Point endPoint, AgvTask agvTask) {

        List<Task> taskList = taskService.findTaskByCallAgvTask(agvTask.getId());
        for (Task task : taskList) {
            inventoryService.deleteAll(new Long[]{task.getInvId()});
        }

        //点位占用
        pointService.usedPoint(endPoint);

        //容器占用
        stockService.usedStock(stock, endPoint, BaseStatus.USED);

        Pick pick = pickService.findByPickCode(agvTask.getLineSlotCode());
        if (pick != null) {
            pick.setStatus(BizStatus.CLOSE);
            pickService.update(pick);
        }

        //回传MES

    }

    /**
     * 叫料返空完成;成品上线完成
     *
     * @param endPoint 点位
     * @param stock    容器
     */
    private void handleJlFkAndCpSx(Point endPoint, Stock stock) {

        //终点占用
        pointService.usedPoint(endPoint);

        //容器占用
        stockService.usedStock(stock, endPoint, BaseStatus.FREE);
    }

    /**
     * 成品下线完成
     *
     * @param endPoint 点位
     * @param stock    容器
     */
    private void handleCpOffLine(Point endPoint, Stock stock) {
        //终点占用
        pointService.usedPoint(endPoint);

        //容器占用
        stockService.usedStock(stock, endPoint, BaseStatus.USED);
    }

    private void handleFxOffLine(AgvTask agvTask) {
        this.updateAgvTaskStatus(agvTask, null, BizStatus.FINISH);
    }

    /**
     * 满车入库
     *
     * @param taskList 任务列表
     * @param stock    容器
     */
    private void handleXJDJ(List<Task> taskList, Stock stock) {

        //清空库存
        inventoryService.clearInventory(stock);

        for (Task task : taskList) {
            //更新入库明细
            AsnDetail ad = task.getAsnDetail();
            ad.setReceivedQty(ad.getOrderQty());
            ad.setStatus(BizStatus.RECEIVED);
            ad.setStock(stock);
            asnDetailService.update(ad);

            //更新入库任务
            task.setTaskStatus(BizStatus.FINISH);
            task.setMoveQty(task.getPlanQty());
            task.setSrcStock(stock);
            task.setDstStock(stock);
            taskService.update(task);

            //新增库存
            Inventory inventory = inventoryService.createInventory(task.getItemKey(), task.getDstPoint(), stock, stock.getDept(), ad.getOrderQty());

            //点位占用
            pointService.usedPoint(task.getDstPoint());

            //占用容器
            stockService.usedStock(stock, task.getDstPoint(), BaseStatus.USED);

            //新增日志
            inventoryLogService.createInventoryLog(BizStatus.RECEIVING_UP, BizStatus.ADD, null, task.getItemKey(), task.getSrcPoint(), task.getDstPoint(), task.getSrcStock(), task.getSrcStock(), 0d, task.getPlanQty(), BizStatus.ASN, ad.getId(), inventory.getId(), ad.getRemark());

        }


    }

    /**
     * 翻包返库
     *
     * @param agvTask 任务
     * @param stock   容器
     */
    private void handleFbReturn(AgvTask agvTask, Stock stock) {
        Point endPoint = pointService.queryPoint(agvTask.getEndSlotCode(), null, null, null);
        List<Inventory> inventoryList = inventoryService.queryInventory(stock.getId(), null, null, null, stock.getDept().getId());
        if (inventoryList.isEmpty()) {

            //终点占用
            pointService.usedPoint(endPoint);

            //占用容器
            stockService.usedStock(stock, endPoint, BaseStatus.FREE);
        } else {
            for (Inventory inventory : inventoryList) {
                inventory.setPoint(endPoint);
                inventory.setPointCode(endPoint.getCode());
                inventoryService.update(inventory);
            }

            //终点占用
            pointService.usedPoint(endPoint);

            //占用容器
            stockService.usedStock(stock, endPoint, BaseStatus.USED);
        }

    }

    /**
     * 更新任务状态
     *
     * @param agvTask 任务
     * @param stock   容器
     * @param status  状态
     */
    private void updateAgvTaskStatus(AgvTask agvTask, Stock stock, String status) {
        agvTask.setStockCode(stock == null ? null : stock.getCode());
        agvTask.setStatus(status);
        agvTask.setEndTime(new Timestamp(new Date().getTime()));
        agvTaskService.update(agvTask);
    }
}
