| package com.zy.asrs.wms.asrs.service.impl;  | 
|   | 
| import com.alibaba.fastjson.JSON;  | 
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;  | 
| import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;  | 
| import com.zy.asrs.framework.common.Cools;  | 
| import com.zy.asrs.framework.common.DateUtils;  | 
| import com.zy.asrs.framework.exception.CoolException;  | 
| import com.zy.asrs.wms.asrs.entity.*;  | 
| 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.slf4j.Logger;  | 
| import org.slf4j.LoggerFactory;  | 
| import org.springframework.beans.factory.annotation.Autowired;  | 
| import org.springframework.stereotype.Service;  | 
| import org.springframework.transaction.annotation.Transactional;  | 
|   | 
| import java.util.*;  | 
|   | 
| @Service("workService")  | 
| public class WorkServiceImpl implements WorkService {  | 
|   | 
|     public static final Logger logger = LoggerFactory.getLogger(WorkServiceImpl.class);  | 
|   | 
|     @Autowired  | 
|     private TaskService taskService;  | 
|     @Autowired  | 
|     private TaskDetlService taskDetlService;  | 
|     @Autowired  | 
|     private WaitPakinService waitPakinService;  | 
|     @Autowired  | 
|     private TaskTypeService taskTypeService;  | 
|     @Autowired  | 
|     private OrderDetlFieldService orderDetlFieldService;  | 
|     @Autowired  | 
|     private TaskDetlFieldService taskDetlFieldService;  | 
|     @Autowired  | 
|     private OrderService orderService;  | 
|     @Autowired  | 
|     private OrderDetlService orderDetlService;  | 
|     @Autowired  | 
|     private LocService locService;  | 
|     @Autowired  | 
|     private LocDetlService locDetlService;  | 
|     @Autowired  | 
|     private LocDetlFieldService locDetlFieldService;  | 
|     @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;  | 
|     @Autowired  | 
|     private MatFieldService matFieldService;  | 
|   | 
|     @Override  | 
|     public String generateTaskNo(Long taskType) {  | 
|         String format = DateUtils.format(new Date(), "MMddHHmm");  | 
|         Random random = new Random();  | 
|         int nextInt = random.nextInt(99999);  | 
|         logger.info("R" + format + nextInt);  | 
|         return "R" + format + nextInt;  | 
|     }  | 
|   | 
|     @Override  | 
|     public Integer generateIoPri(Long taskType) {  | 
|         return 10;  | 
|     }  | 
|   | 
|     @Override  | 
|     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("未配置上架规则");  | 
|         }  | 
|         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)) {  | 
|                 return locUtils.getGlobalEmptyLocToCtu(locTypeHeight);  | 
|                 //从全局库位中获取(完整巷道)  | 
| //                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)) {  | 
|                 return locUtils.getGlobalEmptyLocToCtu(locTypeHeight);  | 
|                 //从全局库位中获取(完整巷道)  | 
| //                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(rollbackFor = Exception.class)  | 
|     public boolean generatePakIn(GeneratePakInParam param) {  | 
|         List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, param.getBarcode()));  | 
|         if (param.getTaskType() != 10 && waitPakins.isEmpty()) {  | 
|             throw new CoolException("托盘未组托");  | 
|         }  | 
|   | 
|         TaskType taskType = taskTypeService.getById(param.getTaskType());  | 
|         if (taskType == null) {  | 
|             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(), param.getBarcode(), param.getLocTypeHeight());  | 
|         if (loc == null) {  | 
|             throw new CoolException("没有空库位");  | 
|         }  | 
|   | 
|         Task task = new Task();  | 
|         //任务号  | 
|         task.setTaskNo(this.generateTaskNo(taskType.getId()));  | 
|         //1.生成入库任务  | 
|         task.setTaskSts(TaskStsType.GENERATE_IN.id);  | 
|         //任务类型  | 
|         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(param.getBarcode());  | 
|         boolean taskSave = taskService.save(task);  | 
|         if (!taskSave) {  | 
|             throw new CoolException("任务生成失败");  | 
|         }  | 
|   | 
|         //生成任务明细  | 
|         for (WaitPakin waitPakin : waitPakins) {  | 
|             TaskDetl taskDetl = new TaskDetl();  | 
|             taskDetl.setTaskId(task.getId());  | 
|             taskDetl.setTaskNo(task.getTaskNo());  | 
|             //数量  | 
|             taskDetl.setAnfme(waitPakin.getAnfme());  | 
|             //库存  | 
|             taskDetl.setStock(0D);  | 
|             //批号  | 
|             taskDetl.setBatch(waitPakin.getDetl$().getBatch());  | 
|             taskDetl.setBarcode(waitPakin.getBarcode());  | 
|             taskDetl.setOrderId(waitPakin.getOrderId());  | 
|             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("任务明细生成失败");  | 
|             }  | 
|   | 
|             //生成明细扩展  | 
|             List<OrderDetlField> orderDetlFields = orderDetlFieldService.list(new LambdaQueryWrapper<OrderDetlField>().eq(OrderDetlField::getDetlId, waitPakin.getDetlId()));  | 
|             for (OrderDetlField orderDetlField : orderDetlFields) {  | 
|                 TaskDetlField taskDetlField = new TaskDetlField();  | 
|                 taskDetlField.setName(orderDetlField.getName());  | 
|                 taskDetlField.setFieldId(orderDetlField.getFieldId());  | 
|                 taskDetlField.setDetlId(taskDetl.getId());  | 
|                 taskDetlField.setValue(orderDetlField.getValue());  | 
|                 boolean taskDetlFieldSave = taskDetlFieldService.save(taskDetlField);  | 
|                 if (!taskDetlFieldSave) {  | 
|                     throw new CoolException("明细扩展生成失败");  | 
|                 }  | 
|             }  | 
|   | 
|             //更新组托通知档  | 
|             waitPakin.setIoStatus(1);  | 
|             waitPakin.setUpdateTime(new Date());  | 
|             boolean waitPakinUpdate = waitPakinService.updateById(waitPakin);  | 
|             if (!waitPakinUpdate) {  | 
|                 throw new CoolException("组托通知档更新失败");  | 
|             }  | 
|   | 
|             //更新订单明细数据  | 
|             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("订单明细更新失败");  | 
|             }  | 
|   | 
|             //获取订单  | 
|             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("订单数据更新失败");  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|         //库位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 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(TaskStsType.GENERATE_IN.id);//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("任务不存在");  | 
|         }  | 
|   | 
|         List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId);  | 
|         if (taskDetls.isEmpty()) {  | 
|             throw new CoolException("任务明细不存在");  | 
|         }  | 
|   | 
|         if (task.getTaskType() < 100) {  | 
|             //入库  | 
|             task.setTaskSts(TaskStsType.COMPLETE_IN.id);//99.入库完成  | 
|         } else {  | 
|             //出库  | 
|             TaskDetl taskDetl = taskDetls.get(0); //TODO  出库流程待确认,ESS取货后,输送线流转到扫码处状态  | 
|             if (taskDetl.getWaveId() == null && task.getTaskType() != 103 && task.getTaskType() != 107) {  | 
|                 task.setTaskSts(TaskStsType.COMPLETE_OUT.id);//199.出库完成  | 
|             } else {  | 
|                 task.setTaskSts(TaskStsType.WAVE_SEED.id);//198.播种中  | 
|             }  | 
|         }  | 
|         task.setUpdateTime(new Date());  | 
|         if (!taskService.updateById(task)) {  | 
|             throw new CoolException("任务更新失败");  | 
|         }  | 
|   | 
|         return true;  | 
|     }  | 
|   | 
|     @Override  | 
|     @Transactional(rollbackFor = Exception.class)  | 
|     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://盘点  | 
|                 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.入库预约");  | 
|                 }  | 
|                 loc.setLocStsId(LocStsType.O.val());  | 
|                 loc.setUpdateTime(new Date());  | 
|                 if (!locService.updateById(loc)) {  | 
|                     throw new CoolException("库位状态变更失败");  | 
|                 }  | 
|                 break;  | 
|             case 101://出库  | 
|             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("库位不存在");  | 
|                 }  | 
|                 if (loc.getLocStsId() != LocStsType.R.val()) {  | 
|                     throw new CoolException("库位状态不处于R.出库预约");  | 
|                 }  | 
|                 loc.setLocStsId(LocStsType.F.val());  | 
|                 loc.setUpdateTime(new Date());  | 
|                 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) {  | 
|             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  | 
|     @Transactional(rollbackFor = Exception.class)  | 
|     public boolean pickTask(Long taskId) {  | 
|         Task task = taskService.getById(taskId);  | 
|         if (task == null) {  | 
|             throw new CoolException("任务不存在");  | 
|         }  | 
|   | 
|         if (task.getTaskType() != 103 && task.getTaskType() != 107) {  | 
|             throw new CoolException("任务类型不可拣料");  | 
|         }  | 
|   | 
|         if (task.getTaskSts() != 198) {  | 
|             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);  | 
|         //生成新的库位 !important  | 
| //        Loc loc = this.generateLoc(taskType, taskDetl.getMatId(), taskDetl.getBatch(), taskDetl.getUniqueField(), locTypeHeightType.id);  | 
| //        if(loc == null) {  | 
| //            throw new CoolException("没有空库位");  | 
| //        }  | 
|         Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()));  | 
|         if (loc == null) {  | 
|             throw new CoolException("没有空库位");  | 
|         }  | 
|         // 获取新任务号  | 
|         String taskNo = generateTaskNo(53L);  | 
|         // 设置新任务号  | 
|         task.setTaskNo(taskNo);  | 
|         //102拣料此处需修改为WCS_CONTAINER_RECEIVE,定时任务查询后,自动下发入库任务至ESS  | 
|         task.setTaskSts(TaskStsType.GENERATE_IN.id);//1.生成入库任务  | 
|         task.setTaskType(taskType);  | 
|         //原库位变目标库位, 原站点变目标站点  | 
|         //todo 需确认原站点为空,该怎么处理  | 
|         task.setTargetLoc(task.getOriginLoc());  | 
|         task.setUpdateTime(new Date());  | 
|         if (!taskService.updateById(task)) {  | 
|             throw new CoolException("拣料失败");  | 
|         }  | 
|         // 更新任务明细新任务号  | 
|         UpdateWrapper<TaskDetl> updateWrapper = new UpdateWrapper<>();  | 
|         updateWrapper.set("task_no",taskNo).eq("task_id",task.getId());  | 
|         //库位状态改为预约入库 R => S  | 
|         loc.setLocStsId(LocStsType.S.val());  | 
|         loc.setUpdateTime(new Date());  | 
|         boolean locUpdate = locService.updateById(loc);  | 
|         if (!locUpdate) {  | 
|             throw new CoolException("库位状态更新失败");  | 
|         }  | 
|   | 
|         return true;  | 
|     }  | 
|   | 
|     @Override  | 
|     @Transactional(rollbackFor = Exception.class)  | 
|     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);  | 
|   | 
|             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("明细扩展生成失败");  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|         //库位F => R  | 
|         sourceLoc.setLocStsId(LocStsType.R.val());  | 
|         sourceLoc.setUpdateTime(new Date());  | 
|         boolean sourceLocUpdate = locService.updateById(sourceLoc);  | 
|         if (!sourceLocUpdate) {  | 
|             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;  | 
|     }  | 
| }  |