#
Junjie
2024-09-20 053e6028bd20e599aea103401137816c6296a9ef
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
@@ -3,16 +3,18 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.exception.CoolException;
import com.zy.asrs.wms.asrs.entity.*;
import com.zy.asrs.wms.asrs.entity.enums.LocStsType;
import com.zy.asrs.wms.asrs.entity.enums.*;
import com.zy.asrs.wms.asrs.entity.param.FieldParam;
import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam;
import com.zy.asrs.wms.asrs.service.*;
import com.zy.asrs.wms.utils.LocUtils;
import com.zy.asrs.wms.utils.OrderUtils;
import com.zy.asrs.wms.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.*;
@Service("workService")
public class WorkServiceImpl implements WorkService {
@@ -30,11 +32,37 @@
    @Autowired
    private TaskDetlFieldService taskDetlFieldService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetlService orderDetlService;
    @Autowired
    private LocService locService;
    @Autowired
    private LocStsService locStsService;
    @Autowired
    private TaskLogService taskLogService;
    @Autowired
    private TaskDetlLogService taskDetlLogService;
    @Autowired
    private TaskDetlFieldLogService taskDetlFieldLogService;
    @Autowired
    private LocUtils locUtils;
    @Autowired
    private ShelvesRuleService shelvesRuleService;
    @Autowired
    private LanewayRuleService lanewayRuleService;
    @Autowired
    private CircleRuleService circleRuleService;
    @Autowired
    private LocTypeBindService locTypeBindService;
    @Autowired
    private LocTypeService locTypeService;
    @Autowired
    private MatService matService;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private WaveDetlService waveDetlService;
    @Override
    public String generateTaskNo(Long taskType) {
@@ -49,20 +77,177 @@
    }
    @Override
    public Loc generateLoc(Long taskType) {
        LocSts locSts = locStsService.getOne(new LambdaQueryWrapper<LocSts>().eq(LocSts::getLocSts, String.valueOf(LocStsType.O)));
        List<Loc> list = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getLocStsId, locSts.getId()));
        if (list.isEmpty()) {
            throw new CoolException("没有空库位");
    public Loc generateEmptyLoc(Long taskType, Integer locTypeHeight) {
        List<ShelvesRule> shelvesRules = shelvesRuleService.list(new LambdaQueryWrapper<ShelvesRule>().eq(ShelvesRule::getStatus, 1).orderByDesc(ShelvesRule::getCreateTime));
        if(shelvesRules.isEmpty()) {
            throw new CoolException("未配置上架规则");
        }
        return list.get(0);
        ShelvesRule shelvesRule = shelvesRules.get(0);
        //可用巷道
        List<Long> laneList = shelvesRule.getLaneList();
        //可用巷道Row
        List<Integer> laneRowList = new ArrayList<>();
        if (laneList != null) {
            //获取巷道
            List<LanewayRule> lanewayRules = lanewayRuleService.listByIds(laneList);
            for (LanewayRule lanewayRule : lanewayRules) {
                laneRowList.addAll(lanewayRule.getLaneX$());
                laneRowList.addAll(lanewayRule.getLaneY$());
            }
        }
        Integer currentLev = null;
        if (shelvesRule.getRuleType().equals(ShelvesRuleType.HIGH.id)) {
            //优先立体层
            currentLev = circleRuleService.getCurrentValueByFlag(CircleRuleType.LEV.flag);
        }
        List<ShelvesRuleDetl> ruleDetls = shelvesRule.getRuleDetl$();
        if(ruleDetls.isEmpty()) {
            throw new CoolException("未配置上架规则明细");
        }
        Loc defaultLoc = null;
        for (ShelvesRuleDetl ruleDetl : ruleDetls) {
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.TASK_OR_LOC.id)) {
                //从库存或任务中匹配相邻库位
                defaultLoc = locUtils.getNeighborEmptyLoc(taskType, locTypeHeight);
                if (defaultLoc != null) {
                    return defaultLoc;
                }
            }
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.SUGGEST.id)) {
                //获取推荐库位
                List<Loc> suggestLoc = locUtils.getSuggestEmptyLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!suggestLoc.isEmpty()) {
                    defaultLoc = locUtils.filterLoc(taskType, suggestLoc);
                    if(defaultLoc != null) {
                        return defaultLoc;
                    }
                }
            }
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.COMPLETE.id)) {
                //从全局库位中获取(完整巷道)
                List<Loc> globalLoc = locUtils.getGlobalEmptyLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!globalLoc.isEmpty()) {
                    defaultLoc = locUtils.filterAllLoc(globalLoc);
                    if(defaultLoc != null) {
                        return defaultLoc;
                    }
                }
            }
        }
        return defaultLoc;
    }
    @Override
    public synchronized Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight) {
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, barcode));
        if (taskType != 10 && waitPakins.isEmpty()) {
            throw new CoolException("托盘未组托");
        }
        WaitPakin waitPakin = waitPakins.get(0);
        OrderDetl detl = waitPakin.getDetl$();
        if (detl == null) {
            throw new CoolException("订单明细不存在");
        }
        String batch = detl.getBatch();
        List<FieldParam> uniqueFields = detl.getUniqueField();
        Mat mat = detl.getMat$();
        if (mat == null) {
            throw new CoolException("商品不存在");
        }
        return generateLoc(taskType, mat.getId(), batch, uniqueFields, locTypeHeight);
    }
    @Override
    public synchronized Loc generateLoc(Long taskType, Long matId, String batch, List<FieldParam> uniqueFields, Integer locTypeHeight) {
        Mat mat = matService.getById(matId);
        if (mat == null) {
            throw new CoolException("商品不存在");
        }
        List<ShelvesRule> shelvesRules = shelvesRuleService.list(new LambdaQueryWrapper<ShelvesRule>().eq(ShelvesRule::getStatus, 1).orderByDesc(ShelvesRule::getCreateTime));
        if (shelvesRules.isEmpty()) {
            throw new CoolException("未配置上架规则");
        }
        ShelvesRule shelvesRule = shelvesRules.get(0);
        //可用巷道
        List<Long> laneList = shelvesRule.getLaneList();
        //可用巷道Row
        List<Integer> laneRowList = new ArrayList<>();
        if (laneList != null) {
            //获取巷道
            List<LanewayRule> lanewayRules = lanewayRuleService.listByIds(laneList);
            for (LanewayRule lanewayRule : lanewayRules) {
                laneRowList.addAll(lanewayRule.getLaneX$());
                laneRowList.addAll(lanewayRule.getLaneY$());
            }
        }
        Integer currentLev = null;
        if (shelvesRule.getRuleType().equals(ShelvesRuleType.HIGH.id)) {
            //优先立体层
            currentLev = circleRuleService.getCurrentValueByFlag(CircleRuleType.LEV.flag);
        }
        List<ShelvesRuleDetl> ruleDetls = shelvesRule.getRuleDetl$();
        if (ruleDetls.isEmpty()) {
            throw new CoolException("未配置上架规则明细");
        }
        Loc defaultLoc = null;
        for (ShelvesRuleDetl ruleDetl : ruleDetls) {
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.TASK_OR_LOC.id)) {
                //从库存或任务中匹配相邻库位
                defaultLoc = locUtils.getNeighborLoc(taskType, mat.getId(), batch, uniqueFields, locTypeHeight);
                if (defaultLoc != null) {
                    return defaultLoc;
                }
            }
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.SUGGEST.id)) {
                //获取推荐库位
                List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), batch, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!suggestLoc.isEmpty()) {
                    defaultLoc = locUtils.filterLoc(taskType, suggestLoc);
                    if (defaultLoc != null) {
                        return defaultLoc;
                    }
                }
            }
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.COMPLETE.id)) {
                //从全局库位中获取(完整巷道)
                List<Loc> globalLoc = locUtils.getGlobalLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!globalLoc.isEmpty()) {
                    defaultLoc = locUtils.filterAllLoc(globalLoc);
                    if (defaultLoc != null) {
                        return defaultLoc;
                    }
                }
            }
        }
        return defaultLoc;
    }
    @Override
    @Transactional
    public boolean generatePakIn(GeneratePakInParam param) {
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, param.getBarcode()));
        if (waitPakins.isEmpty()) {
        if (param.getTaskType() != 10 && waitPakins.isEmpty()) {
            throw new CoolException("托盘未组托");
        }
@@ -71,8 +256,16 @@
            throw new CoolException("任务类型不存在");
        }
        Task one = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, param.getBarcode()));
        if (one != null) {
            throw new CoolException("任务已经创建,请勿重复请求");
        }
        //生成库位
        Loc loc = this.generateLoc(param.getTaskType());
        Loc loc = this.generateLoc(param.getTaskType(), param.getBarcode(), param.getLocTypeHeight());
        if(loc == null) {
            throw new CoolException("没有空库位");
        }
        Task task = new Task();
        task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号
