opt:优化称重同步功能;
This commit is contained in:
@@ -63,14 +63,16 @@ public class EndDecisionChainer extends DecisionerChain<List> {
|
||||
List<String> structs = new ArrayList<>();
|
||||
//入库分配
|
||||
if (in_storage) {
|
||||
//混托任务判断
|
||||
//非异常任务,且是混托任务判断,直接返回库位
|
||||
if (startParam.getString("vehicle_code").contains("T")) {
|
||||
List<SchBaseTask> schBaseTaskList = iSchBaseTaskService.list(new QueryWrapper<SchBaseTask>()
|
||||
.eq("vehicle_code", startParam.getString("vehicle_code")).select("point_code2")
|
||||
.lt("status", StatusEnum.FORM_STATUS.code("完成")));
|
||||
if (CollectionUtil.isNotEmpty(schBaseTaskList)) {
|
||||
structs.add(schBaseTaskList.get(0).getPoint_code2());
|
||||
return structs;
|
||||
if (!"errorTask".equals(startParam.getString("errorTask"))) {
|
||||
structs.add(schBaseTaskList.get(0).getPoint_code2());
|
||||
return structs;
|
||||
}
|
||||
}
|
||||
}
|
||||
StIvtStructattr struct = (StIvtStructattr) transfers.get(0);
|
||||
|
||||
@@ -48,14 +48,12 @@ public class AlleyAveRuleHandler extends Decisioner<StIvtStructattr, JSONObject>
|
||||
@Override
|
||||
public List<StIvtStructattr> handler(List<StIvtStructattr> list, JSONObject param) {
|
||||
// 判断仓位是否为空
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
if (ObjectUtils.isEmpty(list)) {
|
||||
log.error("均衡策略结果:载具号:" + param.getString("vehicle_code") + "当前分配策略无可用货位");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
long startTime1 = System.currentTimeMillis();
|
||||
if (ObjectUtils.isNotEmpty(list)) {
|
||||
//扩展库不需要均衡策略
|
||||
if ("LXBCP02".equals(list.get(0).getSect_code())) {
|
||||
}else {
|
||||
//扩展库和移库不需要均衡策略
|
||||
if ("LXBCP02".equals(list.get(0).getSect_code())||Boolean.parseBoolean(param.getString("is_move"))) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -93,7 +91,6 @@ public class AlleyAveRuleHandler extends Decisioner<StIvtStructattr, JSONObject>
|
||||
subList = subList.stream().filter(r -> !r.getStruct_code().equals(result.getStruct_code())).collect(Collectors.toList());
|
||||
}
|
||||
log.info("均衡策略结果:载具号:" + param.getString("vehicle_code") + "分配结果: " + subList.stream().map(StIvtStructattr::getStruct_code).collect(Collectors.toList()));
|
||||
log.info("均衡策略:载具号:" + param.getString("vehicle_code") + "获取仓位耗时:{}", System.currentTimeMillis() - startTime1);
|
||||
if (subList.size() == 0) {
|
||||
log.error("均衡策略结果:载具号:" + param.getString("vehicle_code") + "当前分配策略货位数量为0");
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -57,6 +57,7 @@ public class LimitStorageRuleHandler extends Decisioner<StIvtStructattr, JSONObj
|
||||
String vehicleCode = param.getString("vehicle_code");
|
||||
BmVehicleInfo vehileInfo = bmVehicleInfoService.vehileInfo(vehicleCode);
|
||||
// if (vehileInfo == null) {
|
||||
//
|
||||
// throw new BadRequestException("限位策略,当前载具信息不存在:" + vehicleCode + "!");
|
||||
// }
|
||||
//限位策略特殊处理
|
||||
@@ -99,7 +100,6 @@ public class LimitStorageRuleHandler extends Decisioner<StIvtStructattr, JSONObj
|
||||
vehicle.setW(0);
|
||||
vehicle.setL(0);
|
||||
vehicle.setWeight(0);
|
||||
|
||||
}
|
||||
BmVehicleInfo finalVehicle = vehicle;
|
||||
Predicate<StIvtStructattr> eqLimt = stIvtStructattr -> {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.nl.common.enums.StatusEnum;
|
||||
import org.nl.common.utils.SpringContextHolder;
|
||||
import org.nl.wms.decision_manage.handler.decisioner.Decisioner;
|
||||
@@ -14,10 +15,7 @@ import org.nl.wms.stor_manage.struct.service.IStIvtStructattrService;
|
||||
import org.nl.wms.stor_manage.struct.service.dao.StIvtStructattr;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*
|
||||
@@ -42,6 +40,73 @@ public class DepthPriorityHandler extends Decisioner<StIvtStructattr, JSONObject
|
||||
if (list.get(0).getStor_code().equals(StatusEnum.STOCK_INFO.code("托盘库")) || "LXBCP02".equals(list.get(0).getSect_code())) {
|
||||
return list;
|
||||
}
|
||||
//移库任务
|
||||
if (Boolean.parseBoolean(param.getString("is_move"))) {
|
||||
// 深货位
|
||||
List<StIvtStructattr> allDepCollectL1 = list.stream()
|
||||
.filter(a -> a.getRow_num() == 1)
|
||||
.collect(Collectors.toList());
|
||||
List<StIvtStructattr> allDepCollectL4 = list.stream()
|
||||
.filter(a -> a.getRow_num() == 4)
|
||||
.collect(Collectors.toList());
|
||||
// 浅货位
|
||||
List<StIvtStructattr> allShallowCollect = list.stream()
|
||||
.filter(a -> a.getRow_num() == 2 || a.getRow_num() == 3)
|
||||
.collect(Collectors.toList());
|
||||
List<StIvtStructattr> allShallowCollectL2 = list.stream()
|
||||
.filter(a -> a.getRow_num() == 2)
|
||||
.collect(Collectors.toList());
|
||||
List<StIvtStructattr> allShallowCollectL3 = list.stream()
|
||||
.filter(a ->a.getRow_num() == 3)
|
||||
.collect(Collectors.toList());
|
||||
Set<String> allShallowCollectSetL2 = allShallowCollectL2.stream()
|
||||
.map(r -> r.getCol_num() + "_" + r.getLayer_num())
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> allShallowCollectSetL3 = allShallowCollectL3.stream()
|
||||
.map(r -> r.getCol_num() + "_" + r.getLayer_num())
|
||||
.collect(Collectors.toSet());
|
||||
//过滤出无阻挡的全部深货位
|
||||
List<StIvtStructattr> allDepListL1 = allDepCollectL1.stream()
|
||||
.filter(r -> allShallowCollectSetL2.contains(r.getCol_num() + "_" + r.getLayer_num()))
|
||||
.collect(Collectors.toList());
|
||||
List<StIvtStructattr> allDepListL4 = allDepCollectL4.stream()
|
||||
.filter(r -> allShallowCollectSetL3.contains(r.getCol_num() + "_" + r.getLayer_num()))
|
||||
.collect(Collectors.toList());
|
||||
List<StIvtStructattr> alldepList =new ArrayList<>();
|
||||
alldepList.addAll(allDepListL1);
|
||||
alldepList.addAll(allDepListL4);
|
||||
List<StIvtStructattr> depCollect = alldepList.stream().filter(item -> item.getRow_num() == 1 && item.getLayer_num() >= 24 && item.getLayer_num() <= 31).collect(Collectors.toList());
|
||||
List<StIvtStructattr> shallowCollect = allShallowCollect.stream().filter(item -> item.getRow_num() == 2 && item.getLayer_num() >= 24 && item.getLayer_num() <= 31).collect(Collectors.toList());
|
||||
log.info("移库深位优先策略:载具号:{} 分配结果第一个: 全部深库位:{}, 全部浅库位:{}, 专属移库深库位:{}, 专属移库浅库位:{}",
|
||||
param.getString("vehicle_code"),
|
||||
alldepList.isEmpty() ? "无数据" : alldepList.get(0),
|
||||
allShallowCollect.isEmpty() ? "无数据" : allShallowCollect.get(0),
|
||||
depCollect.isEmpty() ? "无数据" : depCollect.get(0),
|
||||
shallowCollect.isEmpty() ? "无数据" : shallowCollect.get(0)
|
||||
);
|
||||
// 实现深位优先策略
|
||||
// 获取起始货位信息
|
||||
String startStructCode = param.getString("start_struct_code");
|
||||
String[] parts = startStructCode.split("-");
|
||||
// int p = Integer.parseInt(parts[0].replaceAll("\\D", ""));
|
||||
int l = Integer.parseInt(parts[1].replaceAll("\\D", ""));
|
||||
int c = Integer.parseInt(parts[2].replaceAll("\\D", ""));
|
||||
// 实现深位优先策略
|
||||
StIvtStructattr result = findBestStructByDeepFirstStrategy(alldepList, allShallowCollect, depCollect, shallowCollect, l, c);
|
||||
if (result != null) {
|
||||
log.info("移库深位优先策略:载具号:{} 分配结果: 存在深位并对应浅位无货的库位,分配仓位:{}", param.getString("vehicle_code"),result.getStruct_code());
|
||||
return Collections.singletonList(result);
|
||||
}
|
||||
log.info("移库深位优先策略:载具号:{} 分配结果: 不存在可用移库库位,查找入库库位", param.getString("vehicle_code"));
|
||||
} else {
|
||||
//入库任务
|
||||
//3,4排不限制移库专属
|
||||
List<StIvtStructattr> list2 = list.stream().filter(item -> item.getRow_num() > 2).collect(Collectors.toList());
|
||||
List<StIvtStructattr> list3 = list.stream().filter(item -> (item.getRow_num() < 3) && (item.getLayer_num() < 24 || item.getLayer_num() > 31)).collect(Collectors.toList());
|
||||
List<StIvtStructattr> list4 = new ArrayList<>(list2);
|
||||
list4.addAll(list3);
|
||||
list = list4;
|
||||
}
|
||||
long startTime1 = System.currentTimeMillis();
|
||||
List<StIvtStructattr> returnResult = new ArrayList<>();
|
||||
// 深货位
|
||||
@@ -52,6 +117,7 @@ public class DepthPriorityHandler extends Decisioner<StIvtStructattr, JSONObject
|
||||
List<StIvtStructattr> shallowCollect = list.stream()
|
||||
.filter(a -> a.getRow_num() == 2 || a.getRow_num() == 3)
|
||||
.collect(Collectors.toList());
|
||||
//找出深和浅货位都无货的深货位
|
||||
for (StIvtStructattr r : depCollect) {
|
||||
for (StIvtStructattr s : shallowCollect) {
|
||||
String depCode = r.getCol_num() + "-" + r.getLayer_num();
|
||||
@@ -136,7 +202,7 @@ public class DepthPriorityHandler extends Decisioner<StIvtStructattr, JSONObject
|
||||
.collect(Collectors.toList());
|
||||
combinedResult.addAll(intersection2);
|
||||
}
|
||||
if (combinedResult.size() < 30) {
|
||||
if (combinedResult.size() < 20) {
|
||||
ISchBaseTaskService iSchBaseTaskService = SpringContextHolder.getBean(ISchBaseTaskService.class);
|
||||
List<SchBaseTask> taskList = iSchBaseTaskService.list(
|
||||
new LambdaQueryWrapper<SchBaseTask>()
|
||||
@@ -144,11 +210,11 @@ public class DepthPriorityHandler extends Decisioner<StIvtStructattr, JSONObject
|
||||
.eq(SchBaseTask::getVehicle_code, param.getString("vehicle_code"))
|
||||
);
|
||||
if (CollectionUtils.isNotEmpty(taskList)) {
|
||||
taskList=taskList.stream()
|
||||
.filter(t -> t.getTask_type().equals(StatusEnum.IOBILL_TYPE_IN.code("生产入库"))||t.getTask_type().equals(StatusEnum.IOBILL_TYPE_IN.code("拣选回库")))
|
||||
taskList = taskList.stream()
|
||||
.filter(t -> t.getTask_type().equals(StatusEnum.IOBILL_TYPE_IN.code("生产入库")) || t.getTask_type().equals(StatusEnum.IOBILL_TYPE_IN.code("拣选回库")))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(taskList)) {
|
||||
log.error("深位优先策略:获取深货位有货且浅货位无货仓位:载具号:" + param.getString("vehicle_code") + "获取仓位失败,该策略对应库位已不足30个!");
|
||||
log.error("深位优先策略:获取深货位有货且浅货位无货仓位:载具号:" + param.getString("vehicle_code") + "获取仓位失败,该策略对应库位已不足20个!");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -161,5 +227,139 @@ public class DepthPriorityHandler extends Decisioner<StIvtStructattr, JSONObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 深位优先策略:寻找最佳货位
|
||||
*
|
||||
* @param depCollect 深货位集合(row_num=1)
|
||||
* @param shallowCollect 浅货位集合(row_num=2)
|
||||
* @param targetCol 目标列号
|
||||
* @param targetLayer 目标层号
|
||||
* @return 最佳匹配的货位
|
||||
*/
|
||||
private StIvtStructattr findBestStructByDeepFirstStrategy(List<StIvtStructattr> allDepCollect,
|
||||
List<StIvtStructattr> allShallowCollect,
|
||||
List<StIvtStructattr> depCollect,
|
||||
List<StIvtStructattr> shallowCollect,
|
||||
int targetCol,
|
||||
int targetLayer) {
|
||||
// 1. 先在深货位中查找相同列的货位
|
||||
StIvtStructattr result = findInCollectionWithSameColumn(depCollect,allDepCollect, targetCol, targetLayer);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
// 2. 如果深货位中没有,则在浅货位中查找相同列的货位
|
||||
result = findInCollectionWithSameColumn(shallowCollect,allShallowCollect, targetCol, targetLayer);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 如果都没有相同列,则查找最近的列(不需要排除层)
|
||||
result = findNearestColumn(depCollect,allDepCollect, targetCol, targetLayer);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
// 4. 最后尝试浅货位中最近的列
|
||||
result = findNearestColumn(shallowCollect,allShallowCollect, targetCol, targetLayer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在集合中查找相同列的货位,排除自身层和相邻层
|
||||
*
|
||||
* @param collection 货位集合
|
||||
* @param targetCol 目标列号
|
||||
* @param targetLayer 目标层号
|
||||
* @return 匹配的货位
|
||||
*/
|
||||
private StIvtStructattr findInCollectionWithSameColumn(List<StIvtStructattr> collection, List<StIvtStructattr> allCollect,
|
||||
int targetCol,
|
||||
int targetLayer) {
|
||||
// 筛选出相同列的货位
|
||||
List<StIvtStructattr> sameColList = collection.stream()
|
||||
.filter(item -> item.getCol_num() != null && item.getCol_num() == targetCol)
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtils.isEmpty(sameColList)) {
|
||||
sameColList = allCollect.stream()
|
||||
.filter(item -> item.getCol_num() != null && item.getCol_num() == targetCol)
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtils.isEmpty(sameColList)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 排除自身层和相邻层(targetLayer-1, targetLayer, targetLayer+1)
|
||||
List<StIvtStructattr> filteredList = sameColList.stream()
|
||||
.filter(item -> {
|
||||
Integer layer = item.getLayer_num();
|
||||
if (layer == null) {
|
||||
return false;
|
||||
}
|
||||
// 排除自身层和相邻层
|
||||
return Math.abs(layer - targetLayer) > 1;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (ObjectUtils.isEmpty(filteredList)) {
|
||||
return null;
|
||||
}
|
||||
// 找到与目标层数最接近的货位
|
||||
return filteredList.stream()
|
||||
.min((a, b) -> {
|
||||
int diffA = Math.abs(a.getLayer_num() - targetLayer);
|
||||
int diffB = Math.abs(b.getLayer_num() - targetLayer);
|
||||
return Integer.compare(diffA, diffB);
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在集合中查找最近的列(不需要排除层)
|
||||
*
|
||||
* @param collection 货位集合
|
||||
* @param targetCol 目标列号
|
||||
* @param targetLayer 目标层号
|
||||
* @return 匹配的货位
|
||||
*/
|
||||
private StIvtStructattr findNearestColumn(List<StIvtStructattr> collection, List<StIvtStructattr> allCollect,
|
||||
int targetCol,
|
||||
int targetLayer) {
|
||||
if (ObjectUtils.isEmpty(collection) && ObjectUtils.isEmpty(allCollect)) {
|
||||
return null;
|
||||
}
|
||||
// 按列号分组,找出与目标列差值最小的列
|
||||
Map<Integer, List<StIvtStructattr>> colGroupMap = collection.stream()
|
||||
.filter(item -> item.getCol_num() != null)
|
||||
.collect(Collectors.groupingBy(StIvtStructattr::getCol_num));
|
||||
if (colGroupMap.isEmpty()) {
|
||||
colGroupMap = allCollect.stream()
|
||||
.filter(item -> item.getCol_num() != null)
|
||||
.collect(Collectors.groupingBy(StIvtStructattr::getCol_num));
|
||||
if (colGroupMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 找到与目标列差值绝对值最小的列号
|
||||
Integer nearestCol = colGroupMap.keySet().stream()
|
||||
.min((col1, col2) -> {
|
||||
int diff1 = Math.abs(col1 - targetCol);
|
||||
int diff2 = Math.abs(col2 - targetCol);
|
||||
return Integer.compare(diff1, diff2);
|
||||
})
|
||||
.orElse(null);
|
||||
if (nearestCol == null) {
|
||||
return null;
|
||||
}
|
||||
// 在该列中找到与目标层数最接近的货位
|
||||
List<StIvtStructattr> nearestColList = colGroupMap.get(nearestCol);
|
||||
return nearestColList.stream()
|
||||
.min((a, b) -> {
|
||||
Integer layerA = a.getLayer_num() != null ? a.getLayer_num() : 0;
|
||||
Integer layerB = b.getLayer_num() != null ? b.getLayer_num() : 0;
|
||||
int diffA = Math.abs(layerA - targetLayer);
|
||||
int diffB = Math.abs(layerB - targetLayer);
|
||||
return Integer.compare(diffA, diffB);
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ public class SchBasePointController {
|
||||
TableDataInfo result = pointService.bindOrUnbind(entity.getCode(), entity.getVehicle_code(), (entity.getPriority()));
|
||||
if (!"200".equals(result.getCode())) {
|
||||
throw new BadRequestException("地面站点:" + entity.getCode() + "绑定或解绑" + entity.getVehicle_code() + "指令下发CTU,返回操作失败,失败原因:" + result.getMsg());
|
||||
}else{
|
||||
lambdaUpdateWrapper.set(SchBasePoint::getRemark,"地面站点:" + entity.getCode() + "绑定或解绑" + entity.getVehicle_code() + "指令下发CTU,返回操作成功。");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -118,12 +118,11 @@ public class MoveStorageTask extends AbstractTask {
|
||||
//移库完成后,起点作为技改锁,支持技改,不再入库,技改完成后需要解锁
|
||||
iStIvtStructattrService.update(
|
||||
new UpdateWrapper<StIvtStructattr>()
|
||||
.set("lock_type", StatusEnum.LOCK.code("技改锁"))
|
||||
.set("is_used",0)
|
||||
.set("lock_type", StatusEnum.LOCK.code("禁分配锁"))
|
||||
.eq("struct_code", schBaseTask.getPoint_code1())
|
||||
);
|
||||
// List<SchBaseTask> taskList = taskService.list(new QueryWrapper<SchBaseTask>().eq("source_form_id", "99").lt("status", StatusEnum.FORM_STATUS.code("完成")));
|
||||
//移库任务完成,解锁需要维护不能分配的区域
|
||||
// // 移库任务完成,解锁需要维护不能分配的区域
|
||||
// if (taskList.size() == 0) {
|
||||
// UpdateWrapper<StIvtStructattr> wrapper = new UpdateWrapper<>();
|
||||
// wrapper.set("update_time", DateUtil.now())
|
||||
@@ -144,5 +143,14 @@ public class MoveStorageTask extends AbstractTask {
|
||||
.eq("struct_code", schBaseTask.getPoint_code1());
|
||||
iStIvtStructattrService.update(wrapper);
|
||||
this.updateTask(data);
|
||||
List<SchBaseTask> taskList = taskService.list(new QueryWrapper<SchBaseTask>().eq("source_form_id", "99").lt("status", StatusEnum.FORM_STATUS.code("完成")));
|
||||
// 移库任务完成,解锁需要维护不能分配的区域
|
||||
if (taskList.size() == 0) {
|
||||
UpdateWrapper<StIvtStructattr> wrapper2 = new UpdateWrapper<>();
|
||||
wrapper2.set("update_time", DateUtil.now())
|
||||
.set("lock_type", StatusEnum.LOCK.code("无锁"))
|
||||
.eq("lock_type", StatusEnum.LOCK.code("禁分配锁"));
|
||||
iStIvtStructattrService.update(wrapper2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ public class OutStorageTask extends AbstractTask {
|
||||
AtomicReference<String> moveStruct = new AtomicReference<>();
|
||||
RedissonUtils.lock(() -> {
|
||||
System.out.println("---3--" + Thread.currentThread().getName());
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", block.getStor_code(), "vehicle_code", block.getVehicle_code())));
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", block.getStor_code(), "vehicle_code", block.getVehicle_code(),"start_struct_code", block.getStruct_code())));
|
||||
moveStruct.set(((Map<String, String>) process.get("form_data")).get("end_struct_code"));
|
||||
}, "1" + block.getStor_code(), 5);
|
||||
Map moveForm = MapOf.of("task_type", StatusEnum.IOBILL_TYPE_MOVE.code("移库")
|
||||
|
||||
@@ -120,11 +120,11 @@ public class SecondFloorAgvTransferTask extends AbstractTask {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancel(JSONObject data) {
|
||||
try {
|
||||
SchBaseTask schBaseTask = iSchBaseTaskService.getOne(new QueryWrapper<SchBaseTask>().eq("task_code", data.getString("task_code")));
|
||||
iSchBaseTaskService.update(new LambdaUpdateWrapper<SchBaseTask>()
|
||||
.set(SchBaseTask::getTask_step, "1")
|
||||
.eq(SchBaseTask::getTask_type, StatusEnum.IOBILL_TYPE_OUT.code("二楼CTU出库"))
|
||||
.in(SchBaseTask::getGroup_code, schBaseTask.getGroup_code()));
|
||||
// SchBaseTask schBaseTask = iSchBaseTaskService.getOne(new QueryWrapper<SchBaseTask>().eq("task_code", data.getString("task_code")));
|
||||
// iSchBaseTaskService.update(new LambdaUpdateWrapper<SchBaseTask>()
|
||||
// .set(SchBaseTask::getTask_step, "1")
|
||||
// .eq(SchBaseTask::getTask_type, StatusEnum.IOBILL_TYPE_OUT.code("二楼CTU出库"))
|
||||
// .in(SchBaseTask::getGroup_code, schBaseTask.getGroup_code()));
|
||||
this.updateTask(data);
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("取消任务失败,失败原因:" + e.getMessage());
|
||||
|
||||
@@ -231,8 +231,10 @@ public class SecondFloorOutStorageTask extends AbstractTask {
|
||||
.set(MdPbVehicleMater::getFrozen_qty, 0)
|
||||
.set(MdPbVehicleMater::getRemark, r.getTask_code() + "任务被取消,任务组:" + r.getGroup_code() + "任务都被取消。")
|
||||
.eq(MdPbVehicleMater::getId, r.getSource_form_id());
|
||||
//任务取消后不再自动生成任务
|
||||
LambdaUpdateWrapper<SchBaseTask> updateWrapper3 = new LambdaUpdateWrapper<SchBaseTask>()
|
||||
.set(SchBaseTask::getRemark, r.getTask_code() + "任务被取消,任务组:" + r.getGroup_code() + "任务都被取消。")
|
||||
.set(SchBaseTask::getTask_step,"2")
|
||||
.eq(SchBaseTask::getId, r.getId());
|
||||
if (r.getStatus().equals(StatusEnum.FORM_STATUS.code("完成"))) {
|
||||
//清除库存
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.nl.common.utils.IdUtil;
|
||||
import org.nl.common.utils.SecurityUtils;
|
||||
import org.nl.common.utils.SpringContextHolder;
|
||||
import org.nl.wms.dispatch_manage.point.service.ISchBasePointService;
|
||||
import org.nl.wms.dispatch_manage.point.service.dao.SchBasePoint;
|
||||
import org.nl.wms.dispatch_manage.task.handler.AbstractTask;
|
||||
import org.nl.wms.dispatch_manage.task.service.ISchBaseTaskService;
|
||||
import org.nl.wms.dispatch_manage.task.service.dao.SchBaseTask;
|
||||
@@ -66,13 +67,22 @@ public class ToPickPlatformTask extends AbstractTask {
|
||||
if (start_struct_code.contains("B")) {
|
||||
target_point = "1311";
|
||||
} else {
|
||||
List<SchBaseTask> list = iSchBaseTaskService.list(new QueryWrapper<SchBaseTask>()
|
||||
.lt("status", StatusEnum.FORM_STATUS.code("完成")));
|
||||
String pointCode1 = "1308";
|
||||
String pointCode2 = "1311";
|
||||
long count1 = list.stream().filter(r -> r.getPoint_code2().equals(pointCode1)).count();
|
||||
long count2 = list.stream().filter(r -> r.getPoint_code2().equals(pointCode2)).count();
|
||||
target_point = count1 >= count2 ? pointCode2 : pointCode1;
|
||||
List<SchBasePoint> targetPoints = iSchBasePointService.list(new QueryWrapper<SchBasePoint>()
|
||||
.eq("region_code", "PICK01").eq("is_used", true));
|
||||
if (CollectionUtils.isEmpty(targetPoints)) {
|
||||
throw new BadRequestException("当前拣选工位未启用");
|
||||
}
|
||||
if (targetPoints.size() > 1) {
|
||||
List<SchBaseTask> list = iSchBaseTaskService.list(new QueryWrapper<SchBaseTask>()
|
||||
.lt("status", StatusEnum.FORM_STATUS.code("完成")));
|
||||
String pointCode1 = "1308";
|
||||
String pointCode2 = "1311";
|
||||
long count1 = list.stream().filter(r -> r.getPoint_code2().equals(pointCode1)).count();
|
||||
long count2 = list.stream().filter(r -> r.getPoint_code2().equals(pointCode2)).count();
|
||||
target_point = count1 >= count2 ? pointCode2 : pointCode1;
|
||||
} else {
|
||||
target_point = targetPoints.get(0).getCode();
|
||||
}
|
||||
// List<SchBasePoint> targetPoints = iSchBasePointService.list(new QueryWrapper<SchBasePoint>()
|
||||
// .eq("region_code", "PICK01").eq("is_used", true));
|
||||
// //通过全局变量获取目标位置
|
||||
@@ -98,7 +108,6 @@ public class ToPickPlatformTask extends AbstractTask {
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
throw new BadRequestException("当前载具存在任务:" + list.stream().map(SchBaseTask::getTask_code).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
//移库判断
|
||||
if (struct.getStor_code().equals("FStockId")) {
|
||||
synchronized ("FStockId") {
|
||||
|
||||
@@ -442,7 +442,7 @@ public class SchBaseTaskServiceImpl extends ServiceImpl<SchBaseTaskMapper, SchBa
|
||||
RedissonUtils.lock(() -> {
|
||||
System.out.println("---3--" + Thread.currentThread().getName());
|
||||
//出阻挡说明是同排跟任务一个类型载具
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", stIvtStructattr.getStor_code(), "vehicle_code", task.getVehicle_code(), "errorTask", "errorTask")));
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", stIvtStructattr.getStor_code(), "vehicle_code", task.getVehicle_code(), "errorTask", "errorTask", "start_struct_code", block.getStruct_code())));
|
||||
moveStruct.set(((Map<String, String>) process.get("form_data")).get("end_struct_code"));
|
||||
}, "1" + stIvtStructattr.getStor_code(), 5);
|
||||
Map moveForm = MapOf.of("task_type", StatusEnum.IOBILL_TYPE_MOVE.code("异常位移库")
|
||||
@@ -503,7 +503,7 @@ public class SchBaseTaskServiceImpl extends ServiceImpl<SchBaseTaskMapper, SchBa
|
||||
.set("lock_type", StatusEnum.LOCK.code("异常锁定"))
|
||||
.set("update_time", DateUtil.now())
|
||||
.set("remark", "入满异常:" + task_code)
|
||||
.set("vehicle_code", task_code + "_ZD_" + org.nl.common.utils.IdUtil.getStringId()));
|
||||
.set("vehicle_code", task_code + "6" + org.nl.common.utils.IdUtil.getStringId()));
|
||||
}
|
||||
List<MdPbVehicleMater> vehicleList = iMdPbVehicleMaterService
|
||||
.list(new QueryWrapper<MdPbVehicleMater>()
|
||||
@@ -533,15 +533,15 @@ public class SchBaseTaskServiceImpl extends ServiceImpl<SchBaseTaskMapper, SchBa
|
||||
String new_struct_code = ((Map<String, String>) map.get("form_data")).get("end_struct_code");
|
||||
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(vehicleList)) {
|
||||
iActRuExecutionService.update(new UpdateWrapper<ActRuExecution>()
|
||||
.set("remark", stIvtStructattr.getStruct_code() + "入满异常重新分配货位" + new_struct_code)
|
||||
.set("remark", stIvtStructattr.getStruct_code() + "入满异常重新分配货位:" + stIvtStructattr.getStruct_code() + "->" + new_struct_code)
|
||||
.eq("proc_inst_id", vehicleList.get(0).getProc_inst_id()));
|
||||
}
|
||||
log.error("任务:{},载具号:{},原终点:{}入满异常重新分配货位:{}", task_code, task.getVehicle_code(), task.getPoint_code2(), new_struct_code);
|
||||
log.info("【入满异常处理-更新任务】任务号:{}, 载具号:{}, 库位变更:{} -> {}, 阻挡库位:{}",
|
||||
task_code, task.getVehicle_code(), stIvtStructattr.getStruct_code(), new_struct_code, stIvtStructattr.getStruct_code());
|
||||
this.update(new UpdateWrapper<SchBaseTask>()
|
||||
.set("point_code2", new_struct_code)
|
||||
.set("remark", stIvtStructattr.getStruct_code() + "入满异常重新分配货位" + new_struct_code)
|
||||
.set("remark", "入满异常重新分配货位:原库位" + stIvtStructattr.getStruct_code() + "->新库位" + new_struct_code + ",阻挡库位:" + stIvtStructattr.getStruct_code())
|
||||
.eq("task_code", task_code));
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("point_code2", new_struct_code);
|
||||
return result;
|
||||
|
||||
@@ -9,10 +9,12 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.kingdee.bos.webapi.sdk.K3CloudApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.nl.common.TableDataInfo;
|
||||
@@ -65,6 +67,7 @@ import java.util.stream.Collectors;
|
||||
* @since 2024-04-24
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MdGruopDickServiceImpl extends ServiceImpl<MdGruopDickMapper, MdGruopDick> implements IMdGruopDickService {
|
||||
|
||||
@Autowired
|
||||
@@ -594,8 +597,10 @@ public class MdGruopDickServiceImpl extends ServiceImpl<MdGruopDickMapper, MdGru
|
||||
+ "在ERP系统上检索不到相关物料信息,请检查!"
|
||||
);
|
||||
}
|
||||
log.info(item.get(0).getVehicle_code()
|
||||
+ "上的物料:" + r.getMaterial_code() + "单重为:" + materialInfo.getNet_weight());
|
||||
r.setSingle_weight(materialInfo.getNet_weight());
|
||||
r.setAssist_unit_id(materialInfo.getAssist_unit_id());
|
||||
r.setWeight_unit_id(materialInfo.getWeight_unit_id());
|
||||
}
|
||||
//过滤出需要称重校验的物料(单重 > 0)
|
||||
List<MdPbVehicleMaterVo> validItems = item.stream()
|
||||
@@ -660,8 +665,8 @@ public class MdGruopDickServiceImpl extends ServiceImpl<MdGruopDickMapper, MdGru
|
||||
.map(r -> {
|
||||
BigDecimal singleWeight = r.getSingle_weight();
|
||||
// 辅助单位包含 kg
|
||||
if (StringUtils.isNotBlank(r.getAssist_unit_id())) {
|
||||
if (r.getAssist_unit_id().toLowerCase().contains("kg")) {
|
||||
if (StringUtils.isNotBlank(r.getWeight_unit_id())) {
|
||||
if (r.getWeight_unit_id().toLowerCase().contains("kg")) {
|
||||
singleWeight = singleWeight.multiply(BigDecimal.valueOf(1000));
|
||||
}
|
||||
}
|
||||
@@ -669,6 +674,7 @@ public class MdGruopDickServiceImpl extends ServiceImpl<MdGruopDickMapper, MdGru
|
||||
return singleWeight.multiply(r.getQty());
|
||||
})
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
log.info("物料理论总重量为:"+materialWeight);
|
||||
unitIsG = isKg ? "kg" : "g";
|
||||
//实际称重换算克
|
||||
actualWeightG = isKg ? actualWeightKg.multiply(BigDecimal.valueOf(1000)) : actualWeightKg;
|
||||
@@ -677,15 +683,21 @@ public class MdGruopDickServiceImpl extends ServiceImpl<MdGruopDickMapper, MdGru
|
||||
if (netWeight.compareTo(BigDecimal.ZERO) < 0) {
|
||||
netWeight = BigDecimal.ZERO;
|
||||
}
|
||||
//更新组盘信息表
|
||||
iMdPbVehicleMaterService.update(
|
||||
new UpdateWrapper<MdPbVehicleMater>()
|
||||
.set("netWeight", netWeight)
|
||||
.eq("id", item.get(0).getId())
|
||||
);
|
||||
// 差异重量 = 净重 - 理论重量 - 误差
|
||||
BigDecimal diffWeight = netWeight
|
||||
.subtract(materialWeight)
|
||||
.abs();
|
||||
if (diffWeight.compareTo(relativeError) > 0) {
|
||||
log.error(item.get(0).getVehicle_code()+ "的物料数量为:" + validItems.get(0).getQty()
|
||||
log.error(item.get(0).getVehicle_code() + "的物料数量为:" + validItems.get(0).getQty()
|
||||
+ ",上报重量为:" + actualWeightKg + ",载具重量为:" + weight + ",去皮重量为:" + netWeight + ",与物料实际重量:" + materialWeight + ",进行对比已超过误差值" + diffWeight + ",不允许入库,请检查。");
|
||||
throw new BadRequestException(
|
||||
(item.get(0).getVehicle_code() + "的物料数量为:" + validItems.get(0).getQty() + ",上报重量为:" + actualWeightKg + unitIsG + ",载具重量为:" + weight + "g" + ",物料单重为:" + validItems.get(0).getSingle_weight() + validItems.get(0).getAssist_unit_id() + ",去皮重量为:" + netWeight + "g,与物料实际重量:" + materialWeight + "g,进行对比已超过误差值" + diffWeight + "g,不允许入库,请检查。")
|
||||
(item.get(0).getVehicle_code() + "的物料数量为:" + validItems.get(0).getQty() + ",上报重量为:" + actualWeightKg + unitIsG + ",载具重量为:" + weight + "g" + ",物料单重为:" + validItems.get(0).getSingle_weight() + validItems.get(0).getWeight_unit_id() + ",去皮重量为:" + netWeight + "g,与物料实际重量:" + materialWeight + "g,进行对比已超过误差值" + diffWeight + "g,不允许入库,请检查。")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,5 +144,11 @@ public class MdPbVehicleMater implements Serializable {
|
||||
*/
|
||||
private Boolean need_pick = Boolean.FALSE;
|
||||
|
||||
/**
|
||||
* 物料净重
|
||||
*/
|
||||
private BigDecimal netWeight;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
<result property="material_name" column="material_name"/>
|
||||
<result property="material_spec" column="material_spec"/>
|
||||
<result property="single_weight" column="single_weight"/>
|
||||
<result property="assist_unit_id" column="assist_unit_id"/>
|
||||
<result property="weight_unit_id" column="weight_unit_id"/>
|
||||
<result property="unit_name" column="unit_name"/>
|
||||
<result property="form_data" column="form_data"
|
||||
typeHandler="org.nl.common.domain.mybatis.handler.FastjsonSortTypeHandler"/>
|
||||
</resultMap>
|
||||
<select id="getVehicleMaters"
|
||||
resultMap="VoResultMap">
|
||||
select md_pb_vehicleMater.*, material_code, material_name, material_spec,single_weight,assist_unit_id
|
||||
select md_pb_vehicleMater.*, material_code, material_name, material_spec,single_weight,weight_unit_id
|
||||
from md_pb_vehicleMater
|
||||
left join md_me_materialbase
|
||||
on md_pb_vehicleMater.material_id = md_me_materialbase.material_id
|
||||
|
||||
@@ -22,8 +22,8 @@ public class MdPbVehicleMaterVo extends MdPbVehicleMater {
|
||||
private String material_code;
|
||||
private String material_name;
|
||||
private String material_spec;
|
||||
//辅助重量
|
||||
private String assist_unit_id;
|
||||
//重量单位
|
||||
private String weight_unit_id;
|
||||
private BigDecimal single_weight;
|
||||
private String unit_name;
|
||||
}
|
||||
|
||||
@@ -990,17 +990,23 @@ public class CockpitServiceImpl implements CockpitService {
|
||||
real_qty_default.add(item);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(real_qty)) {
|
||||
//计算数量
|
||||
// Map<String, BigDecimal> ghRealQtyMap = real_qty.stream()
|
||||
// .filter(r -> StringUtils.isNotBlank(r.getUpdate_time()))
|
||||
// .collect(Collectors.groupingBy(
|
||||
// TaskInfo::getCreate_time,
|
||||
// Collectors.reducing(BigDecimal.ZERO, TaskInfo::getQty, BigDecimal::add)
|
||||
// ));
|
||||
Map<String, BigDecimal> ghRealQtyMap = real_qty.stream()
|
||||
.filter(r -> StringUtils.isNotBlank(r.getUpdate_time()))
|
||||
.filter(r -> StringUtils.isNotBlank(r.getCreate_time()))
|
||||
.collect(Collectors.groupingBy(
|
||||
TaskInfo::getCreate_time,
|
||||
task -> {
|
||||
String createTime = task.getCreate_time();
|
||||
try {
|
||||
LocalDateTime dateTime = LocalDateTime.parse(createTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
return dateTime.toLocalDate().format(formatter);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
LocalDate date = LocalDate.parse(createTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
return date.format(formatter);
|
||||
} catch (Exception ex) {
|
||||
return createTime;
|
||||
}
|
||||
}
|
||||
},
|
||||
Collectors.reducing(BigDecimal.ZERO, task -> {
|
||||
int boxCount = task.getVehicle_code().split(",").length;
|
||||
return BigDecimal.valueOf(boxCount);
|
||||
|
||||
@@ -388,7 +388,6 @@ public class PdaIOService {
|
||||
}
|
||||
BmFormStruc formType = iBmFormStrucService.getFormType(pdaFormOutMst.getForm_type());
|
||||
String billType = StatusEnum.IOBILL_TYPE_OUT.code(formType.getForm_desc());
|
||||
|
||||
StIvtIostorinv mst = new StIvtIostorinv();
|
||||
mst.setId(IdUtil.getStringId());
|
||||
mst.setCreate_name(SecurityUtils.getCurrentNickName());
|
||||
@@ -402,43 +401,126 @@ public class PdaIOService {
|
||||
mst.setBill_type(billType);
|
||||
mst.setIn_storage(false);
|
||||
mst.setProduct_area(pdaFormOutMst.getProduct_area());
|
||||
mst.setForm_data(new JSONObject(MapOf.of("shipper",null,"product_area",pdaFormOutMst.getProduct_area(), "priority", pdaFormOutMst.getUrgent())));
|
||||
mst.setForm_data(new JSONObject(MapOf.of("shipper", null, "product_area", pdaFormOutMst.getProduct_area(), "priority", pdaFormOutMst.getUrgent())));
|
||||
List<StIvtIostorinvdtl> list = new ArrayList<>();
|
||||
JSONObject mstJ = (JSONObject) JSONObject.toJSON(pdaFormOutMst);
|
||||
mstJ.remove("children");
|
||||
mstJ.putAll((Map)mstJ.remove("form_data"));
|
||||
mstJ.putAll((Map) mstJ.remove("form_data"));
|
||||
String mstString = mstJ.toJSONString();
|
||||
// 如果仓库代码为"FStockPallet",需要特殊处理:优先锁定同一载具上的多个物料
|
||||
boolean isFStockPallet = "FStockPallet".equals(pdaFormOutMst.getStor_code());
|
||||
Set<String> processedSharedVehicles = new HashSet<>();
|
||||
Map<String, List<MdPbVehicleMater>> sharedVehicleInfoMap = new HashMap<>(); // 记录共享载具信息,用于循环后冻结
|
||||
if (isFStockPallet) {
|
||||
// 创建final版本的dtls用于lambda表达式
|
||||
final List<PdaFormOutDtl> finalDtls = dtls;
|
||||
// 收集所有物料ID
|
||||
List<String> materialIds = dtls.stream()
|
||||
.map(PdaFormOutDtl::getMaterial_id)
|
||||
.distinct().collect(Collectors.toList());
|
||||
// 查询这些物料的库存信息(查询可用数量>0的物料)
|
||||
if (!CollectionUtils.isEmpty(materialIds)) {
|
||||
List<MdPbVehicleMater> allVehicleMaters = iMdPbVehicleMaterService.list(
|
||||
new QueryWrapper<MdPbVehicleMater>()
|
||||
.in("material_id", materialIds)
|
||||
.eq("is_delete", false)
|
||||
.gt("qty", 0)
|
||||
.eq("stor_code", pdaFormOutMst.getStor_code())
|
||||
);
|
||||
// 按载具分组,找出同一载具上有多个不同物料的情况
|
||||
Map<String, List<MdPbVehicleMater>> vehicleMaterialMap = allVehicleMaters.stream()
|
||||
.collect(Collectors.groupingBy(MdPbVehicleMater::getVehicle_code))
|
||||
.entrySet().stream()
|
||||
.filter(entry -> {
|
||||
// 统计这个载具上有多少个不同的物料在dtls中
|
||||
long distinctMaterialCount = entry.getValue().stream()
|
||||
.map(MdPbVehicleMater::getMaterial_id)
|
||||
.distinct()
|
||||
.filter(materialId -> finalDtls.stream()
|
||||
.anyMatch(dtl -> dtl.getMaterial_id().equals(materialId)))
|
||||
.count();
|
||||
return distinctMaterialCount > 1; // 只保留有多个不同物料的载具
|
||||
})
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
// 步骤1:在循环前,只移除共享载具中非第一个物料的dtl
|
||||
if (!vehicleMaterialMap.isEmpty()) {
|
||||
log.info("发现 {} 个共享载具,开始预处理过滤", vehicleMaterialMap.size());
|
||||
|
||||
// 记录每个共享载具对应的第一个物料ID
|
||||
Set<String> keptDtlIds = new HashSet<>();
|
||||
for (Map.Entry<String, List<MdPbVehicleMater>> entry : vehicleMaterialMap.entrySet()) {
|
||||
String vehicleCode = entry.getKey();
|
||||
List<MdPbVehicleMater> matersInVehicle = entry.getValue();
|
||||
|
||||
// 找到这个载具对应的第一个物料明细
|
||||
PdaFormOutDtl firstDtl = finalDtls.stream()
|
||||
.filter(dtl -> matersInVehicle.stream()
|
||||
.anyMatch(vm -> vm.getMaterial_id().equals(dtl.getMaterial_id())))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (firstDtl != null) {
|
||||
keptDtlIds.add(firstDtl.getId());
|
||||
// 记录共享载具信息,用于循环后冻结
|
||||
sharedVehicleInfoMap.put(vehicleCode, matersInVehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤dtls:如果是共享载具的物料,只保留第一个;如果不是共享载具,全部保留
|
||||
dtls = dtls.stream()
|
||||
.filter(dtl -> {
|
||||
// 检查这个dtl是否在共享载具上
|
||||
boolean isInSharedVehicle = vehicleMaterialMap.values().stream()
|
||||
.anyMatch(maters -> maters.stream()
|
||||
.anyMatch(vm -> vm.getMaterial_id().equals(dtl.getMaterial_id())));
|
||||
|
||||
if (isInSharedVehicle) {
|
||||
// 如果在共享载具上,只保留第一个
|
||||
return keptDtlIds.contains(dtl.getId());
|
||||
} else {
|
||||
// 如果不在共享载具上,全部保留
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
log.info("过滤后剩余 {} 个物料明细需要处理", dtls.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PdaFormOutDtl dtl : dtls) {
|
||||
BigDecimal now_assign_qty = dtl.getNow_assign_qty();
|
||||
if (now_assign_qty==null || now_assign_qty.intValue()==0){
|
||||
throw new BadRequestException("出库申请失败:当前"+dtl.getMaterial_name()+"明细申请数量为0");
|
||||
if (now_assign_qty == null || now_assign_qty.intValue() == 0) {
|
||||
throw new BadRequestException("出库申请失败:当前" + dtl.getMaterial_name() + "明细申请数量为0");
|
||||
}
|
||||
String productArea = pdaFormOutMst.getProduct_area();
|
||||
if (StringUtils.isEmpty(productArea) || !"A1A2A3".contains(productArea)){
|
||||
if (StringUtils.isEmpty(productArea) || !"A1A2A3".contains(productArea)) {
|
||||
throw new BadRequestException("出库申请失败:明细数据车间字段未指定或不正确");
|
||||
}
|
||||
String storCode = pdaFormOutMst.getStor_code();
|
||||
if (StringUtils.isEmpty(storCode)){
|
||||
throw new BadRequestException("出库申请失败:明细数据仓库字段未指定");
|
||||
if (StringUtils.isEmpty(storCode)) {
|
||||
throw new BadRequestException("出库申请失败:明细数据仓库字段未指定");
|
||||
}
|
||||
String pcsn = dtl.getPcsn();
|
||||
// 正常分配逻辑(共享载具已在循环前处理并过滤)
|
||||
List<StructAssignQty> structMaterials = iStIvtStructattrService.getStructIvtAssign(ListOf.of(dtl.getMaterial_id()), storCode);
|
||||
if (CollectionUtils.isEmpty(structMaterials)){
|
||||
throw new BadRequestException(dtl.getMaterial_code()+"物料库存不足");
|
||||
if (CollectionUtils.isEmpty(structMaterials)) {
|
||||
throw new BadRequestException(dtl.getMaterial_code() + "物料库存不足");
|
||||
}
|
||||
if (!StringUtils.isEmpty(pcsn)){
|
||||
if (!StringUtils.isEmpty(pcsn)) {
|
||||
for (StructAssignQty assignQty : structMaterials) {
|
||||
if (assignQty.getPcsn().equals(pcsn)){
|
||||
if (assignQty.getPcsn().equals(pcsn)) {
|
||||
boolean b = assignQty.getSto_qty().intValue() >= dtl.getNow_assign_qty().intValue();
|
||||
if (!b){
|
||||
throw new BadRequestException(dtl.getMaterial_code()+"物料该批号库存不足");
|
||||
if (!b) {
|
||||
throw new BadRequestException(dtl.getMaterial_code() + "物料该批号库存不足");
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
int sum = structMaterials.stream().mapToInt(a -> a.getSto_qty().intValue()).sum();
|
||||
if (sum<now_assign_qty.intValue()){
|
||||
throw new BadRequestException(dtl.getMaterial_code()+"物料库存不足");
|
||||
if (sum < now_assign_qty.intValue()) {
|
||||
throw new BadRequestException(dtl.getMaterial_code() + "物料库存不足");
|
||||
}
|
||||
}
|
||||
//vehicle_code.split(",")
|
||||
@@ -458,7 +540,7 @@ public class PdaIOService {
|
||||
Set<String> materSet = currentPcsnMater.stream().map(MdPbVehicleMater::getVehicle_code).collect(Collectors.toSet());
|
||||
//CTU更新单据号
|
||||
LambdaUpdateWrapper<MdPbVehicleMater> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.in(MdPbVehicleMater::getVehicle_code,materSet);
|
||||
updateWrapper.in(MdPbVehicleMater::getVehicle_code, materSet);
|
||||
updateWrapper.eq(MdPbVehicleMater::getIs_delete, false);
|
||||
updateWrapper.set(MdPbVehicleMater::getPrd_ppbom_no, pdaFormOutMst.getCode());
|
||||
iMdPbVehicleMaterService.update(updateWrapper);
|
||||
@@ -478,19 +560,90 @@ public class PdaIOService {
|
||||
ivtDtl.setStatus(StatusEnum.FORM_STATUS.code("生成"));
|
||||
ivtDtl.setSource_form_id(dtl.getId());
|
||||
ivtDtl.setSource_form_type(dtl.getForm_type());
|
||||
合并主表明细数据:{
|
||||
// 合并主表明细数据
|
||||
{
|
||||
JSONObject sourceFormData = JSONObject.parseObject(mstString);
|
||||
String dtlStr = JSON.toJSONString(dtl);
|
||||
JSONObject dtlJ = JSONObject.parseObject(dtlStr);
|
||||
dtlJ.putAll((Map) dtlJ.remove("form_data"));
|
||||
sourceFormData.putAll(dtlJ);
|
||||
sourceFormData.put("pcsn",disPcsn);
|
||||
sourceFormData.put("stock_code", "FStockId".equals(ivtDtl.getStor_code())?"25":"24");
|
||||
sourceFormData.put("pcsn", disPcsn);
|
||||
sourceFormData.put("stock_code", "FStockId".equals(ivtDtl.getStor_code()) ? "25" : "24");
|
||||
ivtDtl.setSource_form_data(sourceFormData);
|
||||
}
|
||||
list.add(ivtDtl);
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤3:最后一步,处理共享载具的物料分配与冻结
|
||||
if (isFStockPallet && !sharedVehicleInfoMap.isEmpty()) {
|
||||
log.info("开始处理 {} 个共享载具的冻结", sharedVehicleInfoMap.size());
|
||||
|
||||
for (Map.Entry<String, List<MdPbVehicleMater>> entry : sharedVehicleInfoMap.entrySet()) {
|
||||
String vehicleCode = entry.getKey();
|
||||
List<MdPbVehicleMater> matersInVehicle = entry.getValue();
|
||||
|
||||
// 找到这个载具对应的第一个物料明细(已经在dtls中保留)
|
||||
PdaFormOutDtl firstDtl = dtls.stream()
|
||||
.filter(dtl -> matersInVehicle.stream()
|
||||
.anyMatch(vm -> vm.getMaterial_id().equals(dtl.getMaterial_id())))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (firstDtl != null) {
|
||||
// 第一个物料的已分配数量(已经通过outDispense计算)
|
||||
BigDecimal firstAssignedQty = firstDtl.getNow_assign_qty();
|
||||
|
||||
// 计算其他同载具物料的总需求数量
|
||||
BigDecimal otherNeed = matersInVehicle.stream()
|
||||
.filter(vm -> !vm.getMaterial_id().equals(firstDtl.getMaterial_id()))
|
||||
.map(vm -> {
|
||||
PdaFormOutDtl matchingDtl = pdaFormOutMst.getChildren().stream()
|
||||
.filter(dtl -> dtl.getMaterial_id().equals(vm.getMaterial_id()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return matchingDtl != null ? matchingDtl.getNow_assign_qty() : BigDecimal.ZERO;
|
||||
})
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 计算可用数量(排除第一个物料已占用的)
|
||||
BigDecimal availableQty = matersInVehicle.stream()
|
||||
.map(vm -> vm.getQty().subtract(vm.getFrozen_qty() != null ? vm.getFrozen_qty() : BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||
.subtract(firstAssignedQty);
|
||||
|
||||
if (availableQty.compareTo(otherNeed) >= 0) {
|
||||
// 可用数量足够,冻结其他物料的需求数量
|
||||
for (MdPbVehicleMater vm : matersInVehicle) {
|
||||
// 跳过第一个物料(它已经被outDispense冻结了)
|
||||
if (vm.getMaterial_id().equals(firstDtl.getMaterial_id())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PdaFormOutDtl matchingDtl = pdaFormOutMst.getChildren().stream()
|
||||
.filter(dtl -> dtl.getMaterial_id().equals(vm.getMaterial_id()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (matchingDtl != null) {
|
||||
BigDecimal freezeQty = matchingDtl.getNow_assign_qty();
|
||||
LambdaUpdateWrapper<MdPbVehicleMater> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(MdPbVehicleMater::getId, vm.getId());
|
||||
updateWrapper.setSql("frozen_qty = frozen_qty + " + freezeQty);
|
||||
iMdPbVehicleMaterService.update(updateWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
// 标记这个载具已处理
|
||||
processedSharedVehicles.add(vehicleCode);
|
||||
log.info("载具 {} 已冻结其他物料,包含 {} 个物料", vehicleCode, matersInVehicle.size());
|
||||
} else {
|
||||
log.warn("载具 {} 可用数量不足,无法冻结其他物料", vehicleCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iStIvtIostorinvdtlService.saveBatch(list);
|
||||
iStIvtIostorinvService.save(mst);
|
||||
//生成流程
|
||||
@@ -514,9 +667,9 @@ public class PdaIOService {
|
||||
iPmFormDataService.update(new UpdateWrapper<PmFormData>()
|
||||
.set("status",StatusEnum.FORM_STATUS.code("完成"))
|
||||
.set("update_time",now)
|
||||
.set("update_name",nickName)
|
||||
.eq("id",sourceFormid));
|
||||
}else {
|
||||
.set("update_name", nickName)
|
||||
.eq("id", sourceFormid));
|
||||
} else {
|
||||
iPmFormDataService.update(new UpdateWrapper<PmFormData>()
|
||||
.set("status", StatusEnum.FORM_STATUS.code("执行中"))
|
||||
.set("update_time", now)
|
||||
@@ -526,6 +679,72 @@ public class PdaIOService {
|
||||
return mst;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理载具分配逻辑(用于FStockPallet仓库的特殊处理)
|
||||
*/
|
||||
private void processVehicleAssignment(PdaFormOutDtl dtl, String vehicles, StIvtIostorinv mst,
|
||||
List<StIvtIostorinvdtl> list, String productArea,
|
||||
String storCode, String mstString, PdaFormOutMst pdaFormOutMst) {
|
||||
List<MdPbVehicleMater> MdPbVehicleMaters = iMdPbVehicleMaterService.list(
|
||||
new QueryWrapper<MdPbVehicleMater>()
|
||||
.in("vehicle_code", vehicles.split(","))
|
||||
.eq("is_delete", false)
|
||||
.eq("material_id", dtl.getMaterial_id()));
|
||||
|
||||
Map<String, List<MdPbVehicleMater>> pcsnListMap = MdPbVehicleMaters.stream()
|
||||
.collect(Collectors.groupingBy(MdPbVehicleMater::getPcsn));
|
||||
|
||||
// 手持生成出库单
|
||||
for (String disPcsn : pcsnListMap.keySet()) {
|
||||
List<MdPbVehicleMater> currentPcsnMater = pcsnListMap.get(disPcsn);
|
||||
if (StringUtils.isNotBlank(pdaFormOutMst.getCode())) {
|
||||
Set<String> materSet = currentPcsnMater.stream()
|
||||
.map(MdPbVehicleMater::getVehicle_code)
|
||||
.collect(Collectors.toSet());
|
||||
// CTU更新单据号
|
||||
LambdaUpdateWrapper<MdPbVehicleMater> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.in(MdPbVehicleMater::getVehicle_code, materSet);
|
||||
updateWrapper.eq(MdPbVehicleMater::getIs_delete, false);
|
||||
updateWrapper.set(MdPbVehicleMater::getPrd_ppbom_no, pdaFormOutMst.getCode());
|
||||
iMdPbVehicleMaterService.update(updateWrapper);
|
||||
}
|
||||
HashMap map = MapOf.of("end_struct_code", "", "start_struct_code", "", "order", "", "product_area", productArea);
|
||||
StIvtIostorinvdtl ivtDtl = new StIvtIostorinvdtl();
|
||||
ivtDtl.setMaterial_id(dtl.getMaterial_id());
|
||||
ivtDtl.setForm_data(new JSONObject(map));
|
||||
ivtDtl.setQty(BigDecimal.valueOf(currentPcsnMater.stream()
|
||||
.mapToInt(a -> a.getFrozen_qty() != null ? a.getFrozen_qty().intValue() : 0).sum()));
|
||||
ivtDtl.setPcsn(disPcsn);
|
||||
ivtDtl.setStor_code(storCode);
|
||||
ivtDtl.setId(IdUtil.getStringId());
|
||||
// 去重
|
||||
ivtDtl.setVehicle_code(currentPcsnMater.stream()
|
||||
.map(MdPbVehicleMater::getVehicle_code)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(",")));
|
||||
ivtDtl.setVehicle_id(currentPcsnMater.stream()
|
||||
.map(MdPbVehicleMater::getId)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(",")));
|
||||
ivtDtl.setInv_id(mst.getId());
|
||||
ivtDtl.setStatus(StatusEnum.FORM_STATUS.code("生成"));
|
||||
ivtDtl.setSource_form_id(dtl.getId());
|
||||
ivtDtl.setSource_form_type(dtl.getForm_type());
|
||||
// 合并主表明细数据
|
||||
{
|
||||
JSONObject sourceFormData = JSONObject.parseObject(mstString);
|
||||
String dtlStr = JSON.toJSONString(dtl);
|
||||
JSONObject dtlJ = JSONObject.parseObject(dtlStr);
|
||||
dtlJ.putAll((Map) dtlJ.remove("form_data"));
|
||||
sourceFormData.putAll(dtlJ);
|
||||
sourceFormData.put("pcsn", disPcsn);
|
||||
sourceFormData.put("stock_code", "FStockId".equals(ivtDtl.getStor_code()) ? "25" : "24");
|
||||
ivtDtl.setSource_form_data(sourceFormData);
|
||||
}
|
||||
list.add(ivtDtl);
|
||||
}
|
||||
}
|
||||
|
||||
private void pdaTaskOpen(StIvtIostorinv mst) {
|
||||
iStIvtIostorinvService.taskOpen((JSONObject) JSONObject.toJSON(mst));
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -69,13 +70,20 @@ public class PdaPickController {
|
||||
//托盘拣选信息
|
||||
if (form.getVehicle_code().contains("T")) {
|
||||
List<MdPbVehicleMater> list = iMdPbVehicleMaterService.list(new QueryWrapper<MdPbVehicleMater>()
|
||||
.eq("vehicle_code", form.getVehicle_code()));
|
||||
.eq("vehicle_code", form.getVehicle_code()).eq("is_delete", false).eq("need_pick", true));
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
list = list.stream().filter(r -> StringUtils.isNotBlank(r.getRemark())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
list = list.stream().filter(r -> r.getRemark().contains("该托盘")).collect(Collectors.toList());
|
||||
String remark = "需要拣选:";
|
||||
//如果有多个,则在元素前添加1:,2:,3:
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
throw new BadRequestException(list.get(0).getRemark());
|
||||
AtomicInteger counter = new AtomicInteger(1);
|
||||
remark = remark + list.stream()
|
||||
.map(MdPbVehicleMater::getRemark)
|
||||
.map(r -> counter.getAndIncrement() + ": " + r)
|
||||
.collect(Collectors.joining("; "));
|
||||
throw new BadRequestException(remark);
|
||||
} else {
|
||||
throw new BadRequestException("该托盘,托盘号为:" + form.getVehicle_code() + ",无相关出库信息,请在WMS系统查询库存变动信息");
|
||||
}
|
||||
|
||||
@@ -188,14 +188,14 @@ public class StIvtStructattrController {
|
||||
public void exportFile(@RequestBody StructattrQuery query, HttpServletResponse response) {
|
||||
PageQuery page = new PageQuery();
|
||||
page.setPage(0);
|
||||
page.setSize(99999);
|
||||
page.setSize(500);
|
||||
TableDataInfo<Map> structIvt = structattrService.getStructIvt(query, page);
|
||||
List<Map> maps = structIvt.getContent();
|
||||
columnInfoService.exportFile("", maps, response,
|
||||
null,
|
||||
MapOf.linkOf("stor_code", "仓库编码", "struct_code", "仓位", "vehicle_code", "载具编码",
|
||||
"material_code", "物料编号", "material_code", "物料名称", "pcsn", "批号"
|
||||
, "forzen_qty", "冻结数量", "qty", "库位库存", "counts", "物料总库存", "erpCounts", "ERP实时库存", "differCount", "立库-ERP库存差异", "create_time", "组盘入库时间"));
|
||||
, "forzen_qty", "冻结数量", "qty", "库位库存", "counts", "物料总库存", "netWeight", "净重","erpCounts", "ERP实时库存", "differCount", "立库-ERP库存差异", "create_time", "组盘入库时间"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@
|
||||
material.material_code,
|
||||
material.material_name,
|
||||
vm.create_time,
|
||||
vm.netWeight,
|
||||
struct.w as counts,
|
||||
struct.l as erpCounts,
|
||||
struct.weight as differCount
|
||||
|
||||
@@ -34,6 +34,8 @@ public class StructattrQuery extends BaseQuery<StIvtStructattr> {
|
||||
private String idleTime;
|
||||
private Boolean isIdle;
|
||||
private String idleTimes;
|
||||
private String netWeight;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
@@ -167,13 +168,13 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
update.set("need_pick", true);
|
||||
//托盘出库提示拣选信息
|
||||
if (!growth) {
|
||||
update.set("remark", "该托盘需要拣选的物料为:" + materialbase.getMaterial_name() + ",物料编码为:" + materialbase.getMaterial_code() + ",数量为:" + vehicleMater.getFrozen_qty() + ",拣选完请把托盘剩余物料拉到入库口进行回库");
|
||||
update.set("remark", materialbase.getMaterial_code() + ",数量:" + vehicleMater.getFrozen_qty());
|
||||
}
|
||||
}
|
||||
}
|
||||
//入库清除拣选信息
|
||||
if (growth) {
|
||||
update.set("remark", "").set("need_pick", false).set("is_check", null);
|
||||
update.set("remark", "").set("need_pick", false).set("is_check", null).set("netWeight", null);
|
||||
}
|
||||
update.set("qty", subtract);//50
|
||||
} else {
|
||||
@@ -181,7 +182,7 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
//托盘整出需要扣库存,除了二楼料箱整出不扣库存,其他都扣库存
|
||||
if (!("2114").equals(point_code2)) {
|
||||
if (vehicleCode.contains("T")) {
|
||||
update.set("remark", "该托盘需要拣选的物料为:"+materialbase.getMaterial_name()+",物料编码为:"+materialbase.getMaterial_code()+",数量为:"+ vehicleMater.getFrozen_qty() + ",拣选完该物料数量为0,如果托盘不存在其他类型物料,则作为空托盘使用,无需回库").set("need_pick",false);
|
||||
update.set("remark", materialbase.getMaterial_code() + ",数量为:" + vehicleMater.getFrozen_qty() + ",如托盘不存在其他类型物料,则拉走空托盘,无需回库").set("need_pick", false);
|
||||
}
|
||||
if (!task_type.equals(StatusEnum.IOBILL_TYPE_OUT.code("盘点出库"))) {
|
||||
update.set("qty", subtract);
|
||||
@@ -390,6 +391,54 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
BigDecimal::add)
|
||||
));
|
||||
}
|
||||
for (Map<String, Object> item : mst_detail) {
|
||||
String key = (String) item.get("material_code");
|
||||
MdMeMaterialbase material = mdMeMaterialbaseService.getOne(new QueryWrapper<MdMeMaterialbase>().eq("material_code", key));
|
||||
BigDecimal weight;
|
||||
if (item.get("netWeight") == null) {
|
||||
if (material != null && material.getNet_weight() != null) {
|
||||
BigDecimal qty = item.get("qty") != null ? new BigDecimal(item.get("qty").toString()) : BigDecimal.ZERO;
|
||||
weight = qty.multiply(material.getNet_weight()).setScale(2, RoundingMode.HALF_UP);
|
||||
} else {
|
||||
weight = BigDecimal.ZERO;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
weight = new BigDecimal(item.get("netWeight").toString()).setScale(2, RoundingMode.HALF_UP);
|
||||
} catch (NumberFormatException e) {
|
||||
weight = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
// 确定单位显示
|
||||
String weightResult;
|
||||
if ("FStockId".equals(item.get("stor_code"))) {
|
||||
weightResult = weight + "g";
|
||||
} else if (material != null && "g".equals(material.getWeight_unit_id())) {
|
||||
weightResult = weight + "g";
|
||||
} else {
|
||||
weightResult = weight + "kg";
|
||||
}
|
||||
item.put("netWeight", weightResult);
|
||||
}
|
||||
// 如果按净重筛选,需要去除单位后再比较
|
||||
if (StringUtils.isNotBlank(query.getNetWeight())) {
|
||||
try {
|
||||
BigDecimal filterWeight = new BigDecimal(query.getNetWeight().trim());
|
||||
mst_detail = mst_detail.stream()
|
||||
.filter(item -> item.get("netWeight") != null)
|
||||
.filter(item -> {
|
||||
// 从带单位的字符串中提取数值部分,如 "100.00g" -> 100.00
|
||||
String netWeightStr = item.get("netWeight").toString();
|
||||
String weightOnly = netWeightStr.replaceAll("[a-z A-Z]", "").trim();
|
||||
BigDecimal netWeight = new BigDecimal(weightOnly);
|
||||
return netWeight.compareTo(filterWeight) == 0;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果格式不正确,跳过筛选
|
||||
log.warn("净重筛选条件格式错误: {}", query.getNetWeight());
|
||||
}
|
||||
}
|
||||
if (baseQty != null) {
|
||||
for (Map<String, Object> item : mst_detail) {
|
||||
String key = (String) item.get("material_code");
|
||||
@@ -483,6 +532,92 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
@Override
|
||||
@Transactional
|
||||
public void createMoveTask(String structCodeList) {
|
||||
// ISchBaseTaskService taskService = SpringContextHolder.getBean(ISchBaseTaskService.class);
|
||||
// QueryWrapper<SchBaseTask> query1 = new QueryWrapper<SchBaseTask>()
|
||||
// .likeRight("point_code1", structCodeQuery)
|
||||
// .lt("status", StatusEnum.FORM_STATUS.code("完成"));
|
||||
// List<SchBaseTask> schBaseTaskList = taskService.list(query1);
|
||||
// if (!CollectionUtils.isEmpty(schBaseTaskList)) {
|
||||
// throw new BadRequestException("当前同排同列库位在任务,请完成后再下发批量移库任务");
|
||||
// }
|
||||
if (StringUtils.isBlank(structCodeList)) {
|
||||
throw new BadRequestException("移库数量不能为空");
|
||||
}
|
||||
if (!StringUtils.isNumeric(structCodeList)) {
|
||||
throw new BadRequestException("移库数量必须为正整数");
|
||||
}
|
||||
int quantity = Integer.parseInt(structCodeList);
|
||||
if (quantity <= 0) {
|
||||
throw new BadRequestException("移库数量必须大于 0");
|
||||
}
|
||||
QueryWrapper<StIvtStructattr> query = new QueryWrapper<>();
|
||||
query.eq("is_used", true);
|
||||
query.isNotNull("vehicle_code");
|
||||
query.eq("sect_code", "LXBCP01");
|
||||
ArrayList<String> pai = new ArrayList<>();
|
||||
pai.add("1");
|
||||
pai.add("2");
|
||||
query.in("row_num", pai)
|
||||
.lt("row_num", 3)
|
||||
.ge("layer_num", 24)
|
||||
.le("layer_num", 31).orderByDesc("row_num").orderByAsc("col_num");
|
||||
List<StIvtStructattr> list = this.list(query);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
throw new BadRequestException("批量移库任务申请失败,没有可用仓位!");
|
||||
}
|
||||
if (quantity > list.size()) {
|
||||
throw new BadRequestException("移库数量不能超过列表总长度(当前列表长度为 " + list.size() + ")");
|
||||
}
|
||||
list = list.stream().limit(quantity).collect(Collectors.toList());
|
||||
UpdateWrapper<StIvtStructattr> updateWrapper = new UpdateWrapper<StIvtStructattr>()
|
||||
.set("lock_type", StatusEnum.LOCK.code("禁分配锁"))
|
||||
.eq("is_used", 1)
|
||||
.isNull("vehicle_code")
|
||||
.eq("sect_code", "LXBCP01")
|
||||
.lt("row_num", 3)
|
||||
.ge("layer_num", 24)
|
||||
.le("layer_num", 31);
|
||||
this.update(updateWrapper);
|
||||
list.forEach(r -> {
|
||||
DELAY_EXECUTOR.execute(() -> {
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
AtomicReference<String> moveStruct = new AtomicReference<>();
|
||||
String vehicleCode = r.getVehicle_code();
|
||||
RedissonUtils.lock(() -> {
|
||||
System.out.println("---3--" + Thread.currentThread().getName());
|
||||
//出阻挡说明是同排跟任务一个类型载具
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", r.getStor_code(), "vehicle_code", vehicleCode, "start_struct_code", r.getStruct_code())));
|
||||
moveStruct.set(((Map<String, String>) process.get("form_data")).get("end_struct_code"));
|
||||
}, "1" + r.getStor_code(), 5);
|
||||
Map moveForm = MapOf.of("task_type", StatusEnum.IOBILL_TYPE_MOVE.code("移库")
|
||||
, "is_send", false
|
||||
, "vehicle_code", StringUtils.isEmpty(vehicleCode) ? "YCZJ" + r.getVehicle_code() : vehicleCode, "form_data", new JSONObject(MapOf.of("start_struct_code", r.getStruct_code(), "end_struct_code", moveStruct.get())));
|
||||
moveForm.put("isAllMove", "1");
|
||||
SpringContextHolder.getBean(MoveStorageTask.class).createTask(new JSONObject(moveForm));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.error("延迟任务被中断", e);
|
||||
} catch (Exception e) {
|
||||
log.error("延迟下发任务执行失败", e);
|
||||
}
|
||||
});
|
||||
});
|
||||
// if (ObjectUtils.isNotEmpty(list2)) {
|
||||
// LambdaUpdateWrapper<StIvtStructattr> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||
// lambdaUpdateWrapper.set(StIvtStructattr::getLock_type, StatusEnum.LOCK.code("技改锁")).set(StIvtStructattr::getIs_used, 0);
|
||||
// lambdaUpdateWrapper.in(StIvtStructattr::getStruct_code, list2);
|
||||
// this.update(lambdaUpdateWrapper);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量移库下发
|
||||
*/
|
||||
// @Override
|
||||
@Transactional
|
||||
public void createMoveTask1(String structCodeList) {
|
||||
Set<String> structCodeSet = new HashSet<>();
|
||||
String structCodeQuery;
|
||||
String structCode = structCodeList.trim();
|
||||
@@ -523,7 +658,7 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
return;
|
||||
}
|
||||
if (structCodeQuery.contains("L")) {
|
||||
query.eq("sect_code","LXBCP01");
|
||||
query.eq("sect_code", "LXBCP01");
|
||||
} else {
|
||||
query.eq("stor_code", StatusEnum.STOCK_INFO.code("托盘库"));
|
||||
}
|
||||
@@ -586,15 +721,15 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
RedissonUtils.lock(() -> {
|
||||
System.out.println("---3--" + Thread.currentThread().getName());
|
||||
//出阻挡说明是同排跟任务一个类型载具
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", r.getStor_code(), "vehicle_code", vehicleCode, "errorTask", "errorTask")));
|
||||
Map process = SpringContextHolder.getBean(DecisionHandler.class).dispenseTransa(ListOf.of("limitStorage", "depthPriority", "alleyAve"), new JSONObject(MapOf.of("is_move", true, "stor_code", r.getStor_code(), "vehicle_code", vehicleCode, "errorTask", "errorTask", "start_struct_code", r.getStruct_code())));
|
||||
moveStruct.set(((Map<String, String>) process.get("form_data")).get("end_struct_code"));
|
||||
}, "1" + r.getStor_code(), 5);
|
||||
Map moveForm = MapOf.of("task_type", StatusEnum.IOBILL_TYPE_MOVE.code("移库")
|
||||
, "is_send", false
|
||||
, "vehicle_code", StringUtils.isEmpty(vehicleCode) ? "YCZJ" + r.getVehicle_code() : vehicleCode, "form_data", new JSONObject(MapOf.of("start_struct_code", r.getStruct_code(), "end_struct_code", moveStruct.get())));
|
||||
if (isAllMove) {
|
||||
if (isAllMove) {
|
||||
moveForm.put("isAllMove", "1");
|
||||
}
|
||||
}
|
||||
SpringContextHolder.getBean(MoveStorageTask.class).createTask(new JSONObject(moveForm));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
@@ -612,7 +747,6 @@ public class StIvtStructattrServiceImpl extends ServiceImpl<StIvtStructattrMappe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// @Transactional
|
||||
// public void createMoveTask(String structCodeList) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.nl.common.TableDataInfo;
|
||||
import org.nl.common.enums.StatusEnum;
|
||||
import org.nl.common.utils.BaseCode;
|
||||
@@ -20,6 +21,7 @@ import org.nl.wms.dispatch_manage.task.handler.impl.SecondFloorAgvTransferTask;
|
||||
import org.nl.wms.dispatch_manage.task.service.ISchBaseTaskService;
|
||||
import org.nl.wms.dispatch_manage.task.service.dao.SchBaseTask;
|
||||
import org.nl.wms.external_system.acs.service.WmsToAcsService;
|
||||
import org.nl.wms.system_manage.service.param.dao.Param;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -172,6 +174,7 @@ public class TaskScheduleService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTaskResponse(TableDataInfo response, List<String> taskCodes) {
|
||||
if (response.getCode().equals(String.valueOf(HttpStatus.HTTP_OK))) {
|
||||
iSchBaseTaskService.update(new UpdateWrapper<SchBaseTask>()
|
||||
|
||||
@@ -7,6 +7,8 @@ spring:
|
||||
check-template-location: false
|
||||
profiles:
|
||||
active: dev
|
||||
#active: dev
|
||||
#active: prod
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
data:
|
||||
|
||||
@@ -82,6 +82,17 @@
|
||||
@input="handleSearchInput('prd_ppbom_no')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="物料重量">
|
||||
<el-input
|
||||
v-model="query.netWeight"
|
||||
clearable
|
||||
size="mini"
|
||||
placeholder="请输入物料重量"
|
||||
prefix-icon="el-icon-search"
|
||||
class="filter-item"
|
||||
@input="handleSearchInput('netWeight')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="锁定类型">
|
||||
<el-select
|
||||
v-model="query.lock_type"
|
||||
@@ -211,6 +222,7 @@
|
||||
<el-table-column prop="qty" label="库位库存" show-tooltip-when-overflow />
|
||||
<el-table-column prop="frozen_qty" label="冻结库存" show-tooltip-when-overflow />
|
||||
<el-table-column prop="counts" label="物料总库存" min-width="90" show-tooltip-when-overflow />
|
||||
<el-table-column prop="netWeight" label="物料重量" min-width="90" show-tooltip-when-overflow />
|
||||
<el-table-column prop="erpCounts" label="ERP实时库存" min-width="90" show-tooltip-when-overflow />
|
||||
<el-table-column prop="differCount" label="立库-ERP库存差异" min-width="120" show-tooltip-when-overflow />
|
||||
<el-table-column prop="prd_ppbom_no" label="用料单号" min-width="150" show-tooltip-when-overflow />
|
||||
|
||||
Reference in New Issue
Block a user