自动化立体仓库 - WMS系统
zyx
2023-12-21 f35fc1f577af2cb76198a520f47b4c7b85fb170e
src/main/java/com/zy/asrs/service/impl/AgvWorkServiceImpl.java
@@ -1,18 +1,30 @@
package com.zy.asrs.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.param.EmptyPlateOutParam;
import com.zy.asrs.entity.param.LocDetlAdjustParam;
import com.zy.asrs.entity.param.StockOutParam;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.LocDto;
import com.zy.common.model.OrderDto;
import com.zy.common.model.StartupDto;
import com.zy.common.model.TaskDto;
import com.zy.common.service.AgvCommonService;
import com.zy.common.web.BaseController;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
@@ -32,7 +44,9 @@
    @Autowired
    private AgvBasDevpService agvBasDevpService;
    @Autowired
    private AgvLocMastService agvLockMastService;
    private AgvLocMastService agvLocMastService;
    @Autowired
    private AgvLocDetlService agvLocDetlService;
    @Autowired
    private AgvCommonService agvCommonService;
    @Autowired
@@ -41,75 +55,582 @@
    private AgvWrkDetlService agvWrkDetlService;
    @Autowired
    private MatService matService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetlService orderDetlService;
    @Autowired
    private AdjDetlService adjDetlService;
    @Autowired
    private AgvWrkMastLogService agvWrkMastLogService;
    @Autowired
    private AgvWrkDetlLogService agvWrkDetlLogService;
    @Override
    public StartupDto createWaitPainWrkMastStart(List<AgvBasDevp> agvBasDevpList, Long userId) {
    /*
    入库
     */
    @Transactional
    @Synchronized
    public StartupDto createWaitPainWrkMastStart(List<AgvBasDevp> agvBasDevpList, Long userId, boolean isConveyor) {
        Date now = new Date();
        agvBasDevpList.forEach(agvBasDevp -> {
            if(Cools.isEmpty(agvBasDevp.getBarcode())){
                throw new CoolException("选中的站点中含有位绑定托盘的站点,请重新选择");
                throw new CoolException("选中的站点中含有未绑定托盘的站点,请重新选择");
            }
            if(!"F".equals(agvBasDevp.getLocSts())){
                throw new CoolException("选中的站点中含有货位状态不为F.在库的站点,请重新选择");
            }
            List<AgvWaitPakin> agvWaitPakinList = agvWaitPakinService.selectList(new EntityWrapper<AgvWaitPakin>().eq("zpallet", agvBasDevp.getBarcode()));
            List<AgvWaitPakin> agvWaitPakinList = agvWaitPakinService.selectList(new EntityWrapper<AgvWaitPakin>().eq("supp_code", agvBasDevp.getBarcode()));
            //检索库位,选择合适的库位
            AgvLocMast agvLocMast = agvCommonService.getLocNo(agvWaitPakinList, agvBasDevp.getFloor());
            //生成工作档
            AgvWrkMast wrkMast = createWrkMast(agvBasDevp, agvLocMast, now, userId);
            AgvWrkMast wrkMast = createWrkMast(1,201L,agvBasDevp.getDevNo(),agvLocMast.getLocNo(),agvBasDevp.getBarcode(),now,userId, isConveyor);
            //标记是否为输送线入库
            wrkMast.setMk(isConveyor ? "Y" : "N");
            //生成工作档明细
            createWrkDetlReWrite(agvWaitPakinList,wrkMast,userId);
            agvWaitPakinList.forEach(wp -> {
                createWrkDetlReWrite(wp.getMatnr(),wrkMast.getWrkNo(),wp.getOrderNo(),wp.getBatch(),wp.getAnfme(),wp.getSuppCode(),now,userId,wp.getThreeCode(),wp.getDeadTime());
            });
            //更新源站点信息
            updateAgvBasDevp(agvBasDevp);
            updateAgvBasDevp(agvBasDevp,"R");
            //更新目标库位状态
            updateAgvLocMast(agvLocMast);
            updateAgvLocMast(agvLocMast,"S");
        });
        //TODO
        return null;
    }
    /*
    订单出库
     */
    @Transactional
    public void stockOutWrkMast(List<TaskDto> agvTaskDtos, Long userId) {
        Date now = new Date();
        agvTaskDtos.forEach(taskDto -> {
            List<AgvLocDetl> agvLocDetls = agvLocDetlService.selectByTaskDto(taskDto);
            //AgvLocDetl agvLocDetl = agvLocDetlService.selectOne(new EntityWrapper<AgvLocDetl>().eq("loc_no", taskDto.getLocNo()));
            //工作档所需参数
            long wrkSts = 21L;
            String sourceLocNo = taskDto.getLocNo();
            String targetLocNo = taskDto.getAgvStaNo();
            //String barcode = agvLocDetls.get(0).getSuppCode();
            String containerCode = taskDto.getLocDtos().get(0).getContainerCode();
            //判断是否全板出库
            int ioType = isPakOut(sourceLocNo,taskDto) ?  101 : 103;
            //生成工作档
            AgvWrkMast wrkMast = createWrkMast(ioType,wrkSts,sourceLocNo,targetLocNo,containerCode,now,userId,false);
            //生成工作档明细
            taskDto.getLocDtos().forEach(locDto -> {
                //明细档所需参数
                createWrkDetlReWrite(locDto.getMatnr(),
                        wrkMast.getWrkNo(),
                        locDto.getOrderNo(),
                        locDto.getBatch(),
                        locDto.getAnfme(),
                        locDto.getContainerCode(),
                        now,
                        userId,
                        locDto.getCsocode(),
                        locDto.getIsoseq());
                //修改订单信息
                modifyOrderDetl(locDto, userId);
            });
//            //修改订单信息
//            modifyOrderDetl(taskDto.getLocDtos().get(0), userId);
            //更新源站点信息
            String locSts = ioType == 101 ? "R" : "P";
            updateAgvLocMast(agvLocMastService.selectById(sourceLocNo),locSts);
            //更新目标站点状态
            //locSts = ioType == 101 ? "S" : "Q";
            updateAgvBasDevp(agvBasDevpService.selectById(targetLocNo),"S");
        });
    }
    //拣料入库
    @Transactional
    public void pickIn(List<AgvWrkMast> agvWrkMastList){
        Date now = new Date();
        agvWrkMastList.forEach(agvWrkMast -> {
            //保存拣料出库的工作档和明细
            agvWrkMastLogService.save(agvWrkMast);
            agvWrkDetlLogService.save(agvWrkMast.getWrkNo());
            //修改工作党
            agvWrkMast.setWrkSts(201L);
            //根据出库类型 设置入库类型 53拣料入库 57盘点入库
            int ioType = agvWrkMast.getIoType() == 103 ? 53 : 57;
            agvWrkMast.setIoType(ioType);
            String locNo = agvWrkMast.getLocNo();
            agvWrkMast.setLocNo(agvWrkMast.getSourceLocNo());
            agvWrkMast.setSourceLocNo(locNo);
            agvWrkMast.setIoTime(now);
            agvWrkMastService.updateById(agvWrkMast);
            List<AgvWrkDetl> agvWrkDetlList = agvWrkDetlService.selectList(new EntityWrapper<AgvWrkDetl>().eq("wrk_no", agvWrkMast.getWrkNo()));
            AgvLocMast agvLocMast = agvLocMastService.selectById(agvWrkMast.getLocNo());
            //List<AgvLocDetl> agvLocDetlList = agvLocDetlService.selectList(new EntityWrapper<AgvLocDetl>().eq("loc_no",agvLocMast.getLocNo()));
            AgvBasDevp agvBasDevp = agvBasDevpService.selectById(agvWrkMast.getSourceLocNo());
            //拣料入库
            if(ioType == 53){
                //修改工作党明细
                //agvWrkDetl.setAnfme(agvLocDetl.getAnfme() - agvWrkDetl.getAnfme());
                //agvWrkDetlService.update(agvWrkDetl,new EntityWrapper<AgvWrkDetl>().eq("wrk_no",agvWrkDetl.getWrkNo()));
                //修改库存信息
                agvWrkDetlList.forEach(agvWrkDetl -> {
                    AgvLocDetl agvLocDetl = agvLocDetlService.selectByMatnrAndBatchAndCsocodeAndisoCode(agvWrkMast.getLocNo(), agvWrkDetl.getMatnr(), agvWrkDetl.getBatch(), agvWrkDetl.getThreeCode(), agvWrkDetl.getDeadTime());
                    //AgvLocDetl agvLocDetl = agvLocDetlService.selectLocdetl(agvWrkMast.getLocNo(),agvWrkDetl.getMatnr(),agvWrkDetl.getBatch(),agvWrkDetl.getThreeCode(),agvWrkDetl.getDeadTime());
                    double updateAnfme = agvLocDetl.getAnfme() - agvWrkDetl.getAnfme();
                    agvLocDetlService.updateAnfme(updateAnfme,agvLocDetl.getLocNo(),agvLocDetl.getMatnr(),agvLocDetl.getBatch(),agvLocDetl.getThreeCode(),agvLocDetl.getDeadTime());
                });
            }
            //修改库位信息
            updateAgvLocMast(agvLocMast,"Q");
            //修改站点信息
            updateAgvBasDevp(agvBasDevp,"R");
        });
    }
    /*
    盘点出库
     */
    @Transactional
    public void locCheckOut(StockOutParam param, Long userId) {
        String station = param.getStation();
//        List<AgvBasDevp> agvBasDevpList = agvBasDevpService.selectList(new EntityWrapper<AgvBasDevp>()
//                .eq("station_code", station)
//                .eq("loc_sts","O"));
//
//        if(param.getLocDetls().size() > agvBasDevpList.size()){
//            throw new CoolException("当前站点可用缓存货架数量为" + agvBasDevpList.size() + ",少于需要盘点出库库位数量,请重新选择盘点库位");
//        }
        List<TaskDto> taskDtos = new ArrayList<>();
        param.getLocDetls().forEach(locDetl -> {
            LocDto locDto = new LocDto(locDetl.getLocNo(),locDetl.getCount(),locDetl.getMatnr(),locDetl.getBatch(),locDetl.getThreeCode(),locDetl.getDeadTime(),locDetl.getSuppCode());
            TaskDto taskDto = new TaskDto(locDetl.getLocNo(),station,locDto);
            if(TaskDto.has(taskDtos,taskDto)){
                TaskDto.find(taskDtos,taskDto).getLocDtos().add(locDto);
            }else {
                taskDtos.add(taskDto);
            }
        });
        Date now = new Date();
        taskDtos.forEach(taskDto -> {
            //生成工作档
            AgvWrkMast wrkMast = createWrkMast(107, 21L,taskDto.getLocNo(),taskDto.getAgvStaNo(),taskDto.getLocDtos().get(0).getContainerCode(),now,userId,false);
            //生成工作档明细
            taskDto.getLocDtos().forEach(locDto -> {
                //明细档所需参数
                createWrkDetlReWrite(locDto.getMatnr(),
                        wrkMast.getWrkNo(),
                        locDto.getOrderNo(),
                        locDto.getBatch(),
                        locDto.getAnfme(),
                        locDto.getContainerCode(),
                        now,
                        userId,
                        locDto.getCsocode(),
                        locDto.getIsoseq());
            });
            updateAgvLocMast(agvLocMastService.selectById(wrkMast.getSourceLocNo()),"P");
            //更新目标站点状态
            //locSts = ioType == 101 ? "S" : "Q";
            updateAgvBasDevp(agvBasDevpService.selectById(wrkMast.getLocNo()),"S");
        });
//        param.getLocDetls().forEach(locDetl -> {
//            AgvLocMast agvLocMast = agvLocMastService.selectById(locDetl.getLocNo());
//            AgvLocDetl agvLocDetl = agvLocDetlService.selectOne(new EntityWrapper<AgvLocDetl>().eq("loc_no", locDetl.getLocNo()));
//            AgvBasDevp agvBasDevp = agvBasDevpService.selectOne(new EntityWrapper<AgvBasDevp>()
//                    .eq("station_code", station)
//                    .eq("loc_sts","O"));
//            Date now = new Date();
//
//            //生成工作党
//            AgvWrkMast wrkMast = createWrkMast(107, 21L, locDetl.getLocNo(), agvBasDevp.getDevNo(), agvLocDetl.getSuppCode(), now, userId,false);
//            //生成工作明细档
//            createWrkDetlReWrite(locDetl.getMatnr(),wrkMast.getWrkNo(),null,locDetl.getBatch(),locDetl.getCount(),wrkMast.getBarcode(),now,userId,agvLocDetl.getThreeCode(),agvLocDetl.getDeadTime());
//            //修改库位信息
//            updateAgvLocMast(agvLocMast,"P");
//            //修改站点信息
//            updateAgvBasDevp(agvBasDevp,"S");
//
//        });
    }
    /*
    库位移转
     */
    @Transactional
    public void locMove(String sourceLocNo, String targetLocNo, Long userId) {
        AgvLocMast sourceLocMast = agvLocMastService.selectById(sourceLocNo);
        AgvLocMast targetLocMast = agvLocMastService.selectById(targetLocNo);
        AgvLocDetl sourceLocDetl = agvLocDetlService.selectOne(new EntityWrapper<AgvLocDetl>().eq("loc_no", sourceLocMast.getLocNo()));
        if(!sourceLocMast.getLocSts().equals("F")){
            throw new CoolException(sourceLocMast.getLocNo() + "源库位出库失败,状态:"+sourceLocMast.getLocSts$());
        }
        if(!targetLocMast.getLocSts().equals("O")){
            throw new CoolException("移转失败,目标库位状态:"+targetLocMast.getLocSts$());
        }
        Date now = new Date();
        //生成移库工作档
        AgvWrkMast wrkMast = createWrkMast(11, 21L, sourceLocNo, targetLocNo, sourceLocDetl.getSuppCode(), now, userId,false);
        //生成工作党明细
        createWrkDetlReWrite(sourceLocDetl.getMatnr(),wrkMast.getWrkNo(),null,sourceLocDetl.getBatch(),sourceLocDetl.getAnfme(),sourceLocDetl.getZpallet(),now,userId,sourceLocDetl.getThreeCode(),sourceLocDetl.getDeadTime());
        //修改目标库位状态
        updateAgvLocMast(targetLocMast,"S");
        //修改原库位状态
        updateAgvLocMast(sourceLocMast,"R");
    }
    /*
    空板入库
     */
    @Transactional
    public String emptyPlateIn(String sourceStaion, Long userId) {
        Date now = new Date();
        // 源站点状态检测
        AgvBasDevp agvBasDevp = agvBasDevpService.selectById(sourceStaion);
        if(!agvBasDevp.getLocSts().equals("O")){
            throw new CoolException("当前工作位状态为" + agvBasDevp.getLocSts()+",无法进行空板入库");
        }
        // 检索库位
        AgvLocMast locMast = agvCommonService.getLocNo(null, agvBasDevp.getFloor());
        // 生成工作档 10.空板入库
        createWrkMast(10,201L,agvBasDevp.getDevNo(),locMast.getLocNo(),null,now,userId,false);
        //更新源站点状态
        updateAgvBasDevp(agvBasDevp,"R");
        //更新目标库位状态
        updateAgvLocMast(locMast,"S");
        return locMast.getLocNo();
    }
    /*
    空板出库
     */
    @Transactional
    public void emptyPlateOut(EmptyPlateOutParam param, Long userId) {
        Date now = new Date();
        //判断所选工作站空余工作位数量是否满足出库数量
        List<AgvBasDevp> agvBasDevpList = agvBasDevpService.selectList(new EntityWrapper<AgvBasDevp>()
                .eq("station_code", param.getStationCode())
                .eq("loc_sts","O"));
        if(agvBasDevpList.size() < param.getLocNos().size()){
            throw new CoolException("当前工作站可出库工作位数量为"+ agvBasDevpList.size() + ",小于要出库的库位数量,请重新选择出库库位");
        }
        param.getLocNos().forEach(locNo -> {
            AgvLocMast agvLocMast = agvLocMastService.selectById(locNo);
            if(!agvLocMast.getLocSts().equals("D")){
                throw new CoolException(agvLocMast.getLocNo() + "库位状态已经不为D.空桶/空栈板,请重新选择库位进行空板出库");
            }
            //检索工作位
            AgvBasDevp agvBasDevp = agvBasDevpService.selectOne(new EntityWrapper<AgvBasDevp>()
                    .eq("station_code", param.getStationCode())
                    .eq("loc_sts", "O"));
            //生成工作档
            createWrkMast(110,21L,locNo,agvBasDevp.getDevNo(),null,now,userId,false);
            //修改源库位状态
            updateAgvLocMast(agvLocMast,"R");
            //修改目标工作位状态
            updateAgvBasDevp(agvBasDevp,"S");
        });
    }
    @Transactional
    public void adjustLocDetl(LocDetlAdjustParam param, Long userId) {
        param.integrate();
        AgvLocMast locMast = agvLocMastService.selectById(param.getLocNo());
        if (Cools.isEmpty(locMast)) {
            throw new CoolException("库位不存在");
        }
        if (!(locMast.getLocSts().equals("F") || locMast.getLocSts().equals("D") || locMast.getLocSts().equals("O"))) {
            throw new CoolException("当前库位不可调整!库位状态:" + locMast.getLocSts$());
        }
        Date now = new Date();
        List<AgvLocDetl> locDetls = agvLocDetlService.selectList(new EntityWrapper<AgvLocDetl>().eq("loc_no", param.getLocNo()));
        List<LocDetlAdjustParam.LocDetlAdjust> list = param.getList();
        // 修改数量
        Iterator<AgvLocDetl> iterator = locDetls.iterator();
        while (iterator.hasNext()) {
            AgvLocDetl locDetl = iterator.next();
            Iterator<LocDetlAdjustParam.LocDetlAdjust> iterator1 = list.iterator();
            while (iterator1.hasNext()) {
                LocDetlAdjustParam.LocDetlAdjust adjust = iterator1.next();
                if (adjust.getCount() == 0) { continue; }
                if (locDetl.getMatnr().equals(adjust.getMatnr()) && Cools.eq(locDetl.getBatch(), adjust.getBatch()) && Cools.eq(locDetl.getSuppCode(),adjust.getSuppCode()) && Cools.eq(locDetl.getThreeCode(),adjust.getThreeCode()) && Cools.eq(locDetl.getDeadTime(),adjust.getDeadTime())) {
                    if (!locDetl.getAnfme().equals(adjust.getCount())) {
                        // todo 盘点记录
                        // 修改库存
                        if (!agvLocDetlService.updateAnfme(adjust.getCount(), locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(),locDetl.getThreeCode(),locDetl.getDeadTime())) {
                            throw new CoolException(locDetl.getLocNo() + "库位," + locDetl.getMatnr() + "商品," + locDetl.getBatch() + "序列码修改数量失败");
                        }
                        // 保存调整记录
                        AdjDetl adjDetl = new AdjDetl();
                        adjDetl.setLocNo(locDetl.getLocNo());
                        adjDetl.setMatnr(locDetl.getMatnr());
                        adjDetl.setBatch(locDetl.getBatch());
                        adjDetl.setOriQty(locDetl.getAnfme());
                        adjDetl.setAdjQty(adjust.getCount());
                        adjDetl.setModiTime(now);
                        adjDetl.setModiUser(userId);
                        adjDetl.setAppeTime(now);
                        adjDetl.setAppeUser(userId);
                        adjDetl.setOrderNo(Utils.generateAdjustOrderNo());
                        adjDetl.setCsocode(locDetl.getThreeCode());
                        adjDetl.setIsoseq(locDetl.getDeadTime());
                        adjDetlService.save(adjDetl, userId);
                    }
                    iterator.remove();
                    iterator1.remove();
                }
            }
        }
        // 删除库存
        for (AgvLocDetl locDetl : locDetls) {
            // todo 盘点记录
            if (!agvLocDetlService.updateAnfme(-1.0D, locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(),locDetl.getThreeCode(),locDetl.getDeadTime())) {
                throw new CoolException("删除" + locDetl.getLocNo() + "库位," + locDetl.getMatnr() + "商品," + locDetl.getBatch() + "序列码库存明细失败");
            }
            // 保存调整记录
            AdjDetl adjDetl = new AdjDetl();
            adjDetl.setLocNo(locDetl.getLocNo());
            adjDetl.setMatnr(locDetl.getMatnr());
            adjDetl.setBatch(locDetl.getBatch());
            adjDetl.setOriQty(locDetl.getAnfme());
            adjDetl.setAdjQty(0.0D);
            adjDetl.setModiTime(now);
            adjDetl.setModiUser(userId);
            adjDetl.setAppeTime(now);
            adjDetl.setAppeUser(userId);
            adjDetl.setOrderNo(Utils.generateAdjustOrderNo());
            adjDetlService.save(adjDetl, userId);
        }
        // 添加库存
        for (LocDetlAdjustParam.LocDetlAdjust adjust : list) {
            if (adjust.getCount() == 0.0D) { continue; }
            Mat mat = matService.selectByMatnr(adjust.getMatnr());
            AgvLocDetl locDetl = new AgvLocDetl();
            locDetl.sync(mat);
            locDetl.setBatch(adjust.getBatch());
            locDetl.setLocNo(locMast.getLocNo());
            locDetl.setAnfme(adjust.getCount()); // 数量
            locDetl.setModiUser(userId); // 操作人员信息
            locDetl.setModiTime(now);
            locDetl.setAppeUser(userId);
            locDetl.setAppeTime(now);
            locDetl.setThreeCode(adjust.getThreeCode());
            locDetl.setDeadTime(adjust.getDeadTime());
            locDetl.setSuppCode(adjust.getSuppCode());
            if (!agvLocDetlService.insert(locDetl)) {
                throw new CoolException("添加" + locDetl.getLocNo() + "库位," + locDetl.getMatnr() + "商品," + locDetl.getBatch() + "序列码库存明细失败");
            }
            // 保存调整记录
            AdjDetl adjDetl = new AdjDetl();
            adjDetl.setLocNo(locMast.getLocNo());
            adjDetl.setMatnr(adjust.getMatnr());
            adjDetl.setBatch(adjust.getBatch());
            adjDetl.setOriQty(0.0D);
            adjDetl.setAdjQty(adjust.getCount());
            adjDetl.setModiTime(now);
            adjDetl.setModiUser(userId);
            adjDetl.setAppeTime(now);
            adjDetl.setAppeUser(userId);
            adjDetl.setOrderNo(Utils.generateAdjustOrderNo());
            adjDetl.setCsocode(locDetl.getThreeCode());
            adjDetl.setIsoseq(locDetl.getDeadTime());
            adjDetlService.save(adjDetl, userId);
        }
        // 修改库位状态
        int count = agvLocDetlService.selectCount(new EntityWrapper<AgvLocDetl>().eq("loc_no", locMast.getLocNo()));
        if (locMast.getLocSts().equals("F")) {
            if (count == 0) {
                locMast.setLocSts("D");
            }
        }
        if (locMast.getLocSts().equals("D") || locMast.getLocSts().equals("O")) {
            if (count > 0) {
                locMast.setLocSts("F");
            }
        }
        locMast.setModiUser(userId);
        locMast.setModiTime(new Date());
        if (!agvLocMastService.updateById(locMast)) {
            throw new CoolException("更新库位状态失败");
        }
    }
    @Override
    @Transactional
    public void completeWrkMast(String workNo, Long userId) {
        AgvWrkMast wrkMast = agvWrkMastService.selectById(workNo);
        if (Cools.isEmpty(wrkMast)){
            throw new CoolException(workNo+"工作档不存在");
        }
        if(!wrkMast.getLocNo().contains("@") || !wrkMast.getSourceLocNo().contains("@")){
            throw new CoolException("目标库位或者源库位暂未分配,无法取消");
        }
        //修改AGV工作档的工作状态为205.工作完成
        agvWrkMastService.updateWrkStsByWrkNo(wrkMast.getWrkNo(),205);
        //出库任务 101.出库 || 103.拣料出库 || 107.盘点出库
        if(wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103 || wrkMast.getIoType() == 107){
            //修改出库站点状态
            agvBasDevpService.updateLocStsAndBarcodeByDevNo(wrkMast.getLocNo(),"F",wrkMast.getBarcode());
        }
        //出库任务 110.空板出库
        if(wrkMast.getIoType() == 110){
            agvBasDevpService.updateLocStsAndBarcodeByDevNo(wrkMast.getLocNo(),"F",wrkMast.getBarcode());
        }
    }
    @Transactional
    public void cancelWrkMast(String workNo, Long userId) {
        AgvWrkMast wrkMast = agvWrkMastService.selectById(workNo);
        if (Cools.isEmpty(wrkMast)){
            throw new CoolException(workNo+"工作档不存在");
        }
        //拣料入库 盘点入库不可取消
        if(wrkMast.getIoType() == 53 || wrkMast.getIoType() == 57){
            throw new CoolException("当前任务不可取消");
        }
        //入库取消
        if(wrkMast.getIoType() == 1 || wrkMast.getIoType() == 10){
            //源站点
            String devNo = wrkMast.getSourceLocNo();
            //目标库位
            String locNo = wrkMast.getLocNo();
            agvLocMastService.updateLocStsByLocNo(locNo,"O","");
            agvBasDevpService.updateLocStsAndBarcodeByDevNo(devNo,"F",wrkMast.getBarcode());
            //出库取消
        }else {
            //源库位
            String locNo = wrkMast.getSourceLocNo();
            //目标站点
            String devNo = wrkMast.getLocNo();
            agvLocMastService.updateLocStsByLocNo(locNo,"F",wrkMast.getBarcode());
            if(devNo.contains("@")){
                agvBasDevpService.updateLocStsAndBarcodeByDevNo(devNo,"O","");
            }
        }
        //订单回滚
        //List<AgvWrkDetl> agvWrkDetlList = agvWrkDetlService.selectByWrkNo(wrkMast.getWrkNo());
        List<AgvWrkDetl> agvWrkDetlList1 = agvWrkDetlService.selectList(new EntityWrapper<AgvWrkDetl>().eq("wrk_no", wrkMast.getWrkNo()));
        agvWrkDetlList1.forEach(agvWrkDetl -> {
            if(!Cools.isEmpty(agvWrkDetl.getOrderNo())){
                OrderDetl orderDetl = orderDetlService.selectByOrderNoAndMatnr(agvWrkDetl.getOrderNo(),agvWrkDetl.getMatnr(),agvWrkDetl.getThreeCode(),agvWrkDetl.getDeadTime());
                orderDetl.setQty(orderDetl.getQty() - agvWrkDetl.getAnfme());
                orderDetlService.updateById(orderDetl);
            }
        });
        //保存工作档以及明细
        agvWrkMastLogService.save(wrkMast);
        agvWrkDetlLogService.save(wrkMast.getWrkNo());
        //删除工作档以及明细
        if(!agvWrkMastService.deleteByWrkNo(wrkMast.getWrkNo()) || !agvWrkDetlService.deleteByWrkNo(wrkMast.getWrkNo())){
            throw new CoolException("删除失败,请联系管理员");
        }
    }
    /*
    更新目标库位信息
     */
    private void updateAgvLocMast(AgvLocMast locMast){
        locMast.setLocSts("S");
        agvLockMastService.updateById(locMast);
    private void updateAgvLocMast(AgvLocMast locMast, String locSts){
        locMast.setLocSts(locSts);
        agvLocMastService.updateById(locMast);
    }
    /*
    更新源站点信息
     */
    private void updateAgvBasDevp(AgvBasDevp agvBasDevp){
        agvBasDevp.setLocSts("R");
        agvBasDevpService.updateById(agvBasDevp);
    private void updateAgvBasDevp(AgvBasDevp agvBasDevp, String locSts){
        if(!Cools.isEmpty(agvBasDevp)){
            agvBasDevp.setLocSts(locSts);
            agvBasDevpService.updateById(agvBasDevp);
        }
    }
    /*
    生成工作档明细
     */
  /*  private void createWrkDetl(List<AgvWaitPakin> agvWaitPakinList, AgvWrkMast wrkMast, Long userId){
        List<DetlDto> detlDtos = new ArrayList<>();
        agvWaitPakinList.forEach(agvWaitPakin -> {
            DetlDto detlDto = new DetlDto(agvWaitPakin.getMatnr(), agvWaitPakin.getBatch(), agvWaitPakin.getAnfme());
            if (DetlDto.has(detlDtos, detlDto)) {
                DetlDto detlDto1 = DetlDto.find(detlDtos, detlDto.getMatnr(), detlDto.getBatch());
                assert detlDto1 != null;
                detlDto1.setAnfme(detlDto1.getAnfme() + detlDto.getAnfme());
            } else {
                detlDtos.add(detlDto);
            }
        });
        agvWrkDetlService.createWorkDetail(wrkMast.getWrkNo(), detlDtos, wrkMast.getBarcode(), userId);
    }*/
    private void createWrkDetlReWrite(String matnr, int wrkNo, String orderNo,String batch, double anfme, String zpallet, Date now, Long userId, String csocode, String isoseq){
        Mat mat = matService.selectByMatnr(matnr);
        if (Cools.isEmpty(mat)) {
            throw new CoolException(matnr + "商品维护失败");
        }
        AgvWrkDetl wrkDetl = new AgvWrkDetl();
        wrkDetl.sync(mat);
        wrkDetl.setWrkNo(wrkNo);
        wrkDetl.setOrderNo(orderNo);
        wrkDetl.setIoTime(now);
        wrkDetl.setBatch(batch);
        wrkDetl.setAnfme(anfme); // 数量
        wrkDetl.setSuppCode(zpallet); // 托盘条码
        wrkDetl.setAppeUser(userId);
        wrkDetl.setAppeTime(now);
        wrkDetl.setModiUser(userId);
        wrkDetl.setModiTime(now);
        wrkDetl.setThreeCode(csocode);
        wrkDetl.setDeadTime(isoseq);
        if (!agvWrkDetlService.insert(wrkDetl)) {
            throw new CoolException("保存工作明细失败");
        }
    }
    /*
    生成工作档明细
     */
    @Deprecated
    private void createWrkDetlReWrite(List<AgvWaitPakin> agvWaitPakinList, AgvWrkMast wrkMast, Long userId){
        Date now = new Date();
        agvWaitPakinList.stream().forEach(agvWaitPakin -> {
@@ -138,32 +659,108 @@
    /*
    生成工作档
     */
    private AgvWrkMast createWrkMast(AgvBasDevp agvBasDevp,AgvLocMast agvLocMast, Date now, Long userId){
    private AgvWrkMast createWrkMast(int ioType, long wrkSts, String sourceLocNo, String locNo, String barcode,  Date now, Long userId, boolean isConveyor){
        AgvWrkMast wrkMast = new AgvWrkMast();
        //生成工作号
        int workNo = agvCommonService.getWorkNo(0);
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(new Date());
        wrkMast.setWrkSts(201L); // 工作状态:201.生成入库任务ID
        wrkMast.setIoType(1); // 入出库状态:1.入库
        //生成优先级
        //工作状态
        wrkMast.setWrkSts(wrkSts);
        //入出库类型
        wrkMast.setIoType(ioType);
        wrkMast.setIoTime(now);
        //优先级
        wrkMast.setIoPri(300.0);
        wrkMast.setSourceLocNo(agvBasDevp.getDevNo());
        wrkMast.setLocNo(agvLocMast.getLocNo());
        wrkMast.setBarcode(agvBasDevp.getBarcode());
        wrkMast.setFullPlt("Y"); // 满板:Y
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setEmptyMk("N"); // 空板
        wrkMast.setLinkMis("N");
        //源站点
        wrkMast.setSourceLocNo(sourceLocNo);
        //目标站点
        wrkMast.setLocNo(locNo);
        //容器编码
        wrkMast.setBarcode(barcode);
        //标记是否为输送线入库
        wrkMast.setMk(isConveyor ? "Y" : "N");
        wrkMast.setAppeUser(userId);
        wrkMast.setAppeTime(now);
        wrkMast.setModiUser(userId);
        wrkMast.setModiTime(now);
        if (!agvWrkMastService.insert(wrkMast)) {
        if (!agvWrkMastService.insertByIncrease(wrkMast)) {
            throw new CoolException("保存工作档失败");
        }
        return wrkMast;
        //暂存位任务+1
        addInQty(locNo);
        wrkMast = agvWrkMastService.selectOne(new EntityWrapper<AgvWrkMast>().eq("loc_no", locNo).eq("source_loc_no",sourceLocNo));
        return wrkMast;
    }
    private boolean isPakOut(String locNo, TaskDto taskDto){
        Double allAnfme = agvLocDetlService.selectSumAnfmeByLocNo(locNo);
        Double pakOutAnfme = 0.0;
        for (LocDto locDto : taskDto.getLocDtos()){
            pakOutAnfme += locDto.getAnfme();
        }
        if(allAnfme > pakOutAnfme){
            return false;
        }
        return true;
    }
    /*
    AGV生成出库工作档后修改订单信息
    TODO 与四项库生成出库工作档后修改订单信息整合到一起
     */
    private void modifyOrderDetl(LocDto locDto, Long userId){
        if (!BaseController.isJSON(locDto.getOrderNo())) {
            //非合并出库
            OrderDetl orderDetl = orderDetlService.selectItem(locDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch(),locDto.getCsocode(),locDto.getIsoseq());
            if (orderDetl == null) {
                orderDetl = orderDetlService.selectItem(locDto.getOrderNo(), locDto.getMatnr(), null,locDto.getCsocode(),locDto.getIsoseq());
            }
            if (!orderDetlService.increase(orderDetl.getOrderId(), orderDetl.getMatnr(), orderDetl.getBatch(), locDto.getAnfme(),locDto.getCsocode(),locDto.getIsoseq())) {
                throw new CoolException("修改订单明细数量失败");
            }
            orderService.updateSettle(orderDetl.getOrderId(), 2L, userId);
        }else {
            //合并出库
            List<OrderDto> orderDtoList = JSON.parseArray(locDto.getOrderNo(), OrderDto.class);
            //实际出库数量
            Double locAnfme = locDto.getAnfme();
            //订单实际出库数量
            Double orderAnfme;
            for (OrderDto orderDto : orderDtoList) {
                OrderDetl orderDetl = orderDetlService.selectItem(orderDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch(),locDto.getCsocode(),locDto.getIsoseq());
                if (orderDetl == null) {
                    orderDetl = orderDetlService.selectItem(orderDto.getOrderNo(), locDto.getMatnr(), null,locDto.getCsocode(),locDto.getIsoseq());
                }
                if(locAnfme > orderDetl.getAnfme()){
                    orderAnfme = orderDetl.getAnfme();
                    locAnfme -= orderAnfme;
                }else {
                    orderAnfme = locAnfme;
                }
                if (!orderDetlService.increase(orderDetl.getOrderId(), orderDetl.getMatnr(), orderDetl.getBatch(), orderAnfme,orderDetl.getThreeCode(),orderDetl.getDeadTime())) {
                    throw new CoolException("修改订单明细数量失败");
                }
                orderService.updateSettle(orderDetl.getOrderId(), 2L, userId);
            }
        }
    }
    private void addInQty(String devno){
        AgvBasDevp agvBasDevp = agvBasDevpService.selectById(devno);
        if(!Cools.isEmpty(agvBasDevp)){
            if(Cools.isEmpty(agvBasDevp.getInQty())){
                agvBasDevp.setInQty(1);
            }else {
                agvBasDevp.setInQty(agvBasDevp.getInQty() + 1);
            }
        }
    }
}