@@ -102,6 +295,7 @@
            taskDetl.setOrderNo(waitPakin.getOrderNo());
            taskDetl.setDetlId(waitPakin.getDetlId());
            taskDetl.setMatId(waitPakin.getDetl$().getMatId());
            taskDetl.setMatnr(waitPakin.getDetl$().getMat$().getMatnr());
            boolean taskDetlSave = taskDetlService.save(taskDetl);
            if(!taskDetlSave){
                throw new CoolException("任务明细生成失败");
@@ -129,17 +323,32 @@
                throw new CoolException("组托通知档更新失败");
            }
            //更新订单数据
            //更新订单明细数据
            OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
            if(orderDetl == null){
                throw new CoolException("订单数据异常");
                throw new CoolException("订单明细不存在");
            }
            orderDetl.setWorkQty(orderDetl.getWorkQty() + taskDetl.getAnfme());
            orderDetl.setUpdateTime(new Date());
            boolean orderDetlUpdate = orderDetlService.updateById(orderDetl);
            if(!orderDetlUpdate){
                throw new CoolException("订单更新失败");
                throw new CoolException("订单明细更新失败");
            }
            //获取订单
            Order order = orderService.getById(taskDetl.getOrderId());
            if(order == null){
                throw new CoolException("订单不存在");
            }
            //更新订单状态
            if (order.getOrderSettle().equals(OrderSettleType.WAIT.val())) {
                order.setOrderSettle(OrderSettleType.WORKING.val());
                order.setUpdateTime(new Date());
                if (!orderService.updateById(order)) {
                    throw new CoolException("订单数据更新失败");
                }
            }
        }
