#
Junjie
2025-02-14 ac4341ea6b66ae02427d39d35f41d42d78b2eb2e
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
@@ -1,14 +1,20 @@
package com.zy.asrs.wms.asrs.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.common.Cools;
import com.zy.asrs.framework.common.R;
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.OrderSettleType;
import com.zy.asrs.wms.asrs.entity.enums.ShelvesRuleDetlType;
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.entity.param.LocAdjustParam;
import com.zy.asrs.wms.asrs.entity.param.LocTransferParam;
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;
@@ -37,6 +43,10 @@
    @Autowired
    private LocService locService;
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private LocDetlFieldService locDetlFieldService;
    @Autowired
    private LocStsService locStsService;
    @Autowired
    private TaskLogService taskLogService;
@@ -50,6 +60,20 @@
    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;
    @Autowired
    private MatFieldService matFieldService;
    @Override
    public String generateTaskNo(Long taskType) {
@@ -83,6 +107,12 @@
            }
        }
        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("未配置上架规则明细");
@@ -101,7 +131,7 @@
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.SUGGEST.id)) {
                //获取推荐库位
                List<Loc> suggestLoc = locUtils.getSuggestEmptyLoc(taskType, locTypeHeight, laneRowList);
                List<Loc> suggestLoc = locUtils.getSuggestEmptyLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!suggestLoc.isEmpty()) {
                    defaultLoc = locUtils.filterLoc(taskType, suggestLoc);
@@ -113,7 +143,7 @@
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.COMPLETE.id)) {
                //从全局库位中获取(完整巷道)
                List<Loc> globalLoc = locUtils.getGlobalEmptyLoc(taskType, locTypeHeight, laneRowList);
                List<Loc> globalLoc = locUtils.getGlobalEmptyLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!globalLoc.isEmpty()) {
                    defaultLoc = locUtils.filterAllLoc(globalLoc);
@@ -128,7 +158,7 @@
    }
    @Override
    public Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight) {
    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("托盘未组托");
@@ -139,14 +169,26 @@
        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()) {
        if (shelvesRules.isEmpty()) {
            throw new CoolException("未配置上架规则");
        }
        ShelvesRule shelvesRule = shelvesRules.get(0);
@@ -163,8 +205,14 @@
            }
        }
        Integer currentLev = null;
        if (shelvesRule.getRuleType().equals(ShelvesRuleType.HIGH.id)) {
            //优先立体层
            currentLev = circleRuleService.getCurrentValueByFlag(CircleRuleType.LEV.flag);
        }
        List<ShelvesRuleDetl> ruleDetls = shelvesRule.getRuleDetl$();
        if(ruleDetls.isEmpty()) {
        if (ruleDetls.isEmpty()) {
            throw new CoolException("未配置上架规则明细");
        }
@@ -173,7 +221,7 @@
        for (ShelvesRuleDetl ruleDetl : ruleDetls) {
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.TASK_OR_LOC.id)) {
                //从库存或任务中匹配相邻库位
                defaultLoc = locUtils.getNeighborLoc(taskType, detl, locTypeHeight);
                defaultLoc = locUtils.getNeighborLoc(taskType, mat.getId(), batch, uniqueFields, locTypeHeight);
                if (defaultLoc != null) {
                    return defaultLoc;
                }
@@ -181,11 +229,11 @@
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.SUGGEST.id)) {
                //获取推荐库位
                List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), detl.getBatch(), locTypeHeight, laneRowList);
                List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), batch, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!suggestLoc.isEmpty()) {
                    defaultLoc = locUtils.filterLoc(taskType, suggestLoc);
                    if(defaultLoc != null) {
                    if (defaultLoc != null) {
                        return defaultLoc;
                    }
                }
@@ -193,11 +241,11 @@
            if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.COMPLETE.id)) {
                //从全局库位中获取(完整巷道)
                List<Loc> globalLoc = locUtils.getGlobalLoc(taskType, locTypeHeight, laneRowList);
                List<Loc> globalLoc = locUtils.getGlobalLoc(taskType, locTypeHeight, laneRowList, currentLev);
                //获取库位
                if (!globalLoc.isEmpty()) {
                    defaultLoc = locUtils.filterAllLoc(globalLoc);
                    if(defaultLoc != null) {
                    if (defaultLoc != null) {
                        return defaultLoc;
                    }
                }
@@ -232,7 +280,7 @@
        Task task = new Task();
        task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号
        task.setTaskSts(1L);//1.生成入库任务
        task.setTaskSts(TaskStsType.GENERATE_IN.id);//1.生成入库任务
        task.setTaskType(taskType.getId());//任务类型
        task.setIoPri(this.generateIoPri(taskType.getId()));//优先级
        task.setOriginLoc(null);
@@ -341,7 +389,7 @@
        Task task = new Task();
        task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号
        task.setTaskSts(1L);//1.生成入库任务
        task.setTaskSts(TaskStsType.GENERATE_IN.id);//1.生成入库任务
        task.setTaskType(taskType.getId());//任务类型
        task.setIoPri(this.generateIoPri(taskType.getId()));//优先级
        task.setOriginLoc(null);
@@ -379,10 +427,15 @@
        if (task.getTaskType() < 100) {
            //入库
            task.setTaskSts(99L);//99.入库完成
            task.setTaskSts(TaskStsType.COMPLETE_IN.id);//99.入库完成
        }else {
            //出库
            task.setTaskSts(199L);//199.出库完成
            TaskDetl taskDetl = taskDetls.get(0);
            if (taskDetl.getWaveId() == null) {
                task.setTaskSts(TaskStsType.COMPLETE_OUT.id);//199.出库完成
            }else {
                task.setTaskSts(TaskStsType.WAVE_SEED.id);//198.播种中
            }
        }
        task.setUpdateTime(new Date());
@@ -439,7 +492,68 @@
                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;
            case 11://库位移转
                Loc originLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()));
                if(originLoc == null){
                    throw new CoolException("源库位不存在");
                }
                if (originLoc.getLocStsId() != LocStsType.R.val()) {
                    throw new CoolException("源库位状态不处于R.出库预约");
                }
                loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc()));
                if(loc == null){
                    throw new CoolException("目标库位不存在");
                }
                if(loc.getLocStsId() != LocStsType.S.val()){
                    throw new CoolException("目标库位状态不处于S.入库预约");
                }
                originLoc.setLocStsId(LocStsType.F.val());
                originLoc.setUpdateTime(new Date());
                if(!locService.updateById(originLoc)){
                    throw new CoolException("库位状态变更失败");
                }
                loc.setLocStsId(LocStsType.O.val());
                loc.setUpdateTime(new Date());
                if(!locService.updateById(loc)){
                    throw new CoolException("库位状态变更失败");
                }
                break;
        }
        //数据保存至历史档
        TaskLog taskLog = new TaskLog();
        taskLog.sync(task);
        taskLog.setId(null);
        if (!taskLogService.save(taskLog)) {
            throw new CoolException("任务档案转历史档案失败");
        }
        //删除任务
        boolean removeTask = taskService.removeById(taskId);
        if(!removeTask){
            throw new CoolException("回滚任务失败");
        }
        if (task.getTaskType() != 10) {
@@ -450,17 +564,8 @@
            //回滚订单
            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 (taskDetl.getDetlId() != null) {
                    orderUtils.updateWorkQty(taskDetl.getDetlId(), taskDetl.getAnfme(), false);
                }
                //入库回滚组托通知档
@@ -478,11 +583,28 @@
                    }
                }
                //明细数据保存至历史档
                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("明细扩展字段转历史档案失败");
                    }
