贴标申请,仓储转运

This commit is contained in:
2026-09-24 09:01:14 +08:00
parent 10a2ab3e42
commit 186b6be7d8
27 changed files with 1203 additions and 118 deletions
@@ -113,6 +113,31 @@ class PdaRelabelServiceTest {
verify(tasks, never()).insert(any(PdaRelabelTask.class));
}
@Test
void claimReworkTaskOneAtATimeAndAssignsItToCurrentOperator() {
application.setStatus("PROCESSING");
PdaRelabelTask rework = task("AVAILABLE", 3);
rework.setOperatorKey(null);
rework.setOperatorName(null);
rework.setReviewDecision("REWORK");
rework.setReviewRemark("label is crooked");
when(applications.lockAnyByRelabelNo("FBR-1")).thenReturn(application);
when(tasks.lock("100", 1L)).thenReturn(rework);
var result = service.claim("7", "picker", 900L, "FBR-1",
new PdaRelabelRequests.Claim("claim-rework"));
assertEquals("PROCESSING", result.taskStatus());
assertEquals("REWORK", result.reviewDecision());
assertEquals("label is crooked", result.reviewRemark());
assertEquals("7", rework.getOperatorKey());
assertEquals("picker", rework.getOperatorName());
assertEquals(4, rework.getVersion());
verify(tasks).lockProcessingByOperator("7");
verify(tasks).updateWithVersion(rework, 3);
verify(tasks, never()).insert(any(PdaRelabelTask.class));
}
@Test
void workPhotoDownloadValidatesTaskOwnershipAndFileScope() {
application.setStatus("PROCESSING");
@@ -369,10 +394,12 @@ class PdaRelabelServiceTest {
var result = service.returnForRework("8", "reviewer", "FBR-1",
new PdaRelabelRequests.Review("REWORK", 2, "review-rework", "wrong label"));
assertEquals("PROCESSING", result.taskStatus());
assertEquals("AVAILABLE", result.taskStatus());
assertEquals("PROCESSING", result.applicationStatus());
assertEquals(0, result.relabelledPackages());
assertEquals("wrong label", result.reviewRemark());
assertEquals("7", task.getOperatorKey());
assertEquals("picker", task.getOperatorName());
assertTrue(result.completionPhotoFileIds().isEmpty());
verify(applicationService).resetForRework("100", "FBR-1", "8", "wrong label");
verify(applicationService, never()).changeStatus(anyString(), anyString(), anyString(), any());
@@ -126,7 +126,7 @@ class RelabelApplicationServiceTest {
void createBuildsPendingRelabelTailOrderItemsAndBothHistories() {
RelabelRequests.Create request = request("key-1", 10, 6);
RelabelApplication persisted = application(11L, "FBR-1", "10001", "key-1", null,
RelabelApplicationService.PENDING_PROCESSING);
RelabelApplicationService.PENDING_REVIEW);
persisted.setLastlegOrderId(21L);
persisted.setItemCount(1); persisted.setTotalPackageCount(10); persisted.setNotifiedPackageCount(6);
when(applications.findNo(eq("10001"), any())).thenReturn(persisted);
@@ -149,8 +149,8 @@ class RelabelApplicationServiceTest {
verify(orderHistories).insert(tailHistory.capture());
assertEquals("RELABEL_APPLICATION", tailOrder.getValue().getOrderType());
assertEquals("WAIT_RELABEL", tailOrder.getValue().getCurrentStatus());
assertEquals("RELABEL:PENDING_PROCESSING", tailOrder.getValue().getSubOrderStatus());
assertEquals("PENDING_REVIEW", tailOrder.getValue().getCurrentStatus());
assertEquals("RELABEL:PENDING_REVIEW", tailOrder.getValue().getSubOrderStatus());
assertEquals("CUSTOMER", tailOrder.getValue().getSourceRegion());
assertTrue(tailOrder.getValue().getOrderNo().matches("RL-WH-\\d{8}-\\d{6}"));
assertNull(tailOrder.getValue().getInboundCode());
@@ -159,8 +159,8 @@ class RelabelApplicationServiceTest {
assertEquals(10, tailOrder.getValue().getPackageCount());
assertEquals(6, application.getValue().getNotifiedPackageCount());
assertEquals("SKU-A", relabelItem.getValue().getSkuCode());
assertEquals("PENDING_PROCESSING", relabelHistory.getValue().getToStatus());
assertEquals("WAIT_RELABEL", tailHistory.getValue().getToStatus());
assertEquals("PENDING_REVIEW", relabelHistory.getValue().getToStatus());
assertEquals("PENDING_REVIEW", tailHistory.getValue().getToStatus());
assertEquals("FBR-1", result.application().relabelNo());
}
@@ -168,7 +168,7 @@ class RelabelApplicationServiceTest {
void warehouseTransferRelabelReusesExistingTailOrder() {
RelabelRequests.Create request = request("key-transfer", 10, 6);
RelabelApplication persisted = application(11L, "FBR-TRANSFER", "10001", "key-transfer", null,
RelabelApplicationService.PENDING_PROCESSING);
RelabelApplicationService.PENDING_REVIEW);
persisted.setLastlegOrderId(21L);
LastlegOrder transferOrder = order(21L, "10001", "WT-WH-20260916-560449", "INBOUND_COMPLETED");
transferOrder.setOrderType("WAREHOUSE_TRANSFER");
@@ -185,9 +185,38 @@ class RelabelApplicationServiceTest {
verify(orderHistories, never()).insert(any(LastlegOrderStatusHistory.class));
assertEquals(21L, application.getValue().getLastlegOrderId());
assertEquals(application.getValue().getRelabelNo(), transferOrder.getRelabelOrderNo());
assertEquals(RelabelApplicationService.PENDING_PROCESSING, transferOrder.getRelabelStatus());
assertEquals(RelabelApplicationService.PENDING_REVIEW, transferOrder.getRelabelStatus());
assertEquals("WAREHOUSE_TRANSFER", transferOrder.getOrderType());
assertEquals("INBOUND_COMPLETED", transferOrder.getCurrentStatus());
assertEquals("WAIT_RELABEL", application.getValue().getFulfillmentStatus());
}
@Test
void warehouseTransferSkuOnlyRelabelStillRequiresOutboundFulfillment() {
RelabelRequests.Item skuOnly = new RelabelRequests.Item(101L, 201L, 301L,
"SKU-A", null, null, null, "Chinese name", 1, 1,
"WT-WH-1", null, "SKU-NEW", "SKU relabel", null,
null, null, null, "CARTON-1", null, "XLX1", "SKU_LABEL",
List.of(new RelabelRequests.SkuItem("SKU-A", "SKU-NEW", 1, null)));
RelabelRequests.Create request = new RelabelRequests.Create("WT-WH-1", "WH-1",
LocalDateTime.of(2026, 9, 25, 18, 0), "Li", "13800000000", null,
"warehouse transfer", "key-transfer-sku", List.of(skuOnly), "TRUCK", false);
RelabelApplication persisted = application(11L, "FBR-TRANSFER-SKU", "10001",
"key-transfer-sku", null, RelabelApplicationService.PENDING_REVIEW);
persisted.setLastlegOrderId(21L);
LastlegOrder transferOrder = order(21L, "10001", "WT-WH-1", "INBOUND_COMPLETED");
transferOrder.setOrderType("WAREHOUSE_TRANSFER");
when(applications.findNo(eq("10001"), any())).thenReturn(persisted);
when(items.selectList(any())).thenReturn(List.of(item(31L, 11L, "SKU-A", 1, 1)));
when(histories.selectList(any())).thenReturn(List.of());
when(orders.selectById(21L)).thenReturn(transferOrder);
service.createForExistingTailOrder("10001", "operator-1", 21L, request);
ArgumentCaptor<RelabelApplication> application = ArgumentCaptor.forClass(RelabelApplication.class);
verify(applications).insert(application.capture());
assertEquals("TRUCK", application.getValue().getDeliveryMethod());
assertEquals("WAIT_RELABEL", application.getValue().getFulfillmentStatus());
}
@Test
@@ -465,6 +494,56 @@ class RelabelApplicationServiceTest {
verify(walletCommands, never()).publish(any(), any(Long.class), any(), any(), any(), any(), any(Long.class));
}
@Test
void directLabelingOrderCanOnlyBeApprovedFromTailOrderReview() {
RelabelApplication application = application(11L, "FBR-DIRECT", "10001", "key-direct", "hash",
RelabelApplicationService.PENDING_REVIEW);
application.setLastlegOrderId(21L);
LastlegOrder order = order(21L, "10001", "LMO-DIRECT", RelabelApplicationService.PENDING_REVIEW);
order.setOrderType("RELABEL_APPLICATION"); order.setRelabelOrderNo("FBR-DIRECT");
stubDetail(application);
when(applications.lockNo("10001", "FBR-DIRECT")).thenReturn(application);
when(orders.selectById(21L)).thenReturn(order);
ResponseStatusException wrongEntry = assertThrows(ResponseStatusException.class, () ->
service.changeStatus("10001", "FBR-DIRECT", "operator-2",
new RelabelRequests.ChangeStatus("PENDING_PROCESSING", null)));
assertEquals(409, wrongEntry.getStatusCode().value());
service.reviewDirectTailOrder("10001", 21L, "operator-2",
new RelabelRequests.ChangeStatus("PENDING_PROCESSING", null));
assertEquals(RelabelApplicationService.PENDING_PROCESSING, application.getStatus());
assertEquals("WAIT_RELABEL", order.getCurrentStatus());
assertEquals("RELABEL:PENDING_PROCESSING", order.getSubOrderStatus());
}
@Test
void directLabelingRejectionRequiresAndKeepsReviewRemark() {
RelabelApplication application = application(11L, "FBR-DIRECT", "10001", "key-direct", "hash",
RelabelApplicationService.PENDING_REVIEW);
application.setLastlegOrderId(21L);
LastlegOrder order = order(21L, "10001", "LMO-DIRECT", RelabelApplicationService.PENDING_REVIEW);
order.setOrderType("RELABEL_APPLICATION"); order.setRelabelOrderNo("FBR-DIRECT");
stubDetail(application);
when(applications.lockNo("10001", "FBR-DIRECT")).thenReturn(application);
when(orders.selectById(21L)).thenReturn(order);
ResponseStatusException missingReason = assertThrows(ResponseStatusException.class, () ->
service.reviewDirectTailOrder("10001", 21L, "operator-2",
new RelabelRequests.ChangeStatus("REJECTED", " ")));
assertEquals(400, missingReason.getStatusCode().value());
service.reviewDirectTailOrder("10001", 21L, "operator-2",
new RelabelRequests.ChangeStatus("REJECTED", "请替换模糊的箱唛文件"));
assertEquals("REJECTED", application.getStatus());
assertEquals("REJECTED", order.getCurrentStatus());
ArgumentCaptor<RelabelStatusHistory> history = ArgumentCaptor.forClass(RelabelStatusHistory.class);
verify(histories).insert(history.capture());
assertEquals("请替换模糊的箱唛文件", history.getValue().getRemark());
}
@Test
void completedReturnRelabelKeepsParentInboundCompleted() {
RelabelApplication application = application(11L, "FBR-1", "10001", "key-1", "hash", RelabelApplicationService.READY_FOR_OUTBOUND);
@@ -44,6 +44,7 @@ import com.baiyue.lastleg.transfer.gateway.TransferMeasurementPhotoFileGateway;
import com.baiyue.lastleg.transfer.mapper.WarehouseTransferReceiptMapper;
import com.baiyue.lastleg.transfer.mapper.WarehouseTransferSourceOrderMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -90,6 +91,28 @@ class WarehouseTransferServiceTest {
assertNull(WarehouseTransferService.customerMainStatuses(WarehouseTransferService.DRAFT));
}
@Test
void transferPageReturnsRelabelApplicationAndFulfillmentStatuses() {
WarehouseTransferOrder transfer = transfer(WarehouseTransferService.WAIT_RELABEL);
transfer.setNeedRelabel(true);
transfer.setRelabelNo("RL-20260923-000001");
Page<WarehouseTransferOrder> resultPage = new Page<>(1, 20, 1);
resultPage.setRecords(List.of(transfer));
RelabelApplication relabel = new RelabelApplication();
relabel.setRelabelNo("RL-20260923-000001");
relabel.setStatus("COMPLETED");
relabel.setFulfillmentStatus("READY_FOR_DISPATCH");
when(transfers.selectPage(any(), any())).thenReturn(resultPage);
when(relabelApplications.selectList(any())).thenReturn(List.of(relabel));
var result = service.page("TENANT-A", new WarehouseTransferRequests.Query(
1, 20, null, null, null, null, null, null, null, null));
assertEquals("RL-20260923-000001", result.records().get(0).relabelNo());
assertEquals("COMPLETED", result.records().get(0).relabelStatus());
assertEquals("READY_FOR_DISPATCH", result.records().get(0).relabelFulfillmentStatus());
}
@Mock WarehouseTransferOrderMapper transfers;
@Mock WarehouseTransferItemMapper transferItems;
@Mock WarehouseTransferCartonMapper transferCartons;
@@ -328,9 +351,9 @@ class WarehouseTransferServiceTest {
}
@Test
void transferCanEnterTheTransitWarehouseBeforeFbaDestinationIsKnown() {
void transferCanEnterTheTransitWarehouseWithFbaDestinationAndNoRelabel() {
WarehouseTransferRequests.Create request = new WarehouseTransferRequests.Create(
"IN-1", List.of(11L), "WH-1", null, "123 Pickup Road", 5,
"IN-1", List.of(11L), "WH-1", "ONT8", "123 Pickup Road", 5,
new BigDecimal("0.2500"), "WAREHOUSE_PICKUP", LocalDateTime.of(2026, 9, 12, 10, 0),
null, null, null, "FBA destination will be supplied later", false, "key-no-fba",
List.of(new WarehouseTransferRequests.Item("SKU-1", "Product", 5, "MARK-1")));
@@ -346,9 +369,9 @@ class WarehouseTransferServiceTest {
ArgumentCaptor<LastlegOrder> tailOrder = ArgumentCaptor.forClass(LastlegOrder.class);
verify(transfers).insert(transfer.capture());
verify(orders).insert(tailOrder.capture());
assertNull(transfer.getValue().getFbaWarehouseCode());
assertEquals("ONT8", transfer.getValue().getFbaWarehouseCode());
assertNull(transfer.getValue().getFbaShipmentNo());
assertNull(tailOrder.getValue().getFbaWarehouseCode());
assertEquals("ONT8", tailOrder.getValue().getFbaWarehouseCode());
assertEquals("WAREHOUSE_PICKUP", transfer.getValue().getDeliveryMethod());
}
@@ -391,7 +414,7 @@ class WarehouseTransferServiceTest {
@Test
void newTransitInboundCreatesSnapshotAndImmutableCartonMarksWithoutHistoricalInventory() {
WarehouseTransferRequests.Create request = new WarehouseTransferRequests.Create(
null, null, "WH-1", null, "123 Pickup Road", 5,
null, null, "WH-1", "ONT8", "123 Pickup Road", 5,
new BigDecimal("0.2500"), "WAREHOUSE_PICKUP", LocalDateTime.of(2026, 9, 12, 10, 0),
null, "TRACK-MUST-NOT-BE-SAVED", null, "Incoming transit cargo", true, "key-incoming",
List.of(new WarehouseTransferRequests.Item("SKU-1", "Product A", 2, null),