@@ -155,8 +364,46 @@
    }
    @Override
    @Transactional
    public boolean cancelTask(Long taskId) {
    public boolean generateEmptyPakIn(GeneratePakInParam param) {
        TaskType taskType = taskTypeService.getById(param.getTaskType());
        if (taskType == null) {
            throw new CoolException("任务类型不存在");
        }
        //生成库位
        Loc loc = this.generateEmptyLoc(param.getTaskType(), param.getLocTypeHeight());
        if(loc == null) {
            throw new CoolException("没有空库位");
        }
        Task task = new Task();
        task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号
        task.setTaskSts(1L);//1.生成入库任务
        task.setTaskType(taskType.getId());//任务类型
        task.setIoPri(this.generateIoPri(taskType.getId()));//优先级
        task.setOriginLoc(null);
        task.setTargetLoc(loc.getLocNo());
        task.setOriginSite(param.getOriginSite());
        task.setTargetSite(null);
        task.setBarcode(null);//托盘码
        boolean taskSave = taskService.save(task);
        if (!taskSave) {
            throw new CoolException("任务生成失败");
        }
        //库位O => S
        loc.setLocStsId(LocStsType.S.val());
        loc.setUpdateTime(new Date());
        boolean locUpdate = locService.updateById(loc);
        if(!locUpdate){
            throw new CoolException("库位状态更新失败");
        }
        return true;
    }
    @Override
    public boolean completeTask(Long taskId) {
        Task task = taskService.getById(taskId);
        if(task == null){
            throw new CoolException("任务不存在");
@@ -167,10 +414,40 @@
            throw new CoolException("任务明细不存在");
        }
        if (task.getTaskType() < 100) {
            //入库
            task.setTaskSts(99L);//99.入库完成
        }else {
            //出库
            TaskDetl taskDetl = taskDetls.get(0);
            if (taskDetl.getWaveId() == null) {
                task.setTaskSts(199L);//199.出库完成
            }else {
                task.setTaskSts(198L);//198.播种中
            }
        }
        task.setUpdateTime(new Date());
        if (!taskService.updateById(task)) {
            throw new CoolException("任务更新失败");
        }
        return true;
    }
    @Override
    @Transactional
    public boolean cancelTask(Long taskId) {
        Task task = taskService.getById(taskId);
        if(task == null){
            throw new CoolException("任务不存在");
        }
        //更新库位状态
        Loc loc = null;
        switch (task.getTaskType().intValue()) {
            case 1://入库
            case 10://空板
            case 53://拣料
            case 54://并板
            case 57://盘点
@@ -191,6 +468,7 @@
            case 103://拣料
            case 104://并板
            case 107://盘点
            case 110://空板
                loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()));
                if(loc == null){
                    throw new CoolException("库位不存在");
@@ -203,50 +481,35 @@
                if(!locService.updateById(loc)){
                    throw new CoolException("库位状态变更失败");
                }
                List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId);
                for (TaskDetl taskDetl : taskDetls) {
                    if (taskDetl.getWaveId() == null) {
                        continue;
                    }
                    String matUniqueKey = Utils.getMatUniqueKey(taskDetl.getMatnr(), taskDetl.getBatch(), taskDetl.getUniqueField());
                    WaveDetl waveDetl = waveDetlService.getOne(new LambdaQueryWrapper<WaveDetl>().eq(WaveDetl::getStockIndex, matUniqueKey).eq(WaveDetl::getWaveId, taskDetl.getWaveId()));
                    if(waveDetl == null){
                        continue;
                    }
                    waveDetl.setWorkQty(waveDetl.getWorkQty() - taskDetl.getAnfme());
                    waveDetl.setUpdateTime(new Date());
                    if (!waveDetlService.updateById(waveDetl)) {
                        throw new CoolException("波次明细更新失败");
                    }
                }
                break;
        }
        //回滚订单
        for (TaskDetl taskDetl : taskDetls) {
            OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
            if(orderDetl == null){
                throw new CoolException("订单明细不存在");
            }
            //回滚工作数量
            orderDetl.setWorkQty(orderDetl.getWorkQty() - taskDetl.getAnfme());
            orderDetl.setUpdateTime(new Date());
            boolean orderDetlUpdate = orderDetlService.updateById(orderDetl);
            if(!orderDetlUpdate){
                throw new CoolException("工作数量回滚失败");
            }
            //入库回滚组托通知档
            if (task.getTaskType() == 1) {
                WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getDetlId, taskDetl.getDetlId()).eq(WaitPakin::getBarcode, task.getBarcode()));
                if(waitPakin == null){
                    throw new CoolException("组托通知档不存在");
                }
                waitPakin.setIoStatus(0);
                waitPakin.setUpdateTime(new Date());
                boolean updateWaitPakin = waitPakinService.updateById(waitPakin);
                if(!updateWaitPakin){
                    throw new CoolException("组托通知档回滚失败");
                }
            }
            //删除明细扩展
            boolean removeField = taskDetlFieldService.remove(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()));
            if(!removeField){
                throw new CoolException("回滚扩展明细失败");
            }
            //删除明细
            boolean removeDetl = taskDetlService.removeById(taskDetl.getId());
            if(!removeDetl){
                throw new CoolException("回滚明细失败");
            }
        //数据保存至历史档
        TaskLog taskLog = new TaskLog();
        taskLog.sync(task);
        taskLog.setId(null);
        if (!taskLogService.save(taskLog)) {
            throw new CoolException("任务档案转历史档案失败");
        }
        //删除任务
