From c07131b26fc102a70e9a36e245eadbbeee6e6c5f Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Tue, 13 Oct 2026 17:42:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=B4=E6=A0=87=E7=94=B3=E8=AF=B7=EF=BC=8C?= =?UTF-8?q?=E4=BB=93=E5=82=A8=E8=BD=AC=E8=BF=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lastleg/mapper/LastlegOrderMapper.java | 2 +- .../lastleg/relabel/dto/RelabelResponses.java | 2 +- .../service/RelabelApplicationService.java | 4 +- .../service/ReturnReceiptService.java | 2 +- .../RelabelApplicationServiceTest.java | 6 ++- .../service/ReturnReceiptServiceTest.java | 19 ++++++++++ .../service/LastlegOrderReturnVolumeTest.java | 37 +++++++++++++++++++ 7 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderReturnVolumeTest.java diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/mapper/LastlegOrderMapper.java b/lastleg-service/src/main/java/com/baiyue/lastleg/mapper/LastlegOrderMapper.java index c0d87a9c8..519aee690 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/mapper/LastlegOrderMapper.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/mapper/LastlegOrderMapper.java @@ -84,7 +84,7 @@ public interface LastlegOrderMapper extends BaseMapper { "ORDER BY r.signed_at DESC,r.id DESC) AS measurementNo " + "FROM ll_return_receipt r JOIN ll_return_order o ON o.id=r.return_order_id AND o.customer_id=r.customer_id " + "WHERE o.lastleg_order_id IN #{id} " + - "AND r.unit_type IN ('PALLET','BOX') AND r.length IS NOT NULL AND r.width IS NOT NULL AND r.height IS NOT NULL" + + "AND r.unit_type IN ('PALLET','BOX','PARCEL') AND r.length IS NOT NULL AND r.width IS NOT NULL AND r.height IS NOT NULL" + ") m WHERE m.measurementNo=1 GROUP BY m.orderId") List findReturnVolumes(@Param("orderIds") List orderIds); diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelResponses.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelResponses.java index 462e0ce41..de4e8e220 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelResponses.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelResponses.java @@ -20,7 +20,7 @@ public final class RelabelResponses { String fulfillmentStatus, String outboundOrderNo, LocalDateTime customerConfirmedAt, String reviewChannel, String reviewRemark, LocalDateTime createdAt, LocalDateTime reviewedAt, LocalDateTime relabelCompletedAt, LocalDateTime outboundAt, - String productNameZh, String labelRequirement) {} + String productNameZh, String labelRequirement, List operationTypes) {} public record Milestones(LocalDateTime reviewedAt, LocalDateTime relabelCompletedAt, LocalDateTime outboundAt) {} public record Item(Long id, String skuCode, String productImageFileId, String productImageFileName, diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java index 8ff831431..56c9825dc 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java @@ -1226,7 +1226,9 @@ public class RelabelApplicationService implements WalletResultHandler { detailItems.stream().map(RelabelItem::getProductNameZh).filter(StringUtils::hasText) .map(String::trim).distinct().collect(Collectors.joining("、")), detailItems.stream().map(RelabelItem::getLabelRequirement).filter(StringUtils::hasText) - .map(String::trim).distinct().collect(Collectors.joining(";"))); + .map(String::trim).distinct().collect(Collectors.joining(";")), + detailItems.stream().map(RelabelItem::getOperationType).filter(StringUtils::hasText) + .map(String::trim).distinct().toList()); } @Override public boolean supports(String businessType) { return "RELABEL_ORDER".equals(businessType); } diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptService.java index fe3dd0832..5c614af16 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptService.java @@ -768,7 +768,7 @@ public class ReturnReceiptService { tail.setPackageCount(actualBoxes); tail.setReceivedPackageCount(actualBoxes); tail.setProductQuantity(actualUnits); tail.setPalletCount(palletCodes.size()); for (ReturnReceipt signed : signedReceipts) { - if (signed.getLength() == null || signed.getWidth() == null || signed.getHeight() == null || "PARCEL".equals(signed.getUnitType())) continue; + if (signed.getLength() == null || signed.getWidth() == null || signed.getHeight() == null) continue; String code = text(signed.getUnitCode()) == null ? signed.getReceiptNo() : signed.getUnitCode(); measuredUnits.putIfAbsent(signed.getUnitType() + ":" + code, signed); } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java index 2dea60a16..1f762d90b 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java @@ -75,10 +75,11 @@ class RelabelApplicationServiceTest { when(applications.findMilestones("10001", 42L)) .thenReturn(new RelabelResponses.Milestones(reviewed, completed, outbound)); var first = new RelabelItem(); first.setProductNameZh(" 商品甲 "); first.setLabelRequirement(" 贴标要求111 "); - first.setSkuCode("SKU-FIRST"); + first.setSkuCode("SKU-FIRST"); first.setOperationType("SKU_LABEL"); first.setSkuRelabelItemsJson("[{\"skuCode\":\"SKU-FIRST\",\"newSkuCode\":\"NEW-FIRST\",\"quantity\":10},{\"skuCode\":\"SKU-SECOND\",\"newSkuCode\":\"NEW-SECOND\",\"quantity\":5}]"); var second = new RelabelItem(); second.setProductNameZh("商品乙"); second.setLabelRequirement("贴标要求111"); - var empty = new RelabelItem(); empty.setProductNameZh(" "); + second.setOperationType("CARTON_LABEL"); + var empty = new RelabelItem(); empty.setProductNameZh(" "); empty.setOperationType("SKU_LABEL"); RelabelResponses.Summary result = ReflectionTestUtils.invokeMethod(service, "summary", application, List.of(first, second, empty)); assertNotNull(result); assertEquals(reviewed, result.reviewedAt()); @@ -87,6 +88,7 @@ class RelabelApplicationServiceTest { assertEquals("商品甲、商品乙", result.productNameZh()); assertEquals("贴标要求111", result.labelRequirement()); assertEquals("SKU-FIRST,SKU-SECOND", result.skuCodes()); + assertEquals(List.of("SKU_LABEL", "CARTON_LABEL"), result.operationTypes()); assertEquals(3, result.itemCount()); } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptServiceTest.java index c77c1f9fc..55c7a3b05 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/returnreceipt/service/ReturnReceiptServiceTest.java @@ -82,6 +82,25 @@ class ReturnReceiptServiceTest { verify(details, times(1)).insert(any(com.baiyue.lastleg.entity.LastlegOrderDetail.class)); verify(details, times(1)).updateById(any(com.baiyue.lastleg.entity.LastlegOrderDetail.class)); } + @Test void countedParcelsContributeVolumeOncePerPhysicalPackage() { + ReturnOrder order = new ReturnOrder(); order.setId(1L); order.setCustomerId("C1"); order.setLastlegOrderId(9L); + ReturnOrderItem sku = new ReturnOrderItem(); sku.setSkuCode("SKU1"); + ReturnReceipt first = measuredReceipt(2L, "PK-A", "50", "40", "40"); first.setReturnOrderId(1L); first.setUnitType("PARCEL"); + ReturnReceipt second = measuredReceipt(3L, "PK-B", "60", "50", "50"); second.setUnitType("PARCEL"); + ReturnReceipt earlier = measuredReceipt(4L, "PK-A", "40", "40", "40"); earlier.setUnitType("PARCEL"); + var counted = new com.baiyue.lastleg.returnreceipt.entity.ReturnReceiptItem(); counted.setSkuCode("SKU1"); counted.setReceivedQuantity(24L); + LastlegOrder tail = new LastlegOrder(); tail.setId(9L); tail.setCustomerId("C1"); + when(orders.selectById(1L)).thenReturn(order); when(orderItems.listOrder(1L)).thenReturn(List.of(sku)); + when(lastlegOrders.selectById(9L)).thenReturn(tail); when(receipts.listOrder(1L)).thenReturn(List.of(second, first, earlier)); + when(receiptItems.listReceipt(2L)).thenReturn(List.of(counted)); + + service.refreshCountedTailCargo(first); + + assertThat(tail.getVolumeCbm()).isEqualByComparingTo("0.23"); + assertEquals(0, tail.getPackageCount()); + assertEquals(0, tail.getPalletCount()); + verify(lastlegOrders).updateById(tail); + } @Mock ReturnOrderMapper orders; @Mock ReturnOrderItemMapper orderItems; @Mock ReturnReceiptMapper receipts; diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderReturnVolumeTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderReturnVolumeTest.java new file mode 100644 index 000000000..ed78ca1cb --- /dev/null +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderReturnVolumeTest.java @@ -0,0 +1,37 @@ +package com.baiyue.lastleg.service; + +import com.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baiyue.lastleg.mapper.LastlegOrderMapper; +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.junit.jupiter.api.Test; +import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; + +class LastlegOrderReturnVolumeTest { + @Test void historicalParcelsAreIncludedWithLatestCarrierMeasurementsAndCustomerIsolation() throws Exception { + var config = new MybatisConfiguration(); + config.setEnvironment(new Environment("test", new JdbcTransactionFactory(), + new UnpooledDataSource("org.h2.Driver", "jdbc:h2:mem:return-volume;MODE=MySQL", "sa", ""))); + config.addMapper(LastlegOrderMapper.class); + try (var session = new SqlSessionFactoryBuilder().build(config).openSession()) { + var sql = session.getConnection().createStatement(); + sql.execute("CREATE TABLE ll_return_order (id BIGINT, customer_id VARCHAR, lastleg_order_id BIGINT)"); + sql.execute("CREATE TABLE ll_return_receipt (id BIGINT, return_order_id BIGINT, customer_id VARCHAR, unit_type VARCHAR, unit_code VARCHAR, receipt_no VARCHAR, signed_at TIMESTAMP, length DECIMAL(12,3), width DECIMAL(12,3), height DECIMAL(12,3))"); + sql.execute("INSERT INTO ll_return_order VALUES (1,'A',9),(2,'B',10)"); + sql.execute("INSERT INTO ll_return_receipt VALUES " + + "(1,1,'A','PARCEL','PK-A','RR-1','2026-10-13 10:00:00',40,40,40)," + + "(2,1,'A','PARCEL','PK-A','RR-2','2026-10-13 11:00:00',50,40,40)," + + "(3,1,'A','PARCEL','PK-B','RR-3','2026-10-13 11:00:00',60,50,50)," + + "(4,1,'B','PARCEL','PK-C','RR-4','2026-10-13 11:00:00',100,100,100)," + + "(5,2,'B','PARCEL','PK-D','RR-5','2026-10-13 11:00:00',100,100,100)," + + "(6,1,'A','PARCEL','PK-E','RR-6','2026-10-13 11:00:00',NULL,50,50)"); + var rows = session.getMapper(LastlegOrderMapper.class).findReturnVolumes(List.of(9L)); + assertThat(rows).hasSize(1); + assertThat(rows.get(0).orderId()).isEqualTo(9L); + assertThat(rows.get(0).volumeCbm()).isEqualByComparingTo("0.23"); + } + } +}