fix(lastleg): accept cabinet pallet identities

This commit is contained in:
2026-09-18 14:14:10 +08:00
parent 2d902308b5
commit 895d0f7639
9 changed files with 49 additions and 15 deletions
@@ -255,7 +255,7 @@ public class ContainerInboundPlanConversionCoordinator {
String fbaCode = trimToNull(order.fbaWarehouseCode());
if (fbaCode != null && !"ONE_CLICK_DROPSHIP".equals(order.orderType())) {
for (String palletCode : sourcePalletNos) {
PalletCodeParts parts = palletCodeParts(preview.containerNo(), palletCode);
PalletCodeParts parts = palletCodeParts(palletCode);
String previousPrefix = prefixByFba.putIfAbsent(fbaCode, parts.prefix());
if (previousPrefix != null && !previousPrefix.equals(parts.prefix())) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "同一 FBA 仓的头程托盘码内部编码不一致");
@@ -487,17 +487,16 @@ public class ContainerInboundPlanConversionCoordinator {
int localSequenceNo, int globalSequenceNo, String businessKey,
String fbaWarehouseCode, String palletCode) { }
private static PalletCodeParts palletCodeParts(String containerNo, String palletCode) {
String stableContainerNo = trimToNull(containerNo);
private static PalletCodeParts palletCodeParts(String palletCode) {
String stablePalletCode = trimToNull(palletCode);
if (stableContainerNo == null || stablePalletCode == null) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "集装箱号或头程托盘码缺失");
if (stablePalletCode == null) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "头程托盘码缺失");
}
Matcher matcher = Pattern.compile("^(" + Pattern.quote(stableContainerNo) + "-.+)-(\\d{3})$")
Matcher matcher = Pattern.compile("^(D\\d{4,}-.+)-(\\d{3})$")
.matcher(stablePalletCode);
if (!matcher.matches()) {
throw new ResponseStatusException(HttpStatus.CONFLICT,
"头程托盘码不符合‘集装箱号-FBA内部编码-下标’规则");
"头程托盘码不符合‘柜次号-FBA内部编码-下标’规则");
}
return new PalletCodeParts(matcher.group(1), Integer.parseInt(matcher.group(2)));
}
@@ -345,7 +345,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
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"));
"D0004-101-001", "D0004-101-002"));
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
1L, 2L, BOOKING_ID, "FIRST-KEY", request,
@@ -359,7 +359,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
throw new AssertionError(exception);
}
assertEquals(List.of("MSCU6639870-101-001", "MSCU6639870-101-002", "MSCU6639870-101-003"),
assertEquals(List.of("D0004-101-001", "D0004-101-002", "D0004-101-003"),
preparation.items().stream().map(ContainerInboundPlanConversionCoordinator.PreparedItem::palletCode).toList());
}
@@ -376,7 +376,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
1, 1, 3, 2, 1, 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"));
"D10000-101-001", "D10000-101-002"));
when(plans.existingPlanIdentity("100", 11L))
.thenReturn(new InboundPlanService.PlanIdentity(21L, "IP-MANUAL", 3));
@@ -434,7 +434,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
private InboundPlanResponse plan(String planNo, List<InboundPlanResponse.Pallet> pallets) {
return new InboundPlanResponse(21L, planNo, "100", 11L, "FL-WH-1", "验收客户", "ONE_CLICK_DROPSHIP",
"MSCU6639870", "US-LAX-01",
"Los Angeles", "PENDING_ASSIGNMENT", 1, 1, BigDecimal.ONE, 10, 0,
"Los Angeles", "PENDING_ASSIGNMENT", 1, 1, BigDecimal.TEN, new BigDecimal("8"), BigDecimal.ONE, 10, 0,
List.of(), pallets, List.of(), 1, LocalDate.of(2026, 9, 10), "WOOD", false,
false, false, "MANUAL", "自动生成", null, null);
}