From 2f1bda8369732af8170d8bbaa57ac0f0fe22dcb5 Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Tue, 1 Sep 2026 09:57:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=BB=B6=E4=BB=A3=E5=8F=91=E6=8B=A3?= =?UTF-8?q?=E8=B4=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/sql/头程数据库统一增量-MySQL8.sql | 2 + .../firstleg/client/OrderCargoClient.java | 7 ++- .../entity/InboundCartonLabelEntity.java | 1 + .../InboundCartonLabelRepository.java | 10 ++++ .../service/InboundCartonLabelService.java | 12 ++++- ...ase2-carton-label-versioning-migration.sql | 1 + .../db/phase2-inbound-carton-label.sql | 1 + .../resources/db/phase2-inbound-schema.sql | 1 + .../service/DispatchPdaWorkflowService.java | 8 ++++ .../service/InboundPlanService.java | 12 +++++ .../LastlegOrderControllerTest.java | 2 +- .../MerchantLastlegOrderControllerTest.java | 2 +- .../DispatchPdaWorkflowServiceTest.java | 41 ++++++++++++++++ .../service/InboundPlanServiceTest.java | 48 +++++++++++++++++++ .../service/LastlegOrderServiceTest.java | 4 +- .../InternalOrderCargoController.java | 11 +++-- 16 files changed, 154 insertions(+), 9 deletions(-) diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index cdcd06ad8..1d7066d19 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -2792,6 +2792,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label ( inbound_detail_id BIGINT UNSIGNED NOT NULL COMMENT '订单货物明细ID,不建立跨库外键', cargo_item_no INT UNSIGNED NOT NULL COMMENT '订单货物明细序号快照', cargo_name VARCHAR(255) NULL COMMENT '货物名称快照', + sku_code VARCHAR(128) NULL COMMENT '箱唛绑定的SKU快照;二维码内容不变', detail_package_count INT UNSIGNED NOT NULL COMMENT '该订单货物明细箱数快照', inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照', box_code VARCHAR(80) NOT NULL COMMENT '固定二维码内容:入仓码#总箱数-箱下标', @@ -2829,6 +2830,7 @@ BEGIN END$$ DELIMITER ; CALL unified_carton_label_add_column('label_version', 'INT UNSIGNED NOT NULL DEFAULT 1 COMMENT ''内部兼容批次字段,固定为1且不进入箱码'' AFTER carton_index'); +CALL unified_carton_label_add_column('sku_code', 'VARCHAR(128) NULL COMMENT ''箱唛绑定的SKU快照;二维码内容不变'' AFTER cargo_name'); CALL unified_carton_label_add_column('batch_status', 'VARCHAR(16) NOT NULL DEFAULT ''ACTIVE'' COMMENT ''批次状态:ACTIVE有效、VOID已作废'' AFTER label_version'); CALL unified_carton_label_add_column('cargo_fingerprint', 'CHAR(64) NULL COMMENT ''影响标签字段的SHA-256指纹'' AFTER batch_status'); CALL unified_carton_label_add_column('voided_at', 'DATETIME(3) NULL COMMENT ''批次作废时间'' AFTER cargo_fingerprint'); diff --git a/firstleg/src/main/java/com/baiyue/firstleg/client/OrderCargoClient.java b/firstleg/src/main/java/com/baiyue/firstleg/client/OrderCargoClient.java index f3a5683a5..ac30d0298 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/client/OrderCargoClient.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/client/OrderCargoClient.java @@ -63,7 +63,12 @@ public interface OrderCargoClient { } record CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, - Integer packageCount, BigDecimal lengthCm, BigDecimal widthCm, + String skuNo, Integer packageCount, BigDecimal lengthCm, BigDecimal widthCm, BigDecimal heightCm) { + public CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, + Integer packageCount, BigDecimal lengthCm, BigDecimal widthCm, + BigDecimal heightCm) { + this(cargoId, orderId, itemNo, cargoName, null, packageCount, lengthCm, widthCm, heightCm); + } } } diff --git a/firstleg/src/main/java/com/baiyue/firstleg/entity/InboundCartonLabelEntity.java b/firstleg/src/main/java/com/baiyue/firstleg/entity/InboundCartonLabelEntity.java index bf0674011..6e9d7d252 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/entity/InboundCartonLabelEntity.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/entity/InboundCartonLabelEntity.java @@ -22,6 +22,7 @@ public class InboundCartonLabelEntity { private Long inboundDetailId; private Integer cargoItemNo; private String cargoName; + private String skuCode; private Integer detailPackageCount; private String inboundCode; private String boxCode; diff --git a/firstleg/src/main/java/com/baiyue/firstleg/repository/InboundCartonLabelRepository.java b/firstleg/src/main/java/com/baiyue/firstleg/repository/InboundCartonLabelRepository.java index 7cac757ec..1528937ca 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/repository/InboundCartonLabelRepository.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/repository/InboundCartonLabelRepository.java @@ -62,6 +62,16 @@ public class InboundCartonLabelRepository { .set(InboundCartonLabelEntity::getCargoFingerprint, fingerprint)); } + public void initializeLegacySku(long tenantId, long inboundId, long inboundDetailId, String skuCode) { + if (skuCode == null || skuCode.isBlank()) return; + labels.update(null, new LambdaUpdateWrapper() + .eq(InboundCartonLabelEntity::getTenantId, tenantId) + .eq(InboundCartonLabelEntity::getInboundId, inboundId) + .eq(InboundCartonLabelEntity::getInboundDetailId, inboundDetailId) + .isNull(InboundCartonLabelEntity::getSkuCode) + .set(InboundCartonLabelEntity::getSkuCode, skuCode.trim())); + } + public boolean initializeOriginalPackageCount(long tenantId, long inboundId, int packageCount) { return inbounds.update(null, new LambdaUpdateWrapper() .eq(InboundOrderEntity::getTenantId, tenantId) diff --git a/firstleg/src/main/java/com/baiyue/firstleg/service/InboundCartonLabelService.java b/firstleg/src/main/java/com/baiyue/firstleg/service/InboundCartonLabelService.java index 71794fc5b..a54d57828 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/service/InboundCartonLabelService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/service/InboundCartonLabelService.java @@ -50,6 +50,14 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver { throw new BizException(ResultCode.CONFLICT, "当前入库单状态不允许首次生成箱号"); } List cargoes = loadCargoes(inbound); + if ("ONE_CLICK_DROPSHIP".equals(inbound.getFulfillmentType()) + && cargoes.stream().anyMatch(cargo -> cargo.skuNo() == null || cargo.skuNo().isBlank())) { + throw new BizException(ResultCode.VALIDATION_FAILED, "一件代发货物明细缺少SKU,不能生成箱唛"); + } + existing.forEach(label -> cargoes.stream() + .filter(cargo -> java.util.Objects.equals(cargo.cargoId(), label.getInboundDetailId())) + .findFirst().ifPresent(cargo -> repository.initializeLegacySku(tenantId, inboundId, + label.getInboundDetailId(), cargo.skuNo()))); String fingerprint = fingerprint(cargoes); if (!existing.isEmpty()) { String existingFingerprint = consistent.get(0).getCargoFingerprint(); @@ -202,6 +210,7 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver { label.setInboundDetailId(cargo.cargoId()); label.setCargoItemNo(cargo.itemNo()); label.setCargoName(cargo.cargoName()); + label.setSkuCode(cargo.skuNo()); label.setDetailPackageCount(cargo.packageCount()); label.setInboundCode(inbound.getInboundCode()); label.setBoxCode(inbound.getInboundCode() + "#" + total + "-" + index); @@ -256,7 +265,8 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver { private String fingerprint(List cargoes) { String source = cargoes.stream().map(cargo -> String.join("|", String.valueOf(cargo.itemNo()), - cargo.cargoName() == null ? "" : cargo.cargoName().trim(), String.valueOf(cargo.packageCount()), + cargo.cargoName() == null ? "" : cargo.cargoName().trim(), + cargo.skuNo() == null ? "" : cargo.skuNo().trim(), String.valueOf(cargo.packageCount()), decimalOrEmpty(cargo.lengthCm()), decimalOrEmpty(cargo.widthCm()), decimalOrEmpty(cargo.heightCm()))) .collect(java.util.stream.Collectors.joining("\n")); try { diff --git a/firstleg/src/main/resources/db/phase2-carton-label-versioning-migration.sql b/firstleg/src/main/resources/db/phase2-carton-label-versioning-migration.sql index b15f57089..26df34533 100644 --- a/firstleg/src/main/resources/db/phase2-carton-label-versioning-migration.sql +++ b/firstleg/src/main/resources/db/phase2-carton-label-versioning-migration.sql @@ -15,6 +15,7 @@ DELIMITER ; CALL phase2_carton_label_add_column('label_version', 'INT UNSIGNED NOT NULL DEFAULT 1 COMMENT ''内部兼容批次字段,固定为1且不进入箱码'' AFTER carton_index'); CALL phase2_carton_label_add_column('batch_status', 'VARCHAR(16) NOT NULL DEFAULT ''ACTIVE'' COMMENT ''批次状态:ACTIVE有效、VOID已作废'' AFTER label_version'); CALL phase2_carton_label_add_column('cargo_fingerprint', 'CHAR(64) NULL COMMENT ''影响标签字段的SHA-256指纹'' AFTER batch_status'); +CALL phase2_carton_label_add_column('sku_code', 'VARCHAR(128) NULL COMMENT ''箱唛绑定的SKU快照;二维码内容不变'' AFTER cargo_name'); CALL phase2_carton_label_add_column('voided_at', 'DATETIME(3) NULL COMMENT ''批次作废时间'' AFTER cargo_fingerprint'); DROP PROCEDURE phase2_carton_label_add_column; diff --git a/firstleg/src/main/resources/db/phase2-inbound-carton-label.sql b/firstleg/src/main/resources/db/phase2-inbound-carton-label.sql index e67fc4327..1d93f2ec6 100644 --- a/firstleg/src/main/resources/db/phase2-inbound-carton-label.sql +++ b/firstleg/src/main/resources/db/phase2-inbound-carton-label.sql @@ -10,6 +10,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label ( inbound_detail_id BIGINT UNSIGNED NOT NULL COMMENT '订单货物明细ID,不建立跨库外键', cargo_item_no INT UNSIGNED NOT NULL COMMENT '订单货物明细序号快照', cargo_name VARCHAR(255) NULL COMMENT '货物名称快照', + sku_code VARCHAR(128) NULL COMMENT '箱唛绑定的SKU快照;二维码内容不变', detail_package_count INT UNSIGNED NOT NULL COMMENT '该订单货物明细箱数快照', inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照', box_code VARCHAR(80) NOT NULL COMMENT '固定二维码内容:入仓码#总箱数-箱下标', diff --git a/firstleg/src/main/resources/db/phase2-inbound-schema.sql b/firstleg/src/main/resources/db/phase2-inbound-schema.sql index 7d5e63c1d..c248098c9 100644 --- a/firstleg/src/main/resources/db/phase2-inbound-schema.sql +++ b/firstleg/src/main/resources/db/phase2-inbound-schema.sql @@ -197,6 +197,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label ( inbound_detail_id BIGINT UNSIGNED NOT NULL COMMENT '订单货物明细ID,不建立跨库外键', cargo_item_no INT UNSIGNED NOT NULL COMMENT '订单货物明细序号快照', cargo_name VARCHAR(255) NULL COMMENT '货物名称快照', + sku_code VARCHAR(128) NULL COMMENT '箱唛绑定的SKU快照;二维码内容不变', detail_package_count INT UNSIGNED NOT NULL COMMENT '该订单货物明细箱数快照', inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照', box_code VARCHAR(80) NOT NULL COMMENT '固定二维码内容:入仓码#总箱数-箱下标', diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowService.java index 537ca0f97..e988a9ba5 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowService.java @@ -154,6 +154,14 @@ public class DispatchPdaWorkflowService { if (replay != null) return read(replay, DispatchPdaResponses.PickingCompleted.class).withReplay(); requireVehicle(order); DispatchPdaTask task = tasks.lockByDispatch(customerId, order.getId()); + if (task != null && "COMPLETED".equals(task.getStatus())) { + List completedItems = items.findByDispatchOrder(customerId, order.getId()); + long planned = completedItems.stream().map(DispatchItem::getPackageCount).filter(Objects::nonNull) + .mapToLong(Integer::longValue).sum(); + long picked = picks.listTask(customerId, task.getId()).stream().mapToLong(p -> n(p.getPackages())).sum(); + return new DispatchPdaResponses.PickingCompleted(order.getDispatchNo(), order.getStatus(), planned, + picked, Math.max(0, planned - picked), picked < planned, true); + } if (task == null || !("PDA_PENDING".equals(task.getStatus()) || "PICKING".equals(task.getStatus()))) { throw conflict("Dispatch PDA task is not available for completion"); } diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/InboundPlanService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/InboundPlanService.java index 3eae2cef2..19d426809 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/InboundPlanService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/InboundPlanService.java @@ -243,6 +243,18 @@ public class InboundPlanService { if (trimToNull(request.warehouseName()) != null) line.setDestinationWarehouseName(request.warehouseName().trim()); lineMapper.updateById(line); } + // Pallets carry the same destination snapshot and are consumed by PDA/resource assignment. + // Update them in this transaction so a plan edit cannot leave lines and pallets pointing at + // different warehouses. + List pallets = palletMapper.selectList(new LambdaQueryWrapper() + .eq(InboundPlanPallet::getPlanId, plan.getId()) + .eq(InboundPlanPallet::getCustomerId, plan.getCustomerId())); + for (InboundPlanPallet pallet : pallets) { + pallet.setDestinationWarehouseId(String.valueOf(request.overseasWarehouseId())); + if (trimToNull(request.warehouseCode()) != null) pallet.setDestinationWarehouseCode(request.warehouseCode().trim()); + if (trimToNull(request.warehouseName()) != null) pallet.setDestinationWarehouseName(request.warehouseName().trim()); + palletMapper.updateById(pallet); + } return detail(customerId, plan); } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/controller/LastlegOrderControllerTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/controller/LastlegOrderControllerTest.java index 86bdeb353..64cb421eb 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/controller/LastlegOrderControllerTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/controller/LastlegOrderControllerTest.java @@ -32,7 +32,7 @@ class LastlegOrderControllerTest { private final LastlegOrderService service = mock(LastlegOrderService.class); private final LastlegOrderController controller = controller(); private final LastlegOrderRequests.Query query = new LastlegOrderRequests.Query( - 1, 20, null, null, null, null, null, null, null, null, null, null, null, null, null); + 1L, 20L, null, null, null, null, null, null, null, null, null, null, null, null, null); @Test void platformEndpointRejectsMerchantIdentity() { diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/controller/MerchantLastlegOrderControllerTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/controller/MerchantLastlegOrderControllerTest.java index c21728b09..f5dabbcb8 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/controller/MerchantLastlegOrderControllerTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/controller/MerchantLastlegOrderControllerTest.java @@ -18,7 +18,7 @@ class MerchantLastlegOrderControllerTest { private final LastlegOrderService service = mock(LastlegOrderService.class); private final MerchantLastlegOrderController controller = controller(); private final LastlegOrderRequests.Query query = new LastlegOrderRequests.Query( - 1, 20, null, null, null, null, null, null, null, null, null, null, null, null, null); + 1L, 20L, null, null, null, null, null, null, null, null, null, null, null, null, null); @Test void merchantListUsesOnlyAuthenticatedTenant() { diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowServiceTest.java index b36a7e0b1..df38d04ca 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/dispatch/pda/service/DispatchPdaWorkflowServiceTest.java @@ -2,11 +2,17 @@ package com.baiyue.lastleg.dispatch.pda.service; import com.baiyue.lastleg.delivery.mapper.OutboundOrderMapper; import com.baiyue.lastleg.dispatch.entity.DispatchOrder; +import com.baiyue.lastleg.dispatch.entity.DispatchItem; +import com.baiyue.lastleg.dispatch.mapper.DispatchItemMapper; import com.baiyue.lastleg.dispatch.mapper.DispatchOrderMapper; import com.baiyue.lastleg.dispatch.pda.dto.DispatchPdaRequests; import com.baiyue.lastleg.dispatch.pda.dto.DispatchPdaResponses; import com.baiyue.lastleg.dispatch.pda.entity.DispatchPdaOperation; +import com.baiyue.lastleg.dispatch.pda.entity.DispatchPdaPick; +import com.baiyue.lastleg.dispatch.pda.entity.DispatchPdaTask; import com.baiyue.lastleg.dispatch.pda.mapper.DispatchPdaOperationMapper; +import com.baiyue.lastleg.dispatch.pda.mapper.DispatchPdaPickMapper; +import com.baiyue.lastleg.dispatch.pda.mapper.DispatchPdaTaskMapper; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -15,6 +21,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.server.ResponseStatusException; +import java.util.List; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -25,6 +33,9 @@ class DispatchPdaWorkflowServiceTest { @Mock private DispatchOrderMapper orders; @Mock private DispatchPdaOperationMapper operations; @Mock private OutboundOrderMapper outboundOrders; + @Mock private DispatchItemMapper items; + @Mock private DispatchPdaTaskMapper tasks; + @Mock private DispatchPdaPickMapper picks; @Test void labelsTransferredPalletsWithOriginalAndCurrentFbaWarehouses() { @@ -126,4 +137,34 @@ class DispatchPdaWorkflowServiceTest { assertEquals("DEPARTED", result.status()); assertEquals(true, result.replayed()); } + + @Test + void completingAnAutomaticallyCompletedTaskReturnsIdempotentSuccess() { + DispatchPdaWorkflowService service = new DispatchPdaWorkflowService(); + ReflectionTestUtils.setField(service, "orders", orders); + ReflectionTestUtils.setField(service, "operations", operations); + ReflectionTestUtils.setField(service, "items", items); + ReflectionTestUtils.setField(service, "tasks", tasks); + ReflectionTestUtils.setField(service, "picks", picks); + DispatchOrder order = new DispatchOrder(); + order.setId(1L); order.setCustomerId("100"); order.setDispatchNo("PC1"); + order.setStatus("READY_TO_DEPART"); order.setVehiclePlate("CA-100"); + DispatchPdaTask task = new DispatchPdaTask(); + task.setId(2L); task.setStatus("COMPLETED"); + DispatchItem item = new DispatchItem(); item.setPackageCount(6); + DispatchPdaPick pick = new DispatchPdaPick(); pick.setPackages(6L); + DispatchPdaRequests.CompletePicking request = new DispatchPdaRequests.CompletePicking("complete-1", "normal"); + when(orders.findByDispatchNo("100", "PC1")).thenReturn(order); + when(orders.lockById("100", 1L)).thenReturn(order); + when(operations.findKey("100", "complete-1")).thenReturn(null); + when(tasks.lockByDispatch("100", 1L)).thenReturn(task); + when(items.findByDispatchOrder("100", 1L)).thenReturn(List.of(item)); + when(picks.listTask("100", 2L)).thenReturn(List.of(pick)); + + DispatchPdaResponses.PickingCompleted result = service.completePicking("100", "PC1", request); + + assertEquals("READY_TO_DEPART", result.status()); + assertEquals(6, result.pickedPackages()); + assertEquals(true, result.replayed()); + } } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/service/InboundPlanServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/service/InboundPlanServiceTest.java index c2d396156..896fc10c9 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/service/InboundPlanServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/service/InboundPlanServiceTest.java @@ -2,6 +2,7 @@ package com.baiyue.lastleg.inboundplan.service; import com.baiyue.lastleg.inboundplan.entity.InboundPlan; import com.baiyue.lastleg.inboundplan.dto.InboundPlanRequests; +import com.baiyue.lastleg.inboundplan.dto.UpdateInboundPlanRequest; import com.baiyue.lastleg.inboundplan.entity.InboundPlanLine; import com.baiyue.lastleg.inboundplan.entity.InboundPlanPallet; import com.baiyue.lastleg.inboundplan.entity.InboundPlanPalletAllocation; @@ -199,6 +200,53 @@ class InboundPlanServiceTest { .map(InboundPlanPalletAllocation::getPlannedPackageCount).toList()); } + @Test + void updateSynchronizesDestinationSnapshotToLinesAndPallets() { + InboundPlan plan = new InboundPlan(); + plan.setId(20L); + plan.setPlanNo("IP-20"); + plan.setCustomerId("100"); + plan.setStatus("PENDING_ASSIGNMENT"); + plan.setVersion(3); + + InboundPlanLine line = new InboundPlanLine(); + line.setId(21L); + line.setCustomerId("100"); + line.setPlanId(20L); + line.setDestinationWarehouseId("OLD-WH"); + line.setDestinationWarehouseCode("OLD-CODE"); + line.setDestinationWarehouseName("Old warehouse"); + + InboundPlanPallet pallet = new InboundPlanPallet(); + pallet.setId(22L); + pallet.setCustomerId("100"); + pallet.setPlanId(20L); + pallet.setDestinationWarehouseId("OLD-WH"); + pallet.setDestinationWarehouseCode("OLD-CODE"); + pallet.setDestinationWarehouseName("Old warehouse"); + + when(planMapper.selectOne(any())).thenReturn(plan); + when(lineMapper.selectList(any())).thenReturn(List.of(line), List.of(line)); + when(palletMapper.selectList(any())).thenReturn(List.of(pallet), List.of(pallet)); + when(allocationMapper.selectList(any())).thenReturn(List.of()); + + service.update("100", "IP-20", + new UpdateInboundPlanRequest("100", 193000000000200003L, + " US-LAX-01 ", " Los Angeles Warehouse ", 3)); + + ArgumentCaptor updatedLine = ArgumentCaptor.forClass(InboundPlanLine.class); + verify(lineMapper).updateById(updatedLine.capture()); + assertEquals("193000000000200003", updatedLine.getValue().getDestinationWarehouseId()); + assertEquals("US-LAX-01", updatedLine.getValue().getDestinationWarehouseCode()); + assertEquals("Los Angeles Warehouse", updatedLine.getValue().getDestinationWarehouseName()); + + ArgumentCaptor updatedPallet = ArgumentCaptor.forClass(InboundPlanPallet.class); + verify(palletMapper).updateById(updatedPallet.capture()); + assertEquals("193000000000200003", updatedPallet.getValue().getDestinationWarehouseId()); + assertEquals("US-LAX-01", updatedPallet.getValue().getDestinationWarehouseCode()); + assertEquals("Los Angeles Warehouse", updatedPallet.getValue().getDestinationWarehouseName()); + } + private SourceOrderSnapshot order(Long id, String inboundCode, String volume, String warehouse) { return new SourceOrderSnapshot(id, "100", "CONT-1", inboundCode, "PENDING_ASSIGNMENT", null, new BigDecimal(volume), new BigDecimal(volume).multiply(BigDecimal.TEN).intValue(), diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderServiceTest.java index 74abbfe37..cae56fce6 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/service/LastlegOrderServiceTest.java @@ -182,7 +182,7 @@ class LastlegOrderServiceTest { @Test void pageUsesPaginationAndPlatformFiltersWithoutCustomerScope() { - var query = new LastlegOrderRequests.Query(3, 25, "LL-", "FIRST_LEG", "IN-", null, + var query = new LastlegOrderRequests.Query(3L, 25L, "LL-", "FIRST_LEG", "IN-", null, "", "PENDING_ASSIGNMENT", null, "LAX", null, null, null, null, null); var resultPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(3, 25); resultPage.setTotal(0); @@ -208,7 +208,7 @@ class LastlegOrderServiceTest { when(orders.findPalletMergeRelations(List.of(11L))).thenReturn(List.of( new LastlegOrderMapper.PalletMergeRelationRow(11L, "INBOUND-2", "PMG-1"), new LastlegOrderMapper.PalletMergeRelationRow(11L, "INBOUND-3", "PMG-1"))); - var query = new LastlegOrderRequests.Query(1, 10, null, null, null, null, + var query = new LastlegOrderRequests.Query(1L, 10L, null, null, null, null, null, null, null, null, null, null, null, null, null); var result = service.page(null, query); diff --git a/order/src/main/java/com/baiyue/order/controller/InternalOrderCargoController.java b/order/src/main/java/com/baiyue/order/controller/InternalOrderCargoController.java index bf34d41c5..aff44bcb5 100644 --- a/order/src/main/java/com/baiyue/order/controller/InternalOrderCargoController.java +++ b/order/src/main/java/com/baiyue/order/controller/InternalOrderCargoController.java @@ -74,8 +74,8 @@ public class InternalOrderCargoController { } return ApiResponse.success(orders.findCargoInheritedByOrder(tenantId, orderId).stream() .map(cargo -> new CargoLabelBinding(cargo.getId(), orderId, cargo.getItemNo(), - cargo.getCargoName(), cargo.getPackageCount(), cargo.getLengthCm(), cargo.getWidthCm(), - cargo.getHeightCm())) + cargo.getCargoName(), cargo.getSkuNo(), cargo.getPackageCount(), cargo.getLengthCm(), + cargo.getWidthCm(), cargo.getHeightCm())) .toList()); } @@ -155,8 +155,13 @@ public class InternalOrderCargoController { } public record CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, - Integer packageCount, java.math.BigDecimal lengthCm, + String skuNo, Integer packageCount, java.math.BigDecimal lengthCm, java.math.BigDecimal widthCm, java.math.BigDecimal heightCm) { + public CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, + Integer packageCount, java.math.BigDecimal lengthCm, + java.math.BigDecimal widthCm, java.math.BigDecimal heightCm) { + this(cargoId, orderId, itemNo, cargoName, null, packageCount, lengthCm, widthCm, heightCm); + } } public record MeasurementDeclarationSnapshot(