fix(lastleg): preserve return relabel delivery metadata and measurements

This commit is contained in:
2026-10-15 21:40:37 +08:00
parent 607aaf74dc
commit b8739eebf0
10 changed files with 224 additions and 28 deletions
@@ -30,6 +30,18 @@ class DeliverySchemaContractTest {
}
}
@Test
void directOutboundSnapshotsKeepUnknownVolumeNullableAcrossBothBaselines() throws Exception {
for (Path path : java.util.List.of(Path.of("src/main/resources/db/lastleg.sql"), Path.of("../deploy/sql/海外区域统一增量-MySQL8.sql"))) {
String sql = Files.readString(path, StandardCharsets.UTF_8);
for (String table : java.util.List.of("ll_outbound_order", "ll_outbound_pallet_item", "ll_delivery_order")) {
var matcher = java.util.regex.Pattern.compile("(?is)CREATE TABLE(?: IF NOT EXISTS)? " + table + " \\(.*?;").matcher(sql);
assertTrue(matcher.find(), table);
String column = "ll_delivery_order".equals(table) ? "total_volume_cbm" : "volume_cbm";
assertTrue(java.util.regex.Pattern.compile("(?i)" + column + " DECIMAL\\(18,4\\) NULL COMMENT").matcher(matcher.group()).find(), table + " keeps unknown volume NULL");
}
}
}
@Test
void baselineDefinesOutboundPalletsAndDeliveryContracts() throws Exception {
String schema = Files.readString(Path.of("src/main/resources/db/lastleg.sql"), StandardCharsets.UTF_8)
.toLowerCase();
@@ -311,6 +311,38 @@ class DeliveryTransferServiceTest {
assertEquals(1, detail.skus().get(0).packageCount());
}
@org.junit.jupiter.params.ParameterizedTest
@org.junit.jupiter.params.provider.ValueSource(booleans = {true, false})
void relabelDeliveryDetailCarriesFrozenPhysicalMeasurementOnFirstSkuOnly(boolean measured) {
DeliveryOrder delivery = new DeliveryOrder(); delivery.setId(501L); delivery.setCustomerId("TENANT-A");
delivery.setDeliveryNo("DL-501"); delivery.setOutboundOrderId(301L); delivery.setOutboundNo("OUT-301");
delivery.setOverseasWarehouseId("WH-1"); delivery.setCustomerName("客户快照"); delivery.setOverseasWarehouseName("仓库快照");
delivery.setDeliveryGroupKey("RETURN_RELABEL:ABE4"); delivery.setDestinationWarehouseCode("ABE4");
delivery.setStatus("WAIT_DELIVERY");
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "relabel-1"); outbound.setOutboundType("RELABEL_OUTBOUND");
OutboundPalletItem item = new OutboundPalletItem(); item.setCartonMarks("RC-1"); item.setDestinationWarehouseCode("ABE4");
if (measured) { item.setGrossWeightKg(BigDecimal.ONE); item.setVolumeCbm(new BigDecimal("0.008")); }
ReturnInventoryCarton carton = returnCarton("RC-1", null); carton.setId(901L);
carton.setWeight(new BigDecimal("99")); // Reading the current carton must not replace the frozen outbound measurement.
var first = new ReturnInventoryCartonItem(); first.setSkuCode("SKU-A"); first.setQuantity(3L);
var second = new ReturnInventoryCartonItem(); second.setSkuCode("SKU-B"); second.setQuantity(2L);
when(deliveryOrders.findByNo("TENANT-A", "DL-501")).thenReturn(delivery);
when(outboundOrders.selectById(301L)).thenReturn(outbound);
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(item));
when(returnCartons.findCustomerMark("TENANT-A", "RC-1")).thenReturn(carton);
when(returnCartonItems.listCarton(901L)).thenReturn(List.of(first, second));
var detail = service.deliveryDetail("TENANT-A", "DL-501");
assertEquals("客户快照", detail.order().customerName()); assertEquals("仓库快照", detail.order().overseasWarehouseName());
assertEquals(2, detail.skus().size()); assertEquals(1, detail.skus().stream().mapToInt(row -> row.packageCount()).sum());
assertEquals(5L, detail.skus().stream().mapToLong(row -> row.productQuantity()).sum());
assertEquals(measured ? BigDecimal.ONE : null, detail.skus().get(0).weightKg());
assertEquals(measured ? new BigDecimal("0.008") : null, detail.skus().get(0).volumeCbm());
assertEquals(0, detail.skus().get(1).packageCount());
assertNull(detail.skus().get(1).weightKg()); assertNull(detail.skus().get(1).volumeCbm());
}
@Test
void returnCartonPickDelegatesInventoryDeductionOnce() {
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "return-1");