feat: freeze and propagate first-leg pallet labels

This commit is contained in:
2026-09-09 17:27:00 +08:00
parent 83e95d764e
commit de1f7e8ddd
24 changed files with 560 additions and 21 deletions
@@ -3,6 +3,7 @@ package com.baiyue.lastleg.inboundplan.pda.gateway;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestClient;
@@ -98,6 +99,23 @@ class HttpWarehouseResourceGatewayTest {
server.verify();
}
@Test
void resolveReservedFallsBackToConfirmedPhysicalBindingForEarlierPlanDisplayCode() {
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/IP-ACY2-20260909-166786-P001"))
.andRespond(withStatus(HttpStatus.NOT_FOUND));
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/id/31"))
.andRespond(withSuccess("""
{"code":"200","data":{"palletId":31,"palletCode":"PLT-US-LAX-01-31",
"warehouseId":21,"locationId":41,"status":"OCCUPIED","version":3,
"reservable":false,"reservationBlockReason":"PALLET_NOT_IDLE"}}
""", MediaType.APPLICATION_JSON));
var result = gateway.resolveReservedPallet("IP-ACY2-20260909-166786-P001", "11", 21L, 31L, 41L, 51L);
assertThat(result.palletId()).isEqualTo(31L);
server.verify();
}
@Test
void resolveReservedRejectsDifferentPhysicalBinding() {
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/PAL-RESERVED"))
@@ -203,7 +221,7 @@ class HttpWarehouseResourceGatewayTest {
var result = gateway.ensurePalletBatch(new WarehouseResourceGateway.PalletBatchEnsure(31L, "BATCH-1",
List.of(new WarehouseResourceGateway.PalletBatchItemRequest(
100L, "CIP:1:1", "IP-21", 1, "STANDARD", "ONT8"))));
100L, "CIP:1:1", "IP-21", 1, "STANDARD", "ONT8", "CONT-ONT8-001"))));
assertThat(result.batchId()).isEqualTo(41L);
assertThat(result.items().get(0).resourceLockId()).isEqualTo(71L);
@@ -117,7 +117,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
@Test
void reservationMustMatchEveryStableItemIdentity() throws Exception {
var expected = new ContainerInboundPlanConversionCoordinator.PreparedItem(
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8");
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8", "CONT-ONT8-001");
var preparation = new ContainerInboundPlanConversionCoordinator.Preparation(31L, List.of(expected));
var response = new WarehouseResourceGateway.PalletBatchResponse(41L, "BATCH-1", "RESERVED", 1,
false, List.of(new WarehouseResourceGateway.PalletBatchItem(
@@ -239,6 +239,8 @@ class ContainerInboundPlanConversionCoordinatorTest {
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class)))
.thenReturn("IP-FBA", "IP-OVERSEAS");
when(plans.sourcePalletNos("100", 11L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-ABE3-001"));
when(plans.sourcePalletNos("200", 12L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-US-LAX-01-001"));
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
1L, 2L, BOOKING_ID, "FIRST-KEY", request,
@@ -291,7 +293,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
private void setOnePreparedItem(ContainerPlanConversionCommand command) throws Exception {
var item = new ContainerInboundPlanConversionCoordinator.PreparedItem(
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8");
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8", "CONT-ONT8-001");
command.setPreparationJson(objectMapper.writeValueAsString(
new ContainerInboundPlanConversionCoordinator.Preparation(31L, List.of(item))));
}