@@ -493,34 +615,247 @@
                        throw new CoolException("回滚扩展明细失败");
                    }
                }
            }
        }
        return true;
    }
                //明细数据保存至历史档
                TaskDetlLog taskDetlLog = new TaskDetlLog();
                taskDetlLog.sync(taskDetl);
                if (!taskDetlLogService.save(taskDetlLog)) {
                    throw new CoolException("明细数据转历史档案失败");
    @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(TaskStsType.GENERATE_IN.id);//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;
    }
    @Override
    @Transactional
    public boolean locAdjust(LocAdjustParam param) {
        if (param == null) {
            throw new CoolException("参数不能为空");
        }
        if (Cools.isEmpty(param.getLocNo())) {
            throw new CoolException("库位号不能为空");
        }
        if (param.getDetls() == null) {
            throw new CoolException("库存明细不能为空");
        }
        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, param.getLocNo()));
        if (loc == null) {
            throw new CoolException("库位不存在");
        }
        //删除源库存
        locDetlService.removeLocDetl(loc.getId());
        List<MatField> matFields = matFieldService.list(new LambdaQueryWrapper<MatField>().eq(MatField::getUnique, 1));
        for (Map<String, Object> map : param.getDetls()) {
            LocDetl locDetl = JSON.parseObject(JSON.toJSONString(map), LocDetl.class);
            HashMap<String, Object> uniqueFields = new HashMap<>();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                for (MatField field : matFields) {
                    if (entry.getKey().equals(field.getName())) {
                        uniqueFields.put(entry.getKey(), entry.getValue());
                    }
                }
            }
            locDetl.setAnfme(Double.parseDouble(map.get("qty").toString()));
            locDetl.syncFieldMap(uniqueFields);
                //删除明细
                boolean removeDetl = taskDetlService.removeById(taskDetl.getId());
                if(!removeDetl){
                    throw new CoolException("回滚明细失败");
            if (locDetl.getAnfme() <= 0D) {
                throw new CoolException("数量不能小于0");
            }
            locDetl.setId(null);
            locDetl.setLocId(loc.getId());
            locDetl.setLocNo(loc.getLocNo());
            boolean save = locDetlService.save(locDetl);
            if (!save) {
                throw new CoolException("库存调整失败");
            }
            //插入库存明细字段
            for (MatField matField : matFields) {
                LocDetlField locDetlField = new LocDetlField();
                locDetlField.setDetlId(locDetl.getId());
                locDetlField.setFieldId(matField.getId());
                locDetlField.setName(matField.getName());
                locDetlField.setValue(Optional.ofNullable(uniqueFields.get(matField.getName()).toString()).orElse(""));
                locDetlFieldService.save(locDetlField);
            }
        }
        return true;
    }
    @Override
    @Transactional
    public boolean locTransfer(LocTransferParam param) {
        if (param == null) {
            throw new CoolException("参数不能为空");
        }
        if (Cools.isEmpty(param.getSourceLocNo())) {
            throw new CoolException("源库位不能为空");
        }
        if (Cools.isEmpty(param.getTargetLocNo())) {
            throw new CoolException("目标库位不能为空");
        }
        Loc sourceLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, param.getSourceLocNo()));
        if (sourceLoc == null) {
            throw new CoolException("源库位不存在");
        }
        if (sourceLoc.getLocStsId() != LocStsType.F.val()) {
            throw new CoolException("源库位非在库状态");
        }
        Loc targetLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, param.getTargetLocNo()));
        if (targetLoc == null) {
            throw new CoolException("目标库位不存在");
        }
        if(targetLoc.getLocStsId() != LocStsType.O.val()){
            throw new CoolException("目标库位非空状态");
        }
        TaskType taskType = taskTypeService.getById(11);
        if (taskType == null) {
            throw new CoolException("任务类型不存在");
        }
        Task task = new Task();
        task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号
        task.setTaskSts(TaskStsType.GENERATE_IN.id);//1.生成入库任务
        task.setTaskType(taskType.getId());//任务类型
        task.setIoPri(this.generateIoPri(taskType.getId()));//优先级
        task.setOriginLoc(param.getSourceLocNo());
        task.setTargetLoc(param.getTargetLocNo());
        task.setOriginSite(null);
        task.setTargetSite(null);
        task.setBarcode(sourceLoc.getBarcode());//托盘码
        boolean taskSave = taskService.save(task);
        if (!taskSave) {
            throw new CoolException("任务生成失败");
        }
        List<LocDetl> locDetls = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, sourceLoc.getId()));
        if(locDetls.isEmpty()){
            throw new CoolException("源库位明细不存在");
        }
        //生成任务明细
        for (LocDetl locDetl : locDetls) {
            TaskDetl taskDetl = new TaskDetl();
            taskDetl.setTaskId(task.getId());
            taskDetl.setTaskNo(task.getTaskNo());
            taskDetl.setAnfme(locDetl.getAnfme());//数量
            taskDetl.setStock(0D);//库存
            taskDetl.setBatch(locDetl.getBatch());//批号
            taskDetl.setBarcode(sourceLoc.getBarcode());
            taskDetl.setMatId(locDetl.getMatId());
            taskDetl.setMatnr(locDetl.getMatnr());
            boolean taskDetlSave = taskDetlService.save(taskDetl);
            if(!taskDetlSave){
                throw new CoolException("任务明细生成失败");
            }
            //生成明细扩展
            List<LocDetlField> locDetlFieldList = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()));
            for (LocDetlField locDetlField : locDetlFieldList) {
                TaskDetlField taskDetlField = new TaskDetlField();
                taskDetlField.setName(locDetlField.getName());
                taskDetlField.setFieldId(locDetlField.getFieldId());
                taskDetlField.setDetlId(taskDetl.getId());
                taskDetlField.setValue(locDetlField.getValue());
                boolean taskDetlFieldSave = taskDetlFieldService.save(taskDetlField);
                if(!taskDetlFieldSave){
                    throw new CoolException("明细扩展生成失败");
                }
            }
        }
        //数据保存至历史档
        TaskLog taskLog = new TaskLog();
        taskLog.sync(task);
        if (!taskLogService.save(taskLog)) {
            throw new CoolException("任务档案转历史档案失败");
        //库位F => R
        sourceLoc.setLocStsId(LocStsType.R.val());
        sourceLoc.setUpdateTime(new Date());
        boolean sourceLocUpdate = locService.updateById(sourceLoc);
        if(!sourceLocUpdate){
            throw new CoolException("库位状态更新失败");
        }
        //删除任务
        boolean removeTask = taskService.removeById(taskId);
        if(!removeTask){
            throw new CoolException("回滚任务失败");
        //库位O => S
        targetLoc.setLocStsId(LocStsType.S.val());
        targetLoc.setUpdateTime(new Date());
        boolean targetLocUpdate = locService.updateById(targetLoc);
        if(!targetLocUpdate){
            throw new CoolException("库位状态更新失败");
        }
        return true;