feat(lastleg): redispatch returned cargo and reconcile source signatures
This commit is contained in:
+22
@@ -41,6 +41,7 @@ public class InventoryCommandService {
|
||||
@Resource private InventoryLedgerMapper ledgers;
|
||||
@Resource private InventoryOperationMapper operations;
|
||||
@Resource private InventoryCommandMapper commands;
|
||||
@Resource private com.baiyue.lastleg.inventory.mapper.ReturnStockReceiptMapper returnReceipts;
|
||||
@Resource private WarehouseResourceGateway warehouseGateway;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
|
||||
@@ -335,6 +336,17 @@ public class InventoryCommandService {
|
||||
InventoryOperation existing = operations.findIdempotency(customerId, normalizedKey);
|
||||
if (existing != null) return replayReturned(existing, requestHash);
|
||||
|
||||
Map<Long, com.baiyue.lastleg.inventory.mapper.ReturnStockReceiptMapper.ReturnOwner> returnOwners = new LinkedHashMap<>();
|
||||
for (var source : sources.values()) {
|
||||
var owner = returnReceipts.owner(customerId, exceptionNo, outboundNo, source.outboundPalletItemId(), source.inventoryPositionId());
|
||||
if (owner == null || owner.orderId() == null || !Objects.equals(owner.inboundOrderId(), request.inboundOrderId()))
|
||||
throw conflict("Returned stock receipt is missing the original order attribution");
|
||||
returnOwners.put(source.outboundPalletItemId(), owner);
|
||||
}
|
||||
for (Long orderId : returnOwners.values().stream().map(com.baiyue.lastleg.inventory.mapper.ReturnStockReceiptMapper.ReturnOwner::orderId).distinct().sorted().toList()) {
|
||||
if (returnReceipts.lockOrder(customerId, orderId) == null) throw conflict("Returned stock source order is missing or held");
|
||||
}
|
||||
|
||||
InventoryOperation operation = new InventoryOperation();
|
||||
operation.setId(IdWorker.getId());
|
||||
operation.setCustomerId(customerId);
|
||||
@@ -430,6 +442,16 @@ public class InventoryCommandService {
|
||||
normalizedKey + ":" + receipt.outboundPalletItemId() + ":" + target.getId(),
|
||||
"Exception return received with evidence " + request.evidenceFileIds().size());
|
||||
ledgerIds.add(ledger.getId());
|
||||
var owner = returnOwners.get(source.outboundPalletItemId());
|
||||
var stockReceipt = new com.baiyue.lastleg.inventory.entity.ReturnStockReceipt();
|
||||
stockReceipt.setId(IdWorker.getId()); stockReceipt.setCustomerId(customerId);
|
||||
stockReceipt.setReceiptNo("RSR" + stockReceipt.getId()); stockReceipt.setInventoryLedgerId(ledger.getId());
|
||||
stockReceipt.setExceptionOrderId(owner.exceptionOrderId()); stockReceipt.setOrderId(owner.orderId());
|
||||
stockReceipt.setInboundOrderId(owner.inboundOrderId()); stockReceipt.setSourceOutboundNo(outboundNo);
|
||||
stockReceipt.setSourceOutboundPalletItemId(source.outboundPalletItemId()); stockReceipt.setSourceInventoryPositionId(source.inventoryPositionId());
|
||||
stockReceipt.setInventoryBalanceId(balance.getId()); stockReceipt.setInventoryPositionId(target.getId());
|
||||
stockReceipt.setReceivedPackages(receipt.receivedPackages()); stockReceipt.setReceivedAt(ledger.getOccurredAt());
|
||||
stockReceipt.setCreatedAt(ledger.getOccurredAt()); returnReceipts.insert(stockReceipt);
|
||||
restoredPackages += receipt.receivedPackages();
|
||||
}
|
||||
long beforePackages = balanceBefore.values().stream().mapToLong(Long::longValue).sum();
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baiyue.lastleg.inventory.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/** An immutable receipt from a real return ledger; it is not another customer order or initial inbound receipt. */
|
||||
@Data
|
||||
@TableName("ll_return_stock_receipt")
|
||||
public class ReturnStockReceipt {
|
||||
@TableId private Long id;
|
||||
private String customerId;
|
||||
private String receiptNo;
|
||||
private Long inventoryLedgerId;
|
||||
private Long exceptionOrderId;
|
||||
private Long orderId;
|
||||
private Long inboundOrderId;
|
||||
private String sourceOutboundNo;
|
||||
private Long sourceOutboundPalletItemId;
|
||||
private Long sourceInventoryPositionId;
|
||||
private Long inventoryBalanceId;
|
||||
private Long inventoryPositionId;
|
||||
private Long receivedPackages;
|
||||
private LocalDateTime receivedAt;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baiyue.lastleg.inventory.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baiyue.lastleg.inventory.entity.ReturnStockReceipt;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ReturnStockReceiptMapper extends BaseMapper<ReturnStockReceipt> {
|
||||
@Select("SELECT id FROM ll_order WHERE customer_id=#{customerId} AND id=#{id} FOR UPDATE")
|
||||
Long lockOrder(@Param("customerId") String customerId, @Param("id") Long id);
|
||||
record ReturnOwner(Long exceptionOrderId, Long orderId, Long inboundOrderId) { }
|
||||
@Select("SELECT e.id AS exception_order_id,e.last_mile_order_id AS order_id,e.inbound_order_id " +
|
||||
"FROM ll_exception_order e JOIN ll_order o ON o.customer_id=e.customer_id AND o.id=e.last_mile_order_id " +
|
||||
"JOIN ll_exception_return_item i ON i.customer_id=e.customer_id AND i.exception_order_id=e.id " +
|
||||
"WHERE e.customer_id=#{customerId} AND e.exception_no=#{exceptionNo} AND e.outbound_no=#{outboundNo} " +
|
||||
"AND e.exception_type='RETURN' AND e.return_direction='OVERSEAS_WAREHOUSE' AND e.status='PROCESSING' " +
|
||||
"AND i.outbound_pallet_item_id=#{itemId} AND i.inventory_position_id=#{positionId}")
|
||||
ReturnOwner owner(@Param("customerId") String customerId, @Param("exceptionNo") String exceptionNo,
|
||||
@Param("outboundNo") String outboundNo, @Param("itemId") Long itemId, @Param("positionId") Long positionId);
|
||||
|
||||
@Select("SELECT r.* FROM ll_return_stock_receipt r JOIN ll_inventory_position p ON p.id=#{positionId} " +
|
||||
"AND p.customer_id=r.customer_id AND p.balance_id=r.inventory_balance_id " +
|
||||
"WHERE r.customer_id=#{customerId} AND r.received_packages > (SELECT COALESCE(SUM(a.packages),0) " +
|
||||
"FROM ll_dispatch_pda_pick_order a WHERE a.customer_id=r.customer_id AND a.return_receipt_id=r.id) " +
|
||||
"ORDER BY r.received_at,r.id")
|
||||
List<ReturnStockReceipt> available(@Param("customerId") String customerId, @Param("positionId") Long positionId);
|
||||
|
||||
@Select("SELECT * FROM ll_return_stock_receipt WHERE customer_id=#{customerId} AND id=#{id} FOR UPDATE")
|
||||
ReturnStockReceipt lock(@Param("customerId") String customerId, @Param("id") Long id);
|
||||
|
||||
@Select("SELECT COALESCE(SUM(packages),0) FROM ll_dispatch_pda_pick_order WHERE customer_id=#{customerId} AND return_receipt_id=#{id}")
|
||||
long picked(@Param("customerId") String customerId, @Param("id") Long id);
|
||||
}
|
||||
Reference in New Issue
Block a user