This commit is contained in:
2026-08-28 10:03:32 +08:00
parent dd117b8fc2
commit a6f266687e
13 changed files with 147 additions and 16 deletions
@@ -6,6 +6,8 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface ReceivingContainerSessionMapper extends BaseMapper<ReceivingContainerSession> {
@Select("SELECT * FROM ll_receiving_container_session " +
@@ -16,6 +18,13 @@ public interface ReceivingContainerSessionMapper extends BaseMapper<ReceivingCon
"WHERE active_operator_key=#{activeOperatorKey} LIMIT 1")
ReceivingContainerSession findActiveByOperator(@Param("activeOperatorKey") String activeOperatorKey);
@Select("SELECT * FROM ll_receiving_container_session " +
"WHERE active_container_key=#{activeContainerKey} LIMIT 1")
ReceivingContainerSession findActiveByContainer(@Param("activeContainerKey") String activeContainerKey);
@Select("SELECT * FROM ll_receiving_container_session WHERE active_container_key IS NOT NULL")
List<ReceivingContainerSession> findActiveContainers();
@Select("SELECT * FROM ll_receiving_container_session " +
"WHERE active_container_key=#{activeContainerKey} LIMIT 1 FOR UPDATE")
ReceivingContainerSession lockActiveByContainer(@Param("activeContainerKey") String activeContainerKey);
@@ -194,11 +194,22 @@ public class InboundStockReceiptService {
}
if (destinationCode == null) destinationCode = "";
String operationKey = "PDA_STOCK_IN:" + task.getId() + ":" + allocation.getId() + ":" + sku.skuCode();
String customerName = required(order.getCustomerName(),
"Customer name snapshot is required for stock-in");
String overseasWarehouseId = required(order.getOverseasWarehouseId(),
"Actual overseas warehouse is required for stock-in");
String overseasWarehouseName = required(order.getOverseasWarehouseName(),
"Actual overseas warehouse name is required for stock-in");
if (plan.getOverseasWarehouseId() == null
|| !overseasWarehouseId.equals(String.valueOf(plan.getOverseasWarehouseId()))) {
throw conflict("Inbound plan and tail-leg order overseas warehouses must match for stock-in");
}
if (overseasWarehouseId.equals(trim(order.getSourceWarehouseId()))) {
throw conflict("Actual overseas warehouse must not use the domestic source warehouse");
}
InventoryCommandResponse result = inventory.stockIn(customerId, task.getOperatorId(),
new InventoryCommandRequests.StockIn(null, order.getCustomerName(), overseasWarehouseId,
null, order.getOverseasWarehouseName(), line.getDestinationWarehouseId(), destinationCode,
new InventoryCommandRequests.StockIn(null, customerName, overseasWarehouseId,
null, overseasWarehouseName, line.getDestinationWarehouseId(), destinationCode,
line.getDestinationWarehouseName(), order.getId(), plan.getPlanNo(), line.getInboundCode(),
sku.skuCode(), sku.productNameZh(), sku.productNameEn(),
pallet.getWarehousePalletId(), pallet.getPalletNo(), plan.getPlanNo(),
@@ -103,7 +103,14 @@ public class ReceivingContainerService {
grouped.computeIfAbsent(plan.getContainerNo(), ignored -> new ArrayList<>()).add(plan);
}
});
return grouped.entrySet().stream().filter(entry -> eligible(entry.getValue(), overseasWarehouseId)).map(entry -> {
String operatorLockKey = activeOperatorKey(operatorKey);
Set<String> reservedByOthers = sessions.findActiveContainers().stream()
.filter(session -> !operatorLockKey.equals(session.getActiveOperatorKey()))
.map(ReceivingContainerSession::getActiveContainerKey).filter(Objects::nonNull).collect(Collectors.toSet());
return grouped.entrySet().stream()
.filter(entry -> eligible(entry.getValue(), overseasWarehouseId))
.filter(entry -> !reservedByOthers.contains(activeContainerKey(entry.getKey())))
.map(entry -> {
requireSingleCustomer(entry.getValue(), entry.getKey());
Totals totals = totals(entry.getValue());
boolean active = current != null && entry.getKey().equals(current.getContainerNo());
@@ -123,6 +130,10 @@ public class ReceivingContainerService {
if (current != null && !containerNo.equals(current.getContainerNo())) {
throw conflict("Current account is locked to another selected container");
}
ReceivingContainerSession reserved = sessions.findActiveByContainer(activeContainerKey(containerNo));
if (reserved != null && !activeOperatorKey(operatorKey).equals(reserved.getActiveOperatorKey())) {
throw conflict("Container is already signed or prepared by another account");
}
WarehouseResourceGateway.WarehouseReference receivingWarehouse =
warehouse.requireActiveSharedWarehouse(overseasWarehouseId);
return snapshot(current != null && containerNo.equals(current.getContainerNo()) ? current : waitingView(