no message
parent
3ed42758a5
commit
ba8f77f5dd
|
|
@ -10,6 +10,9 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.URLDecoder;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.cpte.modules.base.entity.ItemKey;
|
||||
import org.cpte.modules.base.service.IItemKeyService;
|
||||
import org.cpte.modules.inventory.entity.Inventory;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
|
|
@ -52,6 +55,9 @@ public class InventoryLogController extends JeecgController<InventoryLog, IInven
|
|||
@Autowired
|
||||
private IInventoryLogService inventoryLogService;
|
||||
|
||||
@Autowired
|
||||
private IItemKeyService itemKeyService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
|
|
@ -73,6 +79,19 @@ public class InventoryLogController extends JeecgController<InventoryLog, IInven
|
|||
QueryWrapper<InventoryLog> queryWrapper = QueryGenerator.initQueryWrapper(inventoryLog, req.getParameterMap());
|
||||
Page<InventoryLog> page = new Page<InventoryLog>(pageNo, pageSize);
|
||||
IPage<InventoryLog> pageList = inventoryLogService.page(page, queryWrapper);
|
||||
//物料属性
|
||||
List<Long> itemKeyIds = pageList.getRecords().stream().map(InventoryLog::getItemKeyId).toList();
|
||||
Map<Long, ItemKey> itemKeyMap=itemKeyService.queryByIdsToMap(itemKeyIds);
|
||||
for(InventoryLog log:pageList.getRecords()){
|
||||
ItemKey itemKey = itemKeyMap.get(log.getItemKeyId());
|
||||
if (itemKey != null) {
|
||||
log.setWhCode(itemKey.getWhCode());
|
||||
log.setProject(itemKey.getProject());
|
||||
log.setTaskNo(itemKey.getTaskNo());
|
||||
log.setPropC1(itemKey.getPropC1());
|
||||
log.setPropC3(itemKey.getPropC3());
|
||||
}
|
||||
}
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.*;
|
||||
|
|
@ -138,6 +135,39 @@ public class InventoryLog implements Serializable {
|
|||
@Excel(name = "变动后已分配数量", width = 15)
|
||||
@Schema(description = "变动后已分配数量")
|
||||
private java.math.BigDecimal afterAllocatedQty;
|
||||
|
||||
/**
|
||||
* 外部仓库
|
||||
*/
|
||||
@Schema(description = "外部仓库")
|
||||
@TableField(exist = false)
|
||||
private java.lang.String whCode;
|
||||
|
||||
/**
|
||||
* 项目号
|
||||
*/
|
||||
@Schema(description = "项目号")
|
||||
@TableField(exist = false)
|
||||
private java.lang.String project;
|
||||
/**
|
||||
* 任务号
|
||||
*/
|
||||
@Schema(description = "任务号")
|
||||
@TableField(exist = false)
|
||||
private java.lang.String taskNo;
|
||||
/**
|
||||
* 批次号
|
||||
*/
|
||||
@Schema(description = "批次号")
|
||||
@TableField(exist = false)
|
||||
private java.lang.String propC1;
|
||||
/**
|
||||
* 外部库存状态
|
||||
*/
|
||||
@Schema(description = "外部库存状态")
|
||||
@TableField(exist = false)
|
||||
private java.lang.String propC3;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,242 @@
|
|||
package org.cpte.modules.quartz.job;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.cpte.modules.constant.enums.PickStatusEnum;
|
||||
import org.cpte.modules.constant.enums.PickTypeEnum;
|
||||
import org.cpte.modules.shipping.entity.Pick;
|
||||
import org.cpte.modules.shipping.entity.PickDetail;
|
||||
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
||||
import org.cpte.modules.shipping.mapper.PickMapper;
|
||||
import org.cpte.modules.shipping.service.IPickDetailService;
|
||||
import org.cpte.modules.shipping.service.IPickService;
|
||||
import org.cpte.modules.shipping.vo.AllocationPickDetailData;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* 分配出库明细
|
||||
*/
|
||||
@Slf4j
|
||||
public class AllocatePickDetailJob implements Job {
|
||||
@Autowired
|
||||
private PickMapper pickMapper;
|
||||
|
||||
@Autowired
|
||||
private PickDetailMapper pickDetailMapper;
|
||||
|
||||
@Autowired
|
||||
private IPickService pickService;
|
||||
|
||||
@Autowired
|
||||
private IPickDetailService pickDetailService;
|
||||
|
||||
@Autowired
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
// 使用 ConcurrentHashMap 缓存已处理的结果
|
||||
private static final Map<String, Boolean> processedCache = new ConcurrentHashMap<>();
|
||||
|
||||
// 缓存最大大小,防止内存溢出
|
||||
private static final int MAX_CACHE_SIZE = 1000;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) {
|
||||
//1.获取未拣货完成的出库明细
|
||||
List<PickDetail> pickDetails = pickDetailMapper.queryUnFinishedPickDetail();
|
||||
if (CollectionUtils.isEmpty(pickDetails)) {
|
||||
log.info("没有待分配的出库明细");
|
||||
return;
|
||||
}
|
||||
//1.数据准备
|
||||
AllocationPickDetailData data = prepareData(pickDetails);
|
||||
|
||||
// 处理成品、配件类型的出库单
|
||||
processCpPjTypePicks(data.getCpPjPickIds(), data.getPickDetailMap(), data.getPickMap());
|
||||
|
||||
// 处理其他类型的出库单
|
||||
processOtherTypePicks(data.getOtherPickIds(), data.getPickDetailMap(), data.getPickMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据准备
|
||||
*/
|
||||
private AllocationPickDetailData prepareData(List<PickDetail> pickDetailList) {
|
||||
|
||||
//根据出库单ID进行分组
|
||||
Map<Long, List<PickDetail>> pickDetailMap = pickDetailList.stream().collect(Collectors.groupingBy(PickDetail::getPickId));
|
||||
|
||||
// 获取所有出库单信息
|
||||
List<Long> pickIds = new ArrayList<>(pickDetailMap.keySet());
|
||||
Map<Long, Pick> pickMap = pickDetailService.queryByPickIdsToMap(pickIds);
|
||||
|
||||
|
||||
// 成品、配件类型/其他类型
|
||||
List<Long> cpPjPickIds = new ArrayList<>();
|
||||
List<Long> otherPickIds = new ArrayList<>();
|
||||
|
||||
for (Long pickId : pickIds) {
|
||||
Pick pick = pickMap.get(pickId);
|
||||
if (isCPOrPJType(pick.getOrderType())) {
|
||||
cpPjPickIds.add(pickId);
|
||||
} else {
|
||||
otherPickIds.add(pickId);
|
||||
}
|
||||
}
|
||||
|
||||
return new AllocationPickDetailData(cpPjPickIds, otherPickIds, pickDetailMap, pickMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理成品/配件类型的出库单
|
||||
*/
|
||||
private void processCpPjTypePicks(List<Long> cpPjPickIds, Map<Long, List<PickDetail>> pickDetailMap, Map<Long, Pick> pickMap) {
|
||||
if (CollectionUtils.isEmpty(cpPjPickIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 全局状态:是否有成品/配件类型的任务正在执行
|
||||
boolean hasExecutingCpPjTask = false;
|
||||
|
||||
for (Long pickId : cpPjPickIds) {
|
||||
Pick pick = pickMap.get(pickId);
|
||||
if (hasExecutingCpPjTask) {
|
||||
log.info("有成品/配件类型任务正在执行,跳过出库单【{}】的分配", pick.getThirdOrderNo());
|
||||
continue;
|
||||
}
|
||||
|
||||
List<PickDetail> details = pickDetailMap.get(pickId);
|
||||
if (CollectionUtils.isEmpty(details)) {
|
||||
continue;
|
||||
}
|
||||
// 处理单个成品/配件出库单
|
||||
hasExecutingCpPjTask = allocateCpPjPick(pick, details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配单个成品/配件出库单
|
||||
*
|
||||
* @return 是否分配了任务且任务正在执行
|
||||
*/
|
||||
private boolean allocateCpPjPick(Pick pick, List<PickDetail> pickDetails) {
|
||||
for (PickDetail detail : pickDetails) {
|
||||
// 检查已分配的任务是否正在执行
|
||||
if (isAlreadyAssigned(detail.getStatus())) {
|
||||
if (isPickDetailExecuting(detail.getId())) {
|
||||
log.info("出库单【{}】的明细【{}】任务正在执行", pick.getThirdOrderNo(), detail.getId());
|
||||
return true; // 有任务正在执行
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
allocatePickDetail(detail);
|
||||
|
||||
// 检查分配后任务状态
|
||||
if (isPickDetailExecuting(detail.getId())) {
|
||||
log.info("出库单【{}】的明细【{}】任务已生成", pick.getThirdOrderNo(), detail.getId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // 没有正在执行的任务
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他类型的出库单
|
||||
*/
|
||||
private void processOtherTypePicks(List<Long> otherPickIds, Map<Long, List<PickDetail>> pickDetailMap, Map<Long, Pick> pickMap) {
|
||||
if (CollectionUtils.isEmpty(otherPickIds)) {
|
||||
return;
|
||||
}
|
||||
for (Long pickId : otherPickIds) {
|
||||
Pick pick = pickMap.get(pickId);
|
||||
List<PickDetail> details = pickDetailMap.get(pickId);
|
||||
if (CollectionUtils.isEmpty(details)) {
|
||||
continue;
|
||||
}
|
||||
// 分配单个其他类型出库单的所有明细
|
||||
log.info("分配其他类型出库单的明细【{}】", pick.getThirdOrderNo());
|
||||
allocateOtherPick(details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配单个其他类型出库单的所有明细
|
||||
*/
|
||||
private void allocateOtherPick(List<PickDetail> details) {
|
||||
for (PickDetail detail : details) {
|
||||
// 如果已分配,跳过
|
||||
if (isAlreadyAssigned(detail.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
allocatePickDetail(detail);
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法
|
||||
private boolean isCPOrPJType(Integer orderType) {
|
||||
return PickTypeEnum.CP.getValue().equals(orderType)
|
||||
|| PickTypeEnum.PJ.getValue().equals(orderType);
|
||||
}
|
||||
|
||||
private boolean isAlreadyAssigned(Integer status) {
|
||||
return PickStatusEnum.ASSIGNED.getValue().equals(status);
|
||||
}
|
||||
|
||||
private boolean isPickDetailExecuting(Long pickDetailId) {
|
||||
return pickMapper.queryPickDetailIsExecuting(pickDetailId) > 0;
|
||||
}
|
||||
|
||||
private void allocatePickDetail(PickDetail pickDetail) {
|
||||
// 分配单个出库明细
|
||||
long startTime = System.currentTimeMillis();
|
||||
List<String> resultMsg;
|
||||
try {
|
||||
// 每次只分配一个出库单明细
|
||||
resultMsg = pickService.allocatePickDetail(pickDetail);
|
||||
if (CollectionUtils.isNotEmpty(resultMsg)) {
|
||||
// 生成缓存键
|
||||
String cacheKey = generateCacheKey(resultMsg);
|
||||
|
||||
// 检查是否已经处理过相同的内容
|
||||
if (!processedCache.containsKey(cacheKey)) {
|
||||
// 新内容,记录日志
|
||||
baseCommonService.addLog("出库明细分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
|
||||
|
||||
// 添加到缓存
|
||||
processedCache.put(cacheKey, true);
|
||||
|
||||
// 控制缓存大小
|
||||
if (processedCache.size() > MAX_CACHE_SIZE) {
|
||||
processedCache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resultMsg = List.of(e.getMessage());
|
||||
log.error("分配出库明细失败,ID: {}, 错误: {}", pickDetail.getId(), resultMsg);
|
||||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("分配出库明细耗时:{}ms,处理ID:{}", endTime - startTime, pickDetail.getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成缓存键 - 基于分配结果生成唯一标识
|
||||
*/
|
||||
private String generateCacheKey(List<String> resultMsg) {
|
||||
// 对结果进行排序后拼接,确保相同内容生成相同键
|
||||
return resultMsg.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.sorted()
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
}
|
||||
|
|
@ -194,6 +194,8 @@ public class PickController {
|
|||
@GetMapping(value = "/queryPickDetailByMainId")
|
||||
public Result<List<PickDetail>> queryPickDetailListByMainId(@RequestParam(name = "id", required = true) Long id) {
|
||||
List<PickDetail> pickDetailList = pickDetailService.selectByMainId(id);
|
||||
//根据 lineNo 排序
|
||||
pickDetailList.sort(Comparator.comparingInt(PickDetail::getLineNo));
|
||||
return Result.OK(pickDetailList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,35 +10,42 @@ import org.apache.ibatis.annotations.Param;
|
|||
/**
|
||||
* @Description: 出库明细
|
||||
* @author: cpte
|
||||
* @Date: 2025-11-14
|
||||
* @Date: 2025-11-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface PickDetailMapper extends BaseMapper<PickDetail> {
|
||||
|
||||
/**
|
||||
* 通过主表id删除子表数据
|
||||
*
|
||||
* @param mainId 主表id
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean deleteByMainId(@Param("mainId") Long mainId);
|
||||
/**
|
||||
* 通过主表id删除子表数据
|
||||
*
|
||||
* @param mainId 主表id
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean deleteByMainId(@Param("mainId") Long mainId);
|
||||
|
||||
/**
|
||||
* 通过主表id查询子表数据
|
||||
*
|
||||
* @param mainId 主表id
|
||||
* @return List<PickDetail>
|
||||
*/
|
||||
public List<PickDetail> selectByMainId(@Param("mainId") Long mainId);
|
||||
/**
|
||||
* 通过主表id查询子表数据
|
||||
*
|
||||
* @param mainId 主表id
|
||||
* @return List<PickDetail>
|
||||
*/
|
||||
public List<PickDetail> selectByMainId(@Param("mainId") Long mainId);
|
||||
|
||||
/**
|
||||
* 通过出库单id集合查询出库明细
|
||||
*
|
||||
* @param pickIds 出库单id集合
|
||||
* @return List<PickDetail>
|
||||
*/
|
||||
List<PickDetail> queryByPickIds(@Param("pickIds") List<Long> pickIds);
|
||||
/**
|
||||
* 通过出库单id集合查询出库明细
|
||||
*
|
||||
* @param pickIds 出库单id集合
|
||||
* @return List<PickDetail>
|
||||
*/
|
||||
List<PickDetail> queryByPickIds(@Param("pickIds") List<Long> pickIds);
|
||||
|
||||
@Select("select MAX(line_no) from data_pick_detail where pick_id = #{pickId} ")
|
||||
Integer queryMaxLineNoByPickId(@Param("pickId") Long pickId);
|
||||
@Select("select MAX(line_no) from data_pick_detail where pick_id = #{pickId} ")
|
||||
Integer queryMaxLineNoByPickId(@Param("pickId") Long pickId);
|
||||
|
||||
/**
|
||||
* 按顺序查询未完成的出库明细
|
||||
*
|
||||
* @return List<PickDetail>
|
||||
*/
|
||||
List<PickDetail> queryUnFinishedPickDetail();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,4 +41,12 @@ public interface PickMapper extends BaseMapper<Pick> {
|
|||
* @return Long
|
||||
*/
|
||||
Long queryPickIsExecuting(@Param("pickId") Long pickId);
|
||||
|
||||
/**
|
||||
* 查询出库单任务是否正在执行
|
||||
*
|
||||
* @param pickDetailId 出库单明细
|
||||
* @return Long
|
||||
*/
|
||||
Long queryPickDetailIsExecuting(@Param("pickDetailId") Long pickDetailId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,4 +26,12 @@
|
|||
</foreach>
|
||||
ORDER BY line_no
|
||||
</select>
|
||||
|
||||
<select id="queryUnFinishedPickDetail" resultType="org.cpte.modules.shipping.entity.PickDetail">
|
||||
select pd.* from data_pick p
|
||||
join data_pick_detail pd on pd.pick_id=p.id
|
||||
where p.`status` in (1,2,3,4)
|
||||
and pd.order_qty>pd.picked_qty
|
||||
order by p.order_date,pd.line_no
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,16 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.cpte.modules.shipping.mapper.PickMapper">
|
||||
<select id="queryPickIsExecuting" resultType="long">
|
||||
SELECT count(p.id) FROM data_pick p
|
||||
JOIN data_task t ON t.pick_id=p.id
|
||||
SELECT count(t.id) FROM data_task t
|
||||
JOIN data_agv_task agv ON agv.id=t.agv_task_id
|
||||
WHERE p.id = #{pickId}
|
||||
WHERE t.pick_id = #{pickId}
|
||||
AND agv.`status` in (1,2,3)
|
||||
</select>
|
||||
|
||||
<select id="queryPickDetailIsExecuting" resultType="long">
|
||||
SELECT count(t.id) FROM data_task t
|
||||
JOIN data_agv_task agv ON agv.id=t.agv_task_id
|
||||
WHERE t.pick_detail_id = #{pickDetailId}
|
||||
AND agv.`status` in (1,2,3)
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -54,6 +54,13 @@ public interface IPickService extends IService<Pick> {
|
|||
*/
|
||||
List<String> allocatePick(List<Long> pickIds);
|
||||
|
||||
/**
|
||||
* 分配出库单
|
||||
*
|
||||
* @param pickDetail 出库单明细
|
||||
*/
|
||||
List<String> allocatePickDetail(PickDetail pickDetail);
|
||||
|
||||
/**
|
||||
* 取消分配
|
||||
*
|
||||
|
|
|
|||
|
|
@ -154,6 +154,11 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
|
|||
return allocateProcessor.allocatePick(pickIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> allocatePickDetail(PickDetail pickDetail) {
|
||||
return allocateProcessor.allocatePickDetail(pickDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> cancelAllocate(List<Long> pickIds) {
|
||||
return cancelAllocateProcessor.cancelAllocatePick(pickIds);
|
||||
|
|
|
|||
|
|
@ -133,6 +133,46 @@ public class AllocateProcessor {
|
|||
return new ArrayList<>(errorMsgSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配出库单明细
|
||||
*
|
||||
* @param pickDetail 出库单明细
|
||||
* @return 错误信息
|
||||
*/
|
||||
public List<String> allocatePickDetail(PickDetail pickDetail) {
|
||||
// 错误信息去重(LinkedHashSet保证顺序和唯一)
|
||||
Set<String> errorMsgSet = new LinkedHashSet<>();
|
||||
|
||||
// 1.数据准备
|
||||
AllocationData data = prepareAllocationDetailData(pickDetail);
|
||||
|
||||
//2.验证库存
|
||||
if (!validateInventory(data, errorMsgSet)) {
|
||||
return new ArrayList<>(errorMsgSet);
|
||||
}
|
||||
|
||||
//3.创建数据结构
|
||||
Map<Long, Inventory> inventoryUpdateMap = new HashMap<>();
|
||||
Map<Long, PickDetail> pickDetailUpdateMap = new HashMap<>();
|
||||
List<Task> createToTask = new ArrayList<>();
|
||||
List<Point> movePoints = new ArrayList<>();
|
||||
|
||||
//4.分配
|
||||
allocate(data, inventoryUpdateMap, pickDetailUpdateMap, createToTask, movePoints, errorMsgSet);
|
||||
|
||||
//5.生成移位任务
|
||||
moveTask(createToTask, movePoints);
|
||||
|
||||
//6.批量操作
|
||||
batchProcessor.batchAllocate(inventoryUpdateMap, pickDetailUpdateMap, createToTask);
|
||||
|
||||
//7.刷新出库单
|
||||
refreshData(data);
|
||||
|
||||
return new ArrayList<>(errorMsgSet);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据准备
|
||||
*
|
||||
|
|
@ -206,6 +246,80 @@ public class AllocateProcessor {
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据准备
|
||||
*
|
||||
* @param pickDetail 出库单明细
|
||||
* @return AllocationData
|
||||
*/
|
||||
private AllocationData prepareAllocationDetailData(PickDetail pickDetail) {
|
||||
AllocationData data = new AllocationData();
|
||||
|
||||
//查询出库单
|
||||
Map<Long, Pick> pickMap = pickDetailService.queryByPickIdsToMap(Collections.singletonList(pickDetail.getPickId()));
|
||||
data.setPickMap(pickMap);
|
||||
|
||||
//查询出库单明细
|
||||
List<PickDetail> pickDetails = new ArrayList<>();
|
||||
pickDetails.add(pickDetail);
|
||||
data.setPickDetails(pickDetails);
|
||||
|
||||
//查询物料
|
||||
List<Long> itemIds = pickDetails.stream().map(PickDetail::getItemId).distinct().toList();
|
||||
Map<Long, Item> itemMap = itemService.queryByItemIdsToMap(itemIds);
|
||||
data.setItemMap(itemMap);
|
||||
|
||||
//筛选查询库存的条件(非空去重)外部仓库、项目号、任务号、批次、外部库存状态
|
||||
List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).distinct().toList();
|
||||
List<String> projectList = pickDetails.stream().map(PickDetail::getProject).distinct().toList();
|
||||
List<String> taskNoList = pickDetails.stream().map(PickDetail::getTaskNo).distinct().toList();
|
||||
List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).distinct().toList();
|
||||
List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).distinct().toList();
|
||||
List<ItemKey> itemKeys = itemKeyMapper.queryItemKeys(itemIds, whCodeList, projectList, taskNoList, propC1List, propC3List);
|
||||
|
||||
//根据物料属性分组
|
||||
Map<ItemGroupKey, ItemKey> itemGroupKey = itemKeys.stream()
|
||||
.collect(Collectors.toMap(
|
||||
itemKey -> ItemGroupKey.of(
|
||||
itemKey.getItemId(),
|
||||
itemKey.getWhCode(),
|
||||
itemKey.getProject(),
|
||||
itemKey.getTaskNo(),
|
||||
itemKey.getPropC1(),
|
||||
itemKey.getPropC3()
|
||||
),
|
||||
itemKey -> itemKey
|
||||
));
|
||||
data.setItemGroupMap(itemGroupKey);
|
||||
|
||||
//查询库存
|
||||
List<Inventory> inventories = null;
|
||||
List<Long> itemKeyIds = itemKeys.stream().map(ItemKey::getId).distinct().toList();
|
||||
if (CollectionUtils.isNotEmpty(itemKeyIds)) {
|
||||
inventories = inventoryMapper.queryInventoryByItemKeyId(itemKeyIds);
|
||||
data.setInventories(inventories);
|
||||
}
|
||||
|
||||
|
||||
if (CollectionUtils.isNotEmpty(inventories)) {
|
||||
//根据itemKeyId分组
|
||||
Map<Long, List<Inventory>> inventoryMap = inventories.stream().collect(Collectors.groupingBy(Inventory::getItemKeyId));
|
||||
data.setInventoryMap(inventoryMap);
|
||||
|
||||
//获取容器
|
||||
List<Long> stockIds = inventories.stream().map(Inventory::getStockId).distinct().toList();
|
||||
Map<Long, Stock> stockMap = stockService.queryByStockIdsToMap(stockIds);
|
||||
data.setStockMap(stockMap);
|
||||
|
||||
//获取目标库位
|
||||
List<Long> pointIds = inventories.stream().map(Inventory::getPointId).distinct().toList();
|
||||
Map<Long, Point> pointMap = pointService.queryByPointIdsToMap(pointIds);
|
||||
data.setPointMap(pointMap);
|
||||
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证库存
|
||||
*
|
||||
|
|
@ -597,7 +711,6 @@ public class AllocateProcessor {
|
|||
Map<Long, Inventory> inventoryUpdateMap) {
|
||||
Inventory targetInventory = inventoryUpdateMap.getOrDefault(inventory.getId(), inventory);
|
||||
BigDecimal newQueuedQty = BigDecimalUtil.add(targetInventory.getQueuedQty(), allocateQty, 0);
|
||||
log.info("更新库存分配数: {}", newQueuedQty);
|
||||
targetInventory.setQueuedQty(newQueuedQty);
|
||||
targetInventory.setStatus(InventoryStatusEnum.ALLOCATED.getValue());
|
||||
inventoryUpdateMap.put(targetInventory.getId(), targetInventory);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package org.cpte.modules.shipping.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.cpte.modules.shipping.entity.Pick;
|
||||
import org.cpte.modules.shipping.entity.PickDetail;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class AllocationPickDetailData {
|
||||
private List<Long> cpPjPickIds; // 成品/配件类型出库单ID列表
|
||||
private List<Long> otherPickIds; // 其他类型出库单ID列表
|
||||
private Map<Long, List<PickDetail>> pickDetailMap; // 按出库单分组的明细
|
||||
private Map<Long, Pick> pickMap; // 出库单信息映射
|
||||
}
|
||||
|
|
@ -206,6 +206,7 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void resendTes(AgvTask agvTask) {
|
||||
handleResend(agvTask);
|
||||
}
|
||||
|
|
@ -279,6 +280,12 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
|||
Point point = pointMapper.queryByPointCode(agvTask.getEndCode());
|
||||
point.setStatus(CommonStatusEnum.USED.getValue());
|
||||
pointMapper.updateById(point);
|
||||
}else if(BusinessTypeEnum.OUTBOUND.getValue().equals(agvTask.getType())){
|
||||
List<Task> tasks=taskMapper.queryByAgvTask(agvTask.getId());
|
||||
for (Task task:tasks){
|
||||
task.setAgvTaskId(newAgvTask.getId());
|
||||
}
|
||||
taskMapper.updateById(tasks);
|
||||
}
|
||||
switch (agvTask.getType()) {
|
||||
case "INBOUND":
|
||||
|
|
|
|||
Loading…
Reference in New Issue