@@ -255,6 +518,136 @@
            throw new CoolException("回滚任务失败");
        }
        if (task.getTaskType() != 10) {
            List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId);
            if (taskDetls.isEmpty()) {
                throw new CoolException("任务明细不存在");
            }
            //回滚订单
            for (TaskDetl taskDetl : taskDetls) {
                if (taskDetl.getDetlId() != null) {
                    orderUtils.updateWorkQty(taskDetl.getDetlId(), taskDetl.getAnfme(), false);
                }
                //入库回滚组托通知档
                if (task.getTaskType() == 1) {
                    WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getDetlId, taskDetl.getDetlId()).eq(WaitPakin::getBarcode, task.getBarcode()));
                    if(waitPakin == null){
                        throw new CoolException("组托通知档不存在");
                    }
                    waitPakin.setIoStatus(0);
                    waitPakin.setUpdateTime(new Date());
                    boolean updateWaitPakin = waitPakinService.updateById(waitPakin);
                    if(!updateWaitPakin){
                        throw new CoolException("组托通知档回滚失败");
                    }
                }
                //明细数据保存至历史档
                TaskDetlLog taskDetlLog = new TaskDetlLog();
                taskDetlLog.sync(taskDetl);
                taskDetlLog.setId(null);
                taskDetlLog.setTaskId(taskLog.getId());
                if (!taskDetlLogService.save(taskDetlLog)) {
                    throw new CoolException("明细数据转历史档案失败");
                }
                //删除明细
                boolean removeDetl = taskDetlService.removeById(taskDetl.getId());
                if(!removeDetl){
                    throw new CoolException("回滚明细失败");
                }
                List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()));
                for (TaskDetlField detlField : detlFields) {
                    //明细扩展字段数据保存至历史档
                    TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog();
                    taskDetlFieldLog.sync(detlField);
                    taskDetlFieldLog.setId(null);
                    taskDetlFieldLog.setDetlId(taskDetlLog.getId());
                    if (!taskDetlFieldLogService.save(taskDetlFieldLog)) {
                        throw new CoolException("明细扩展字段转历史档案失败");
                    }
                    //删除明细扩展
                    boolean removeField = taskDetlFieldService.removeById(detlField.getId());
                    if(!removeField){
                        throw new CoolException("回滚扩展明细失败");
                    }
                }
            }
        }
        return true;
    }
    @Override
    public boolean pickTask(Long taskId) {
        Task task = taskService.getById(taskId);
        if(task == null){
            throw new CoolException("任务不存在");
        }
        if (task.getTaskType() != 103) {
            throw new CoolException("任务类型不可拣料");
        }
        if (task.getTaskSts() != 200) {
            throw new CoolException("当前状态不可拣料");
        }
        //获取源库位
        Loc originLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()));
        if(originLoc == null){
            throw new CoolException("源库位不存在");
        }
        //获取源库位高度
        LocTypeBind locTypeBind = locTypeBindService.getOne(new LambdaQueryWrapper<LocTypeBind>().eq(LocTypeBind::getLocId, originLoc.getId()).in(LocTypeBind::getTypeId, LocBindType.HEIGHT.list()));
        if(locTypeBind == null){
            throw new CoolException("库位类型不存在");
        }
        LocType locType = locTypeService.getById(locTypeBind.getTypeId());
        if(locType == null){
            throw new CoolException("库位类型不存在");
        }
        LocTypeHeightType locTypeHeightType = LocTypeHeightType.get(locType.getFlag());
        if(locTypeHeightType == null){
            throw new CoolException("高低库位类型不存在");
        }
        Long taskType = task.getTaskType() - 50;
        List<TaskDetl> taskDetls = taskDetlService.list(new LambdaQueryWrapper<TaskDetl>().eq(TaskDetl::getTaskId, taskId).gt(TaskDetl::getAnfme, 0));
        if (taskDetls.isEmpty()) {
            throw new CoolException("任务明细不存在");
        }
        TaskDetl taskDetl = taskDetls.get(0);
        //生成库位
        Loc loc = this.generateLoc(taskType, taskDetl.getMatId(), taskDetl.getBatch(), taskDetl.getUniqueField(), locTypeHeightType.id);
        if(loc == null) {
            throw new CoolException("没有空库位");
        }
        task.setTaskSts(1L);//1.生成入库任务
        task.setTaskType(taskType);
        task.setTargetLoc(loc.getLocNo());
        task.setUpdateTime(new Date());
        if (!taskService.updateById(task)) {
            throw new CoolException("拣料失败");
        }
        //库位O => S
        loc.setLocStsId(LocStsType.S.val());
        loc.setUpdateTime(new Date());
        boolean locUpdate = locService.updateById(loc);
        if(!locUpdate){
            throw new CoolException("库位状态更新失败");
        }
        return true;
    }
}