Commit 38026629 zshaohui

odn出库 挑料逻辑提交

1 个父辈 0b074730
...@@ -23,7 +23,6 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager; ...@@ -23,7 +23,6 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager; import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder; import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem; import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.order.util.CombinationUtil;
import com.neotel.smfcore.core.storage.bean.InventoryItem; import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE; import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager; import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
...@@ -38,15 +37,12 @@ import com.neotel.smfcore.custom.lizhen.innerBox.util.StorageExportUtil; ...@@ -38,15 +37,12 @@ import com.neotel.smfcore.custom.lizhen.innerBox.util.StorageExportUtil;
import com.neotel.smfcore.custom.lizhen.third.maicheng.api.MaiZhengApi; import com.neotel.smfcore.custom.lizhen.third.maicheng.api.MaiZhengApi;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi; import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.FetchHoldInfoRequest; import com.neotel.smfcore.custom.luxsan.api.bean.request.FetchHoldInfoRequest;
import com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickLabelList;
import com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickRequest; import com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickRequest;
import com.neotel.smfcore.custom.luxsan.api.bean.result.FetchHoldInfoResult; import com.neotel.smfcore.custom.luxsan.api.bean.result.FetchHoldInfoResult;
import com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil; import com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.common.util.DisableBarcodeUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.enums.LiteorderCheckType; import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.enums.LiteorderCheckType;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.enums.TaskCurrentLoc; import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.enums.TaskCurrentLoc;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.util.BinCacheUtil; import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.util.BinCacheUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.util.BoxHandleUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TaskLocUtil; import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TaskLocUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -1430,7 +1426,6 @@ public class LiteOrderCache { ...@@ -1430,7 +1426,6 @@ public class LiteOrderCache {
log.info("开始执行工单:" + orderNo); log.info("开始执行工单:" + orderNo);
cacheOrder.setTaskReelCount(0); cacheOrder.setTaskReelCount(0);
cacheOrder.setFinishedReelCount(0); cacheOrder.setFinishedReelCount(0);
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType(); CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> storageIdList = new ArrayList<>(); List<String> storageIdList = new ArrayList<>();
...@@ -1438,94 +1433,118 @@ public class LiteOrderCache { ...@@ -1438,94 +1433,118 @@ public class LiteOrderCache {
storageIdList.add(storage.getId()); storageIdList.add(storage.getId());
} }
int taskReelCount = 0;
List<String> holdPosIdList = getHoldPosIdList(cacheOrder);
//查找所有的任务 //查找所有的任务
List<DataLog> dataLogList = new ArrayList<>(); List<DataLog> dataLogList = new ArrayList<>();
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) { for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
String partNumber = orderItem.getPn();
int taskNum = 0;
int remainNum = orderItem.getNeedNum() - orderItem.getTotalOutNum(); int remainNum = orderItem.getNeedNum() - orderItem.getTotalOutNum();
if (remainNum <= 0) {
continue;
}
String pn = orderItem.getPn();
String warehouseCode = orderItem.getWarehouseCode();
List<StoragePos> needOutPosList = new ArrayList<>();
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePos storagePos : storagePosList) {
Barcode barcode = storagePos.getBarcode();
if (barcode.getPartNumber().equals(pn) && barcode.getWarehouseCode().equals(warehouseCode)) {
if (holdPosIdList != null && !holdPosIdList.isEmpty()) {
if (holdPosIdList.contains(storagePos.getId())) {
throw new ValidateException("", barcode.getPalletId() + "被hold,不允许出库");
}
}
if (dataLogList != null && !dataLogList.isEmpty()) {
for (DataLog dataLog : dataLogList) {
if (storagePos.getId().equals(dataLog.getPosId())) {
log.info(storagePos.getPosName() + "已经在任务列表中,跳过");
continue;
//throw new ValidateException("", barcode.getPalletId()+"已在任务列表中,不允许出库");;
}
}
}
needOutPosList.add(storagePos);
}
}
}
while (taskNum < remainNum) { if (needOutPosList != null && !needOutPosList.isEmpty()) {
List<Barcode> barcodeList = needOutPosList.stream().map(StoragePos::getBarcode).collect(Collectors.toList());
int count = barcodeList.stream().collect(Collectors.summingInt(Barcode::getQty));
if (count > remainNum) {
throw new ValidateException("", "手动输入的料箱号数量为:" + count + "大于实际需要的数量:" + remainNum + "料号为:" + pn + "库别为:" + warehouseCode);
}
remainNum = (remainNum - count);
}
log.info(orderNo + "已分配数量为:"+taskNum+",剩余数量为:"+remainNum); if (remainNum > 0) {
Collection<String> excludePosIds = excludeOutPosIds(); Collection<String> excludePosIds = excludeOutPosIds();
if (dataLogList != null && !dataLogList.isEmpty()){ if (dataLogList != null && !dataLogList.isEmpty()) {
for (DataLog dataLog : dataLogList) { for (DataLog dataLog : dataLogList) {
excludePosIds.add(dataLog.getPosId()); excludePosIds.add(dataLog.getId());
} }
} }
//1.先从执行的料箱中出库 //查找符合条件的库位
StoragePos pos = null; Criteria c = Criteria.where("barcode.partNumber").is(pn)
if (storagePosList != null && !storagePosList.isEmpty()) { .and("id").nin(excludePosIds)
for (StoragePos storagePos : storagePosList) { .and("enabled").is(true)
if (excludePosIds.contains(storagePos.getId())) { .and("storageId").in(storageIdList)
continue; .and("barcode.warehouseCode").is(warehouseCode);
}
if (partNumber.equals(storagePos.getBarcode().getPartNumber())) {
pos = storagePos;
break;
}
}
}
if (pos == null) { List<StoragePos> posList = storagePosManager.findByQuery(new Query(c));
pos = storagePosManager.findPartNumberInStorages(storageIdList, partNumber, excludePosIds, checkoutType, orderItem.getBrand(),orderItem.getWarehouseCode()); if (posList == null || posList.isEmpty()) {
throw new ValidateException("", "料号:" + pn + ",库别:" + warehouseCode + "未找到可用出库的物料");
} }
if (pos == null) {
break; List<StoragePos> targetPos = findTargetPos(posList, remainNum);
} else { if (targetPos == null || targetPos.isEmpty()) {
Barcode barcode = pos.getBarcode(); throw new ValidateException("", "料号:" + pn + ",库别:" + warehouseCode + "未找到符合出库的组合");
log.info(barcode.getBarcode() + "需要生成出库任务,工单号为:" + orderNo+",数量为:"+barcode.getQty());
taskNum = taskNum + barcode.getQty();
taskReelCount = taskReelCount + 1;
DataLog task = newTask(pos);
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getFeederInfo());
task.setType(OP.CHECKOUT);
task.setStatus(OP_STATUS.WAIT.name());
task.setLoc(TaskLocUtil.OUT);
if (StringUtils.isNotEmpty(barcode.getCartonId())){
task.setCartonId(barcode.getCartonId());
}
task.setOdn(true);
dataLogList.add(task);
} }
needOutPosList.addAll(targetPos);
} }
//如果数量不满足,则提示出来 for (StoragePos pos : needOutPosList) {
if (taskNum < remainNum){ Storage storage = dataCache.getStorageById(pos.getStorageId());
finishedOrderTasks(cacheOrder); Barcode barcode = pos.getBarcode();
throw new ValidateException("", orderItem.getPn()+"库存不足,odn:"+cacheOrder.getOrderNo()+"无法进行出库"); DataLog dataLog = new DataLog(storage, barcode, pos);
dataLog.setSubSourceId(orderItem.getId());
dataLog.setSourceName(cacheOrder.getOrderNo());
dataLog.setSourceId(cacheOrder.getId());
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLog.setType(OP.CHECKOUT);
dataLog.setLoc(TaskLocUtil.OUT);
if (StringUtils.isNotEmpty(barcode.getCartonId())) {
dataLog.setCartonId(barcode.getCartonId());
}
dataLog.setOdn(true);
dataLogList.add(dataLog);
} }
}
for (DataLog dataLog : dataLogList) {
taskService.addTaskToExecute(dataLog);
} }
if (taskReelCount <= 0) {
log.info("工单:" + orderNo + "没有找到对应的任务");
finishedOrderTasks(cacheOrder);
throw new ValidateException("smfcore.order.out.noTask", "工单无可执行的任务");
}
if (dataLogList == null || dataLogList.isEmpty()){
log.info("工单:" + orderNo + "没有找到对应的任务");
//finishedOrderTasks(cacheOrder);
throw new ValidateException("smfcore.order.out.noTask", "工单无可执行的任务");
}
Collection newDataLogList = taskService.batchSave(dataLogList);
cacheOrder.setTaskReelCount(taskReelCount); cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
cacheOrder.setTaskReelCount(dataLogList.size());
liteOrderManager.save(cacheOrder); liteOrderManager.save(cacheOrder);
liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder); liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
log.info("生成工单" + orderNo + "任务结束,数量为:" + dataLogList.size());
log.info("生成工单" + orderNo + "任务结束,数量为:" + taskReelCount);
} }
...@@ -2106,7 +2125,7 @@ public class LiteOrderCache { ...@@ -2106,7 +2125,7 @@ public class LiteOrderCache {
private List<String> getHoldPosIdList(LiteOrder cacheOrder) { private List<String> getHoldPosIdList(LiteOrder cacheOrder) {
//如果是hold的,判断有没有符合的条件 //如果是hold的,判断有没有符合的条件
List<String> holdPosIdList = new ArrayList<>(); List<String> holdPosIdList = new ArrayList<>();
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) { /*for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
String warehouseCode = StringUtils.isNotEmpty(orderItem.getSrcWarehouse()) ? orderItem.getSrcWarehouse() : orderItem.getWarehouseCode(); String warehouseCode = StringUtils.isNotEmpty(orderItem.getSrcWarehouse()) ? orderItem.getSrcWarehouse() : orderItem.getWarehouseCode();
...@@ -2124,7 +2143,35 @@ public class LiteOrderCache { ...@@ -2124,7 +2143,35 @@ public class LiteOrderCache {
} }
} }
} }
} }*/
return holdPosIdList; return holdPosIdList;
} }
private List<StoragePos> findTargetPos(List<StoragePos> numbers, int targetNum) {
numbers.sort((a, b) -> Integer.valueOf(b.getBarcode().getQty()).compareTo(Integer.valueOf(a.getBarcode().getQty())));
//System.out.println(numbers);
int target = targetNum;
List<StoragePos> result = new ArrayList<>();
for (int i = 0; i < 3000; i++) {
boolean notFound = true;
Iterator<StoragePos> iterator = numbers.iterator();
while (iterator.hasNext()) {
StoragePos pos = iterator.next();
if (pos.getBarcode().getQty() <= target) { // 假设我们要删除值为3的元素
result.add(pos);
notFound = false;
iterator.remove();
target = target - pos.getBarcode().getQty();
break;
}
}
if (notFound) {
break;
}
}
if (target == 0) {
return result;
}
return new ArrayList<>();
}
} }
package com.neotel.smfcore.core.order.util;
import java.util.ArrayList;
import java.util.List;
public class CombinationUtil {
private static void backtrack(List<Integer> numbers, int targetSum, int start, List<Integer> current, List<List<Integer>> combinations, boolean used[]) {
if (targetSum == 0) {
combinations.add(new ArrayList<>(current));
return;
}
if (targetSum < 0 || start >= numbers.size()) {
return;
}
for (int i = start; i < numbers.size(); i++) {
// 如果不允许重复使用数字,并且当前数字已经被使用过,则跳过
if (used != null && used[i]) {
continue;
}
// 选择当前数字
current.add(numbers.get(i));
// 如果不允许重复使用数字,则标记当前数字为已使用
if (used != null) {
used[i] = true;
}
// 递归调用,继续查找剩余的数字
backtrack(numbers, targetSum - numbers.get(i), i + 1, current, combinations, used);
// 回溯,移除当前选择的数字
current.remove(current.size() - 1);
// 如果不允许重复使用数字,则取消标记
if (used != null) {
used[i] = false;
}
}
}
// 如果不允许重复使用数字,可以使用以下版本的findCombinations方法
public static List<List<Integer>> findCombinationsWithoutDuplicates(List<Integer> numbers, int targetSum) {
boolean[] used = new boolean[numbers.size()];
return findCombinations(numbers, targetSum, used);
}
// 带有used数组的findCombinations方法
private static List<List<Integer>> findCombinations(List<Integer> numbers, int targetSum, boolean[] used) {
List<List<Integer>> combinations = new ArrayList<>();
backtrack(numbers, targetSum, 0, new ArrayList<>(), combinations, used);
return combinations;
}
}
...@@ -1338,4 +1338,12 @@ public class TaskService { ...@@ -1338,4 +1338,12 @@ public class TaskService {
public void outTaskStatusChange(List<DataLog> dataLogList) { public void outTaskStatusChange(List<DataLog> dataLogList) {
smfApi.outTaskStatusChange(dataLogList); smfApi.outTaskStatusChange(dataLogList);
} }
public Collection<DataLog> batchSave(List<DataLog> dataLogList) {
Collection<DataLog> dataLogs = dataLogDao.insertAll(dataLogList);
for (DataLog task : dataLogs) {
taskMap.put(task.getId(), task);
}
return dataLogs;
}
} }
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!