暂扣 标记合托功能

This commit is contained in:
2026-08-28 14:20:48 +08:00
parent 6a83008ba6
commit 66b9c3aa77
34 changed files with 416 additions and 51 deletions
@@ -31,4 +31,10 @@ public interface InventoryCommandMapper {
List<InventoryBalance> lockInboundTransitBalances(@Param("customerId") String customerId,
@Param("inboundOrderId") Long inboundOrderId,
@Param("inboundCode") String inboundCode);
@Select("SELECT p.* FROM ll_inventory_position p JOIN ll_inventory_balance b ON b.id=p.balance_id " +
"WHERE p.customer_id=#{customerId} AND b.inbound_order_id=#{inboundOrderId} " +
"AND p.hold_packages>0 ORDER BY p.id FOR UPDATE")
List<InventoryPosition> lockInboundHeldPositions(@Param("customerId") String customerId,
@Param("inboundOrderId") Long inboundOrderId);
}
@@ -60,13 +60,25 @@ public class InventoryCommandService {
@Transactional
public InventoryCommandResponse stockIn(String customerId, String operatorId,
InventoryCommandRequests.StockIn request) {
return stockIn(customerId, operatorId, request, false);
}
@Transactional
public InventoryCommandResponse stockInHeld(String customerId, String operatorId,
InventoryCommandRequests.StockIn request) {
return stockIn(customerId, operatorId, request, true);
}
private InventoryCommandResponse stockIn(String customerId, String operatorId,
InventoryCommandRequests.StockIn request, boolean held) {
return execute(customerId, operatorId, "STOCK_IN", request.idempotencyKey(), request, operation -> {
List<InventoryBalance> transitBalances = commands.lockInboundTransitBalances(customerId,
request.inboundOrderId(), request.inboundCode());
InventoryBalance balance = balance(customerId, request);
InventoryPosition position = position(customerId, balance, request);
long before = value(position.getAvailablePackages());
position.setAvailablePackages(before + request.packages());
long before = held ? value(position.getHoldPackages()) : value(position.getAvailablePackages());
if (held) position.setHoldPackages(before + request.packages());
else position.setAvailablePackages(before + request.packages());
position.setStatus("OCCUPIED");
position.setVersion(value(position.getVersion()) + 1);
position.setUpdatedAt(LocalDateTime.now());
@@ -74,11 +86,12 @@ public class InventoryCommandService {
long transferred = transferInTransit(customerId, operatorId, operation.getId(), balance,
transitBalances, request);
balance.setAvailablePackages(value(balance.getAvailablePackages()) + request.packages());
if (held) balance.setHoldPackages(value(balance.getHoldPackages()) + request.packages());
else balance.setAvailablePackages(value(balance.getAvailablePackages()) + request.packages());
touch(balance);
balances.updateById(balance);
ledger(customerId, operatorId, operation.getId(), balance, position, sku(request.skuCode()), "STOCK_IN",
transferred == request.packages() ? "IN_TRANSIT" : "OUTSIDE", "AVAILABLE",
transferred == request.packages() ? "IN_TRANSIT" : "OUTSIDE", held ? "HOLD" : "AVAILABLE",
before, request.packages(), before + request.packages(),
request.businessOrderNo(), request.inboundOrderNo(), null, request.sourceEventId(),
request.idempotencyKey(), request.remark());
@@ -86,6 +99,17 @@ public class InventoryCommandService {
});
}
@Transactional
public void releaseInboundOrderHold(String customerId, String operatorId, long inboundOrderId,
String businessOrderNo, String remark) {
for (InventoryPosition position : commands.lockInboundHeldPositions(customerId, inboundOrderId)) {
long packages = value(position.getHoldPackages());
if (packages == 0) continue;
release(customerId, operatorId, new InventoryCommandRequests.Move(position.getId(), packages,
businessOrderNo, null, null, "ORDER_HOLD_RELEASE:" + inboundOrderId + ":" + position.getId(), remark));
}
}
private long transferInTransit(String customerId, String operatorId, Long operationId,
InventoryBalance target, List<InventoryBalance> sources,
InventoryCommandRequests.StockIn request) {