fix: materialize container pallet plans
This commit is contained in:
+66
@@ -290,6 +290,72 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
.map(ContainerInboundPlanConversionCoordinator.PreparedItem::palletCode).toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void standardFbaPreviewMaySupplementButNeverReduceHeadLegPalletCodes() {
|
||||
ConvertContainerInboundPlanRequest request = request();
|
||||
var order = new ContainerInboundPlanPreviewResponse.Order(
|
||||
"100", "Customer 100", "11", "LM-11", "RK-FBA", "FIRST_LEG", "FBA",
|
||||
null, "ACY2", "Amazon ACY2", "ACY2", 20, new BigDecimal("5.8000"), 3,
|
||||
null, null, null, 0, "READY", List.of());
|
||||
var preview = new ContainerInboundPlanPreviewResponse(BOOKING_ID, "MSCU6639870", "31", "US-LAX-01",
|
||||
"Los Angeles", 7L, SNAPSHOT_HASH, 1, 1, 0, 1, 3, 0, 3, 0, true,
|
||||
List.of(new ContainerInboundPlanPreviewResponse.Group("FBA", null, "ACY2", "Amazon ACY2",
|
||||
1, 1, 3, 0, 3, 0, List.of(order))));
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class))).thenReturn("IP-ACY2");
|
||||
when(plans.sourcePalletNos("100", 11L, "FIRST_LEG")).thenReturn(List.of(
|
||||
"MSCU6639870-101-001", "MSCU6639870-101-002"));
|
||||
|
||||
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
|
||||
1L, 2L, BOOKING_ID, "FIRST-KEY", request,
|
||||
ReflectionTestUtils.invokeMethod(coordinator, "hash",
|
||||
List.of(BOOKING_ID, request.snapshotVersion(), request.snapshotHash())));
|
||||
ContainerInboundPlanConversionCoordinator.Preparation preparation;
|
||||
try {
|
||||
preparation = objectMapper.readValue(command.getPreparationJson(),
|
||||
ContainerInboundPlanConversionCoordinator.Preparation.class);
|
||||
} catch (Exception exception) {
|
||||
throw new AssertionError(exception);
|
||||
}
|
||||
|
||||
assertEquals(List.of("MSCU6639870-101-001", "MSCU6639870-101-002", "MSCU6639870-101-003"),
|
||||
preparation.items().stream().map(ContainerInboundPlanConversionCoordinator.PreparedItem::palletCode).toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void existingManualPlanIsPreparedForWarehouseMaterialization() {
|
||||
ConvertContainerInboundPlanRequest request = request();
|
||||
var order = new ContainerInboundPlanPreviewResponse.Order(
|
||||
"100", "Customer 100", "11", "LM-11", "RK-FBA", "FIRST_LEG", "FBA",
|
||||
null, "ACY2", "Amazon ACY2", "ACY2", 20, new BigDecimal("5.8000"), 3,
|
||||
3, "IP-MANUAL", "PENDING_ASSIGNMENT", 1, "RESOURCE_PENDING", List.of());
|
||||
var preview = new ContainerInboundPlanPreviewResponse(BOOKING_ID, "MSCU6639870", "31", "US-LAX-01",
|
||||
"Los Angeles", 7L, SNAPSHOT_HASH, 1, 1, 0, 1, 3, 3, 3, 3, true,
|
||||
List.of(new ContainerInboundPlanPreviewResponse.Group("FBA", null, "ACY2", "Amazon ACY2",
|
||||
1, 1, 3, 3, 3, 3, List.of(order))));
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(plans.sourcePalletNos("100", 11L, "FIRST_LEG")).thenReturn(List.of(
|
||||
"MSCU6639870-101-001", "MSCU6639870-101-002"));
|
||||
when(plans.existingPlanIdentity("100", 11L))
|
||||
.thenReturn(new InboundPlanService.PlanIdentity(21L, "IP-MANUAL", 3));
|
||||
|
||||
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
|
||||
1L, 2L, BOOKING_ID, "FIRST-KEY", request,
|
||||
ReflectionTestUtils.invokeMethod(coordinator, "hash",
|
||||
List.of(BOOKING_ID, request.snapshotVersion(), request.snapshotHash())));
|
||||
ContainerInboundPlanConversionCoordinator.Preparation preparation;
|
||||
try {
|
||||
preparation = objectMapper.readValue(command.getPreparationJson(),
|
||||
ContainerInboundPlanConversionCoordinator.Preparation.class);
|
||||
} catch (Exception exception) {
|
||||
throw new AssertionError(exception);
|
||||
}
|
||||
|
||||
assertEquals(21L, preparation.items().get(0).planId());
|
||||
assertEquals("IP-MANUAL", preparation.items().get(0).planNo());
|
||||
verify(numbers, never()).next(any(String.class), any(String.class), any(Long.class));
|
||||
}
|
||||
|
||||
private ContainerInboundPlanPreviewResponse.Order previewOrder(String customerId, String orderId,
|
||||
String inboundCode, String destinationCode,
|
||||
String fbaWarehouseCode) {
|
||||
|
||||
+2
-2
@@ -74,7 +74,7 @@ class ContainerInboundPlanPreviewTest {
|
||||
new InboundPlanOrderMapper.ContainerPreviewOrderRow("100", 1L, "LM-1", "FO-1", "测试客户",
|
||||
"FIRST_LEG", "OVERSEAS", "IN-1", "PENDING_ASSIGNMENT", null, null, 0, 0,
|
||||
BigDecimal.ZERO, null, null, null, null, null, null, null, 0, false, 1,
|
||||
null, null, null)));
|
||||
null, null, null, null)));
|
||||
|
||||
var result = service.previewContainer("BOOKING-NULL");
|
||||
|
||||
@@ -113,6 +113,6 @@ class ContainerInboundPlanPreviewTest {
|
||||
"FBA".equals(destinationType) || destinationCode == null ? null : "WH-" + id,
|
||||
"FBA".equals(destinationType) ? null : destinationCode, destinationName,
|
||||
"FBA".equals(destinationType) || destinationCode == null ? 0 : 1, false, version, planNo,
|
||||
planNo == null ? null : "PENDING_ASSIGNMENT", plannedPallets);
|
||||
planNo == null ? null : "PENDING_ASSIGNMENT", plannedPallets, plannedPallets);
|
||||
}
|
||||
}
|
||||
|
||||
+47
@@ -164,6 +164,53 @@ class InboundPlanServiceTest {
|
||||
verify(orderMapper).lockContainerWarehouseFacts("100", 2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void manualPlanMayExceedButCannotUndercutPreviewPalletCount() {
|
||||
SourceOrderSnapshot source = new SourceOrderSnapshot(2L, "100", "MSCU6639870", "RK-2",
|
||||
"PENDING_ASSIGNMENT", null, new BigDecimal("5.8000"), 58, 2,
|
||||
"193000000000200003", "US-LAX-01", "洛杉矶仓", "ACY2",
|
||||
null, null, "Amazon ACY2", 0, 0, false, 0);
|
||||
when(orderMapper.lockOrder("100", 2L)).thenReturn(List.of(source));
|
||||
ResponseStatusException error = assertThrows(ResponseStatusException.class, () -> service.convertManual(
|
||||
new ManualInboundPlanRequest("100", 2L, 0, LocalDate.of(2026, 9, 15),
|
||||
2, "WOOD", false, false, false, null), "manual-below-preview", "900"));
|
||||
|
||||
assertEquals(400, error.getStatusCode().value());
|
||||
verify(planMapper, never()).insert(any(InboundPlan.class));
|
||||
verify(commandMapper, never()).insert(any(com.baiyue.lastleg.entity.LastlegOrderCommandRecord.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerConversionBindsRealWarehousePalletsBackToExistingManualPlan() {
|
||||
InboundPlan plan = existingPlan("100", 2L, "IP-MANUAL");
|
||||
plan.setCreationMode("MANUAL");
|
||||
plan.setPalletCount(2);
|
||||
InboundPlanPallet first = new InboundPlanPallet();
|
||||
first.setId(301L); first.setCustomerId("100"); first.setPlanId(plan.getId()); first.setSequenceNo(1);
|
||||
InboundPlanPallet second = new InboundPlanPallet();
|
||||
second.setId(302L); second.setCustomerId("100"); second.setPlanId(plan.getId()); second.setSequenceNo(2);
|
||||
when(palletMapper.selectList(any())).thenReturn(List.of(first, second));
|
||||
var firstReservation = new WarehouseResourceGateway.PalletBatchItem(100L, "CIP:1:1", "IP-MANUAL",
|
||||
1, 401L, "MSCU6639870-101-001", 501L, 601L, "RESERVED");
|
||||
var secondReservation = new WarehouseResourceGateway.PalletBatchItem(100L, "CIP:1:2", "IP-MANUAL",
|
||||
2, 402L, "MSCU6639870-101-002", 502L, 602L, "RESERVED");
|
||||
var prepared = new InboundPlanService.PreparedPlan(plan.getId(), plan.getPlanNo(), "100", 2L, List.of(
|
||||
new InboundPlanService.PreparedPallet(1, "CIP:1:1", firstReservation),
|
||||
new InboundPlanService.PreparedPallet(2, "CIP:1:2", secondReservation)));
|
||||
|
||||
ReflectionTestUtils.invokeMethod(service, "materializeExistingPlan", plan,
|
||||
new InboundPlanOrderMapper.ContainerOrderRef("100", 2L, "INBOUND_PLANNED", "MSCU6639870", "FIRST_LEG"),
|
||||
prepared);
|
||||
|
||||
assertEquals("MSCU6639870-101-001", first.getPalletNo());
|
||||
assertEquals("MSCU6639870-101-001", first.getSourcePalletNo());
|
||||
assertEquals(401L, first.getWarehousePalletId());
|
||||
assertEquals("RESERVED", first.getAssignmentStatus());
|
||||
assertEquals(402L, second.getWarehousePalletId());
|
||||
verify(palletMapper, times(2)).updateById(any(InboundPlanPallet.class));
|
||||
verify(planMapper).updateById(plan);
|
||||
}
|
||||
|
||||
@Test
|
||||
void manuallyCreatesPlanWhenStableWarehouseIdExistsWithoutDisplaySnapshots() {
|
||||
SourceOrderSnapshot source = new SourceOrderSnapshot(2L, "100", "MSCU6639870", "RK-2",
|
||||
|
||||
Reference in New Issue
Block a user