fix(lastleg): bind merged return inventory to reusable target pallet
This commit is contained in:
+9
@@ -58,6 +58,7 @@ public class ReturnInventoryService {
|
||||
@Resource private com.baiyue.lastleg.returnreceipt.mapper.ReturnReceiptMapper receiptMapper;
|
||||
@Resource private LastlegOrderMapper lastlegOrders;
|
||||
@Resource private LastlegOrderDetailMapper lastlegOrderDetails;
|
||||
@Resource private com.baiyue.lastleg.palletops.gateway.PalletPhysicalGateway physicalPallets;
|
||||
|
||||
@Transactional
|
||||
public ReturnInventoryCarton createReceiptCarton(ReturnOrder order, ReturnReceipt receipt,
|
||||
@@ -300,6 +301,14 @@ public class ReturnInventoryService {
|
||||
if (total <= 0) throw badRequest("至少填写一个大于 0 的 SKU 合箱数量");
|
||||
long targetId = IdWorker.getId();
|
||||
ReturnInventoryCarton target = new ReturnInventoryCarton();
|
||||
// Stable across transaction rollback/retry; a generated target ID would leak a new resource on every retry.
|
||||
String palletBusinessKey = "RETURN-MERGE:" + hash(List.of(identity.operatorKey(), key, requestHash));
|
||||
var pallet = physicalPallets.ensureRelabelPallet(identity.overseasWarehouseId(), palletBusinessKey);
|
||||
if (pallet == null || pallet.warehouseId() != identity.overseasWarehouseId()
|
||||
|| pallet.palletId() <= 0 || text(pallet.palletCode()) == null) {
|
||||
throw conflict("合箱目标托盘资源无效,请核对后重试");
|
||||
}
|
||||
target.setPalletCode(pallet.palletCode());
|
||||
target.setId(targetId); target.setCustomerId(customerId); target.setOverseasWarehouseId(sources.get(0).getOverseasWarehouseId());
|
||||
target.setCartonMark(numbers.next("RETURN_CARTON", target.getOverseasWarehouseId(), targetId)); target.setSourceBatchNo(String.join(",", consumedBatchNos)); target.setSourceReturnNo(String.join(",", consumedReturnNos)); target.setStatus(AVAILABLE);
|
||||
target.setSkuTypes(requested.size()); target.setTotalQuantity(total); target.setLength(request.length()); target.setWidth(request.width()); target.setHeight(request.height()); target.setWeight(request.weight()); target.setCreatedAt(now); target.setUpdatedAt(now); cartons.insert(target);
|
||||
|
||||
+11
-1
@@ -50,6 +50,7 @@ class ReturnInventoryServiceTest {
|
||||
@Mock LastlegOrderNoGenerator numbers;
|
||||
@Mock ReturnOrderMapper orders;
|
||||
@Mock ReturnReceiptMapper receipts;
|
||||
@Mock com.baiyue.lastleg.palletops.gateway.PalletPhysicalGateway physicalPallets;
|
||||
private ReturnInventoryService service;
|
||||
|
||||
@BeforeEach
|
||||
@@ -64,6 +65,7 @@ class ReturnInventoryServiceTest {
|
||||
ReflectionTestUtils.setField(service, "numbers", numbers);
|
||||
ReflectionTestUtils.setField(service, "orders", orders);
|
||||
ReflectionTestUtils.setField(service, "receiptMapper", receipts);
|
||||
ReflectionTestUtils.setField(service, "physicalPallets", physicalPallets);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -142,6 +144,8 @@ class ReturnInventoryServiceTest {
|
||||
when(cartons.lockMark("RC-SOURCE")).thenReturn(source);
|
||||
when(cartonItems.lockCarton(31L)).thenReturn(List.of(skuA, skuB));
|
||||
when(numbers.next(anyString(), anyString(), anyLong())).thenReturn("RC-MERGED");
|
||||
when(physicalPallets.ensureRelabelPallet(org.mockito.ArgumentMatchers.eq(42L), anyString()))
|
||||
.thenReturn(new com.baiyue.lastleg.palletops.gateway.PalletPhysicalGateway.PalletReference(91L, "PLT-MERGED", 42L, null, "EMPTY", null, 0));
|
||||
when(balances.adjustCartonQuantity(anyString(), anyString(), anyString(), anyLong())).thenReturn(1);
|
||||
|
||||
service.merge(new PdaWarehouseIdentity("operator-1", "操作员", 42L),
|
||||
@@ -158,6 +162,10 @@ class ReturnInventoryServiceTest {
|
||||
verify(cartons).insert(target.capture());
|
||||
assertThat(target.getValue().getSourceBatchNo()).isEqualTo("RB-1");
|
||||
assertThat(target.getValue().getSourceReturnNo()).isEqualTo("RT-1");
|
||||
assertThat(target.getValue().getPalletCode()).isEqualTo("PLT-MERGED");
|
||||
ArgumentCaptor<String> businessKey = ArgumentCaptor.forClass(String.class);
|
||||
verify(physicalPallets).ensureRelabelPallet(org.mockito.ArgumentMatchers.eq(42L), businessKey.capture());
|
||||
assertThat(businessKey.getValue()).matches("RETURN-MERGE:[0-9a-f]{64}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -190,6 +198,8 @@ class ReturnInventoryServiceTest {
|
||||
ReturnInventoryCarton locked = prepareConcurrentSource();
|
||||
when(cartonItems.lockCarton(31L)).thenReturn(List.of(item(41L, "SKU-A", 2L)));
|
||||
when(numbers.next(anyString(), anyString(), anyLong())).thenReturn("RC-TARGET");
|
||||
when(physicalPallets.ensureRelabelPallet(org.mockito.ArgumentMatchers.eq(42L), anyString()))
|
||||
.thenReturn(new com.baiyue.lastleg.palletops.gateway.PalletPhysicalGateway.PalletReference(92L, "PLT-TARGET", 42L, null, "EMPTY", null, 0));
|
||||
when(balances.adjustCartonQuantity(anyString(), anyString(), anyString(), anyLong())).thenReturn(1);
|
||||
service.merge(new PdaWarehouseIdentity("operator-2", "操作员2", 42L), mergeRequest(2));
|
||||
assertThat(locked.getTotalQuantity()).isZero();
|
||||
@@ -224,7 +234,7 @@ class ReturnInventoryServiceTest {
|
||||
verify(cartons, never()).insert(any(ReturnInventoryCarton.class));
|
||||
verify(cartonItems, never()).insert(any(ReturnInventoryCartonItem.class));
|
||||
verify(operations, never()).updateById(any(ReturnInventoryOperation.class));
|
||||
verifyNoInteractions(orders, receipts, balances, numbers);
|
||||
verifyNoInteractions(orders, receipts, balances, numbers, physicalPallets);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user