|
|
@ -237,6 +237,7 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { |
|
|
shipmentReserveVos.add(shipmentReserveVo); |
|
|
shipmentReserveVos.add(shipmentReserveVo); |
|
|
} |
|
|
} |
|
|
List<ShipmentReserveVo> reserveVos = splitReserves(shipmentReserveVos, customerIssueDto.getShipmentLine()); |
|
|
List<ShipmentReserveVo> reserveVos = splitReserves(shipmentReserveVos, customerIssueDto.getShipmentLine()); |
|
|
|
|
|
log.info("拆分后的数组:{},ifsline:{}",reserveVos,customerIssueDto.getShipmentLine()); |
|
|
|
|
|
|
|
|
//调用ifs接口 |
|
|
//调用ifs接口 |
|
|
for (ShipmentReserveVo lineVo : reserveVos){ |
|
|
for (ShipmentReserveVo lineVo : reserveVos){ |
|
|
@ -295,12 +296,10 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { |
|
|
reserveTotalMap.put(key, reserveTotalMap.getOrDefault(key, BigDecimal.ZERO).add(reserve.getTransQty())); |
|
|
reserveTotalMap.put(key, reserveTotalMap.getOrDefault(key, BigDecimal.ZERO).add(reserve.getTransQty())); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 验证总量一致性:比较两个 map 中每个 key 的总数量是否一致 |
|
|
|
|
|
// 注意:假设 contract 对应 site,inventoryPartNo 对应 partNo,所以两个 key 格式的值应该相同 |
|
|
|
|
|
|
|
|
// 验证总量一致性 |
|
|
Set<String> allKeys = new HashSet<>(); |
|
|
Set<String> allKeys = new HashSet<>(); |
|
|
allKeys.addAll(lineTotalMap.keySet()); |
|
|
allKeys.addAll(lineTotalMap.keySet()); |
|
|
allKeys.addAll(reserveTotalMap.keySet()); |
|
|
allKeys.addAll(reserveTotalMap.keySet()); |
|
|
|
|
|
|
|
|
for (String key : allKeys) { |
|
|
for (String key : allKeys) { |
|
|
BigDecimal lineTotal = lineTotalMap.getOrDefault(key, BigDecimal.ZERO); |
|
|
BigDecimal lineTotal = lineTotalMap.getOrDefault(key, BigDecimal.ZERO); |
|
|
BigDecimal reserveTotal = reserveTotalMap.getOrDefault(key, BigDecimal.ZERO); |
|
|
BigDecimal reserveTotal = reserveTotalMap.getOrDefault(key, BigDecimal.ZERO); |
|
|
@ -311,29 +310,53 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 构建以contract|inventoryPartNo为键的lines映射表(用于后续拆分) |
|
|
|
|
|
Map<String, List<ShipmentLineVo>> lineMap = new HashMap<>(); |
|
|
|
|
|
|
|
|
// 构建以contract|inventoryPartNo为键的lines队列(保持原有顺序用来逐个吃掉数量) |
|
|
|
|
|
Map<String, Queue<LineAllocation>> lineQueueMap = new HashMap<>(); |
|
|
for (ShipmentLineVo line : lines) { |
|
|
for (ShipmentLineVo line : lines) { |
|
|
|
|
|
BigDecimal availableQty = line.getInventoryQty().subtract(line.getQtyAssigned()); |
|
|
|
|
|
if (availableQty.compareTo(BigDecimal.ZERO) <= 0) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
String key = line.getContract() + "|" + line.getInventoryPartNo(); |
|
|
String key = line.getContract() + "|" + line.getInventoryPartNo(); |
|
|
lineMap.computeIfAbsent(key, k -> new ArrayList<>()).add(line); |
|
|
|
|
|
|
|
|
lineQueueMap.computeIfAbsent(key, k -> new LinkedList<>()) |
|
|
|
|
|
.add(new LineAllocation(line, availableQty)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
List<ShipmentReserveVo> result = new ArrayList<>(); |
|
|
List<ShipmentReserveVo> result = new ArrayList<>(); |
|
|
|
|
|
|
|
|
// 遍历reserves进行拆分处理 |
|
|
// 遍历reserves进行拆分处理 |
|
|
for (ShipmentReserveVo reserve : reserves) { |
|
|
for (ShipmentReserveVo reserve : reserves) { |
|
|
// 使用 site|partNo 格式查找(假设 contract=site, inventoryPartNo=partNo,所以 key 值相同) |
|
|
|
|
|
String key = reserve.getSite() + "|" + reserve.getPartNo(); |
|
|
String key = reserve.getSite() + "|" + reserve.getPartNo(); |
|
|
List<ShipmentLineVo> matchedLines = lineMap.get(key); |
|
|
|
|
|
|
|
|
Queue<LineAllocation> queue = lineQueueMap.get(key); |
|
|
|
|
|
if (queue == null || queue.isEmpty()) { |
|
|
|
|
|
throw new IllegalStateException("未找到匹配的ShipmentLine用于分配数量,key=" + key); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (matchedLines != null && !matchedLines.isEmpty()) { |
|
|
|
|
|
// 执行拆分并赋值 |
|
|
|
|
|
for (ShipmentLineVo line : matchedLines) { |
|
|
|
|
|
result.add(createSplitReserve(reserve, line)); |
|
|
|
|
|
|
|
|
BigDecimal remainingReserve = reserve.getTransQty(); |
|
|
|
|
|
while (remainingReserve.compareTo(BigDecimal.ZERO) > 0) { |
|
|
|
|
|
LineAllocation current = queue.peek(); |
|
|
|
|
|
if (current == null) { |
|
|
|
|
|
throw new IllegalStateException("可分配数量不足,key=" + key); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BigDecimal alloc = remainingReserve.min(current.remaining); |
|
|
|
|
|
|
|
|
|
|
|
ShipmentReserveVo split = new ShipmentReserveVo(); |
|
|
|
|
|
BeanUtils.copyProperties(reserve, split); |
|
|
|
|
|
split.setTransQty(alloc); |
|
|
|
|
|
split.setIfsSourceRef1(current.line.getSourceRef1()); |
|
|
|
|
|
split.setIfsSourceRef2(current.line.getSourceRef2()); |
|
|
|
|
|
split.setIfsSourceRef3(current.line.getSourceRef3()); |
|
|
|
|
|
split.setIfsInputUoM(current.line.getInventoryUom()); |
|
|
|
|
|
split.setIfsBlockedForPickByChoice(current.line.getCreditBlocked()); |
|
|
|
|
|
result.add(split); |
|
|
|
|
|
|
|
|
|
|
|
// 更新剩余量 |
|
|
|
|
|
remainingReserve = remainingReserve.subtract(alloc); |
|
|
|
|
|
current.remaining = current.remaining.subtract(alloc); |
|
|
|
|
|
if (current.remaining.compareTo(BigDecimal.ZERO) == 0) { |
|
|
|
|
|
queue.poll(); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
|
|
|
// 处理无匹配lines的情况(保留原始对象) |
|
|
|
|
|
result.add(reserve); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
@ -345,22 +368,14 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { |
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add); |
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ShipmentReserveVo createSplitReserve(ShipmentReserveVo reserve, ShipmentLineVo line) { |
|
|
|
|
|
// 创建新对象并复制基础字段 |
|
|
|
|
|
ShipmentReserveVo split = new ShipmentReserveVo(); |
|
|
|
|
|
BeanUtils.copyProperties(reserve, split); |
|
|
|
|
|
|
|
|
|
|
|
// 设置拆分后的数量 |
|
|
|
|
|
split.setTransQty(line.getInventoryQty().subtract(line.getQtyAssigned())); |
|
|
|
|
|
|
|
|
private static class LineAllocation { |
|
|
|
|
|
private ShipmentLineVo line; |
|
|
|
|
|
private BigDecimal remaining; |
|
|
|
|
|
|
|
|
// 从line复制附加字段 |
|
|
|
|
|
split.setIfsSourceRef1(line.getSourceRef1()); |
|
|
|
|
|
split.setIfsSourceRef2(line.getSourceRef2()); |
|
|
|
|
|
split.setIfsSourceRef3(line.getSourceRef3()); |
|
|
|
|
|
split.setIfsInputUoM(line.getInventoryUom()); |
|
|
|
|
|
split.setIfsBlockedForPickByChoice(line.getCreditBlocked()); |
|
|
|
|
|
|
|
|
|
|
|
return split; |
|
|
|
|
|
|
|
|
LineAllocation(ShipmentLineVo line, BigDecimal remaining) { |
|
|
|
|
|
this.line = line; |
|
|
|
|
|
this.remaining = remaining; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public List<ShipmentReserveVo> mapShipmentData(List<ShipmentReserveVo> reserves, List<ShipmentLineVo> lines) { |
|
|
public List<ShipmentReserveVo> mapShipmentData(List<ShipmentReserveVo> reserves, List<ShipmentLineVo> lines) { |
|
|
|