diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationService.java index fb8030484..ff85c70c7 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationService.java @@ -126,7 +126,8 @@ public class PdaPalletOperationService { long quantity = entry.getValue().stream().anyMatch(item -> "RETURN_BULK_SKU_LABEL".equals(item.getOperationType())) ? value(carton.getTotalQuantity()) : 1; result.add(new PalletOperationResponses.RelabelSource(carton.getId(), 0L, - pallet == null ? null : pallet.palletId(), palletCode, null, carton.getSourceBatchNo(), quantity, quantity, + // 未组托退货箱使用 UNBOUND 和零身份,不对 null 执行基本类型拆箱。 + pallet == null ? 0L : pallet.palletId(), palletCode, null, carton.getSourceBatchNo(), quantity, quantity, entry.getValue().stream().map(RelabelItem::getCartonMark).filter(Objects::nonNull).toList())); } return result; diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/MerchantRelabelApplicationController.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/MerchantRelabelApplicationController.java index 0ddf2936c..3a797c9b6 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/MerchantRelabelApplicationController.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/MerchantRelabelApplicationController.java @@ -31,8 +31,8 @@ public class MerchantRelabelApplicationController { @GetMapping("/quantity-summary") @PreAuthorize("hasAuthority('" + OverseasPermissions.MERCHANT_RELABEL_LIST + "')") public ApiResponse quantities( - @AuthenticationPrincipal AuthenticatedUser user, @Valid RelabelRequests.Query query) { - return ApiResponse.success(quantities.totals(customer(user), query)); + @AuthenticationPrincipal AuthenticatedUser user, @Valid RelabelRequests.QuantityQuery query) { + return ApiResponse.success(quantities.totals(customer(user), query.asQuery())); } @GetMapping("/inventory-candidates") @PreAuthorize("hasAuthority('" + OverseasPermissions.MERCHANT_RELABEL_LIST + "')") diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/RelabelApplicationController.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/RelabelApplicationController.java index f0b77d159..ec3a5b2a8 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/RelabelApplicationController.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/controller/RelabelApplicationController.java @@ -31,9 +31,9 @@ public class RelabelApplicationController { @GetMapping("/quantity-summary") @PreAuthorize("hasAuthority('" + OverseasPermissions.RELABEL_ORDER_LIST + "')") public ApiResponse quantities( - @AuthenticationPrincipal AuthenticatedUser user, @Valid RelabelRequests.Query query) { + @AuthenticationPrincipal AuthenticatedUser user, @Valid RelabelRequests.QuantityQuery query) { requirePlatform(user); - return ApiResponse.success(quantities.totals(null, query)); + return ApiResponse.success(quantities.totals(null, query.asQuery())); } @Resource private com.baiyue.lastleg.relabel.pda.service.PdaRelabelService pdaService; diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelRequests.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelRequests.java index 4595244e2..b895e2918 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelRequests.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/dto/RelabelRequests.java @@ -126,6 +126,15 @@ public final class RelabelRequests { public Query { if (page == 0) page = 1; if (size == 0) size = 20; } } + /** 数量汇总不需要分页参数,避免缺省原始数值绑定失败。 */ + public record QuantityQuery(String relabelNo, String customerOrderNo, String skuCode, String status, + String overseasWarehouseId, LocalDateTime createdFrom, LocalDateTime createdTo) { + public Query asQuery() { + return new Query(1, 200, relabelNo, customerOrderNo, skuCode, status, + overseasWarehouseId, createdFrom, createdTo); + } + } + public record ChangeStatus(@NotBlank @Size(max = 32) String status, @Size(max = 1000) String remark) {} diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationServiceTest.java index cdc8e8b34..ada74b54a 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/palletops/service/PdaPalletOperationServiceTest.java @@ -576,6 +576,23 @@ class PdaPalletOperationServiceTest { assertEquals(java.util.Set.of(), ReflectionTestUtils.invokeMethod(service, "boundRelabelMarks", app)); } + @Test void unboundReturnRelabelSourceDoesNotUnboxNullPalletIdentity() { + RelabelApplication app = new RelabelApplication(); app.setId(600L); app.setCustomerId("100"); + app.setRelabelNo("RL-1"); app.setOverseasWarehouseId("88"); app.setStatus("READY_FOR_OUTBOUND"); + when(relabelApplications.findAnyByRelabelNo("RL-1")).thenReturn(app); + RelabelItem item = relabelItem(701L, "BOX-1", 100L); item.setReturnCartonId(801L); + item.setOperationType("RETURN_BULK_SKU_LABEL"); + when(relabelItems.selectList(any())).thenReturn(List.of(item)); + ReturnInventoryCarton carton = new ReturnInventoryCarton(); carton.setId(801L); + carton.setCustomerId("100"); carton.setOverseasWarehouseId("88"); carton.setStatus("RELABEL_PENDING"); + carton.setTotalQuantity(8L); + when(returnCartons.selectById(801L)).thenReturn(carton); + var result = service.relabelSources(identity(), new PalletOperationRequests.RelabelSources("RL-1")); + assertEquals(0L, result.get(0).palletId()); + assertEquals("UNBOUND", result.get(0).palletCode()); + assertEquals(8L, result.get(0).stockPackages()); + } + @Test void relabelSourcesExposeAuthoritativePalletId() { var tasks = mock(com.baiyue.lastleg.relabel.pda.mapper.PdaRelabelTaskMapper.class); ReflectionTestUtils.setField(service, "relabelWorkTasks", tasks); diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/transfer/service/WarehouseTransferCartonCountTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/transfer/service/WarehouseTransferCartonCountTest.java index 3beaf15b2..e0de96786 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/transfer/service/WarehouseTransferCartonCountTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/transfer/service/WarehouseTransferCartonCountTest.java @@ -175,7 +175,7 @@ class WarehouseTransferCartonCountTest { ia.setDeclaredQuantity(4L); assertTrue(service.hasSkuReceiptDifference(List.of(a),List.of(ia,ib))); } - /** 新箱必须先补客户预报,PDA不能绕过预报生成另一套箱号。 */ + /** 缺失申报保持未知,已知SKU差异及真实零申报仍按实际值校验。 */ @Test void missingDeclarationIsUnknownButKnownSkuDifferenceStillRequiresReason() { var unknown = new WarehouseTransferItem(); unknown.setId(10L); unknown.setSkuCode("A"); var known = new WarehouseTransferItem(); known.setId(11L); known.setSkuCode("B"); known.setDeclaredQuantity(7L);