fix(lastleg): align outbound pallet workflows
This commit is contained in:
+7
@@ -34,6 +34,13 @@ public class OutboundPdaController {
|
||||
return ApiResponse.success(service.pdaTasks(String.valueOf(identity.overseasWarehouseId()), status));
|
||||
}
|
||||
|
||||
@GetMapping("/resolve/{businessNo}")
|
||||
public ApiResponse<DeliveryResponses.PdaTaskResolution> resolve(
|
||||
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable String businessNo) {
|
||||
PdaWarehouseIdentity identity = PdaWarehouseIdentity.require(user);
|
||||
return ApiResponse.success(service.resolvePdaTask(String.valueOf(identity.overseasWarehouseId()), businessNo));
|
||||
}
|
||||
|
||||
@GetMapping("/{taskNo}")
|
||||
public ApiResponse<DeliveryResponses.PdaTaskDetail> detail(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String taskNo) {
|
||||
|
||||
+5
-1
@@ -40,8 +40,12 @@ public final class DeliveryResponses {
|
||||
public record DeliveryDetail(DeliveryRow order, List<DeliverySku> skus,
|
||||
List<DeliveryFeeRow> fees, List<DeliveryOperationRow> operations) {}
|
||||
|
||||
public record OutboundDetail(OutboundRow outbound, DeliveryRow delivery) {}
|
||||
/** palletNo is the warehouse-authoritative physical pallet code after inbound assignment. */
|
||||
public record OutboundPalletRow(String palletNo, String inboundCode, String destinationWarehouseCode,
|
||||
String destinationWarehouseName, String skuCode, int packageCount) {}
|
||||
public record OutboundDetail(OutboundRow outbound, List<OutboundPalletRow> pallets, DeliveryRow delivery) {}
|
||||
public record PdaTask(Long id, String taskNo, String status, String outboundNo, LocalDateTime pushedAt, LocalDateTime completedAt) {}
|
||||
public record PdaTaskResolution(String workflow, String taskNo, String outboundNo, String dispatchNo) {}
|
||||
public record PdaPickPosition(Long inventoryPositionId, String palletNo, String cartonMark,
|
||||
String skuCode, String inboundCode, long availablePackages,
|
||||
long pickedPackages) {}
|
||||
|
||||
+6
@@ -23,6 +23,12 @@ public interface OutboundPdaTaskMapper extends BaseMapper<OutboundPdaTask> {
|
||||
"AND o.customer_id=t.customer_id WHERE t.task_no=#{taskNo} AND o.overseas_warehouse_id=#{warehouseId} LIMIT 1")
|
||||
OutboundPdaTask findByNoAndWarehouse(@Param("taskNo") String taskNo, @Param("warehouseId") String warehouseId);
|
||||
|
||||
@Select("SELECT t.* FROM ll_outbound_pda_task t JOIN ll_outbound_order o ON o.id=t.outbound_order_id " +
|
||||
"AND o.customer_id=t.customer_id WHERE t.customer_id=#{customerId} AND t.outbound_order_id=#{outboundOrderId} " +
|
||||
"AND o.overseas_warehouse_id=#{warehouseId} LIMIT 1")
|
||||
OutboundPdaTask findByOutboundAndWarehouse(@Param("customerId") String customerId,
|
||||
@Param("outboundOrderId") Long outboundOrderId, @Param("warehouseId") String warehouseId);
|
||||
|
||||
@Select("SELECT t.* FROM ll_outbound_pda_task t JOIN ll_outbound_order o ON o.id=t.outbound_order_id " +
|
||||
"AND o.customer_id=t.customer_id WHERE o.overseas_warehouse_id=#{warehouseId} " +
|
||||
"AND (#{status} IS NULL OR t.status=#{status}) ORDER BY t.pushed_at DESC LIMIT 200")
|
||||
|
||||
+42
-1
@@ -409,6 +409,36 @@ public class DeliveryTransferService {
|
||||
return new DeliveryResponses.PdaTaskDetail(taskResult(outbound, task), items);
|
||||
}
|
||||
|
||||
public DeliveryResponses.PdaTaskResolution resolvePdaTask(String warehouseId, String businessNo) {
|
||||
String boundWarehouseId = required(warehouseId, "PDA warehouse binding is required");
|
||||
String code = required(businessNo, "Outbound task, outbound or dispatch number is required");
|
||||
|
||||
OutboundPdaTask task = pdaTasks.findByNoAndWarehouse(code, boundWarehouseId);
|
||||
if (task != null) {
|
||||
OutboundOrder outbound = requireOutboundInWarehouse(task, boundWarehouseId);
|
||||
return outboundResolution(outbound, task);
|
||||
}
|
||||
|
||||
OutboundOrder outbound = outboundOrders.findGlobalByNo(code);
|
||||
if (outbound != null && boundWarehouseId.equals(outbound.getOverseasWarehouseId())) {
|
||||
if ("DISPATCH_DELIVERY".equals(outbound.getOutboundType()) && StringUtils.hasText(outbound.getDispatchNo())) {
|
||||
DispatchOrder dispatch = dispatchOrders.findGlobalByDispatchNo(outbound.getDispatchNo());
|
||||
if (dispatch != null && boundWarehouseId.equals(dispatch.getOverseasWarehouseId())) {
|
||||
return new DeliveryResponses.PdaTaskResolution("DISPATCH", null, outbound.getOutboundNo(),
|
||||
dispatch.getDispatchNo());
|
||||
}
|
||||
}
|
||||
task = pdaTasks.findByOutboundAndWarehouse(outbound.getCustomerId(), outbound.getId(), boundWarehouseId);
|
||||
if (task != null) return outboundResolution(outbound, task);
|
||||
}
|
||||
|
||||
DispatchOrder dispatch = dispatchOrders.findGlobalByDispatchNo(code);
|
||||
if (dispatch != null && boundWarehouseId.equals(dispatch.getOverseasWarehouseId())) {
|
||||
return new DeliveryResponses.PdaTaskResolution("DISPATCH", null, null, dispatch.getDispatchNo());
|
||||
}
|
||||
throw notFound("Outbound or dispatch task not found in the bound warehouse");
|
||||
}
|
||||
|
||||
private List<DeliveryResponses.PdaPickPosition> pdaPickPositions(String customerId, String warehouseId,
|
||||
OutboundPalletItem item) {
|
||||
if (item.getWarehousePalletId() == null) return List.of();
|
||||
@@ -448,6 +478,10 @@ public class DeliveryTransferService {
|
||||
}
|
||||
|
||||
private DeliveryResponses.PdaTask taskResult(OutboundOrder outbound, OutboundPdaTask task) { return new DeliveryResponses.PdaTask(task.getId(), task.getTaskNo(), task.getStatus(), outbound.getOutboundNo(), task.getPushedAt(), task.getCompletedAt()); }
|
||||
private DeliveryResponses.PdaTaskResolution outboundResolution(OutboundOrder outbound, OutboundPdaTask task) {
|
||||
return new DeliveryResponses.PdaTaskResolution("OUTBOUND", task.getTaskNo(), outbound.getOutboundNo(),
|
||||
outbound.getDispatchNo());
|
||||
}
|
||||
private OutboundOrder requireOutbound(OutboundPdaTask task) {
|
||||
OutboundOrder outbound = outboundOrders.selectById(task.getOutboundOrderId());
|
||||
if (outbound == null || !task.getCustomerId().equals(outbound.getCustomerId())) {
|
||||
@@ -481,7 +515,9 @@ public class DeliveryTransferService {
|
||||
if (outbound == null) throw notFound("Outbound order not found");
|
||||
String customerId = outbound.getCustomerId();
|
||||
DeliveryOrder delivery = requireDelivery(customerId, outbound.getId());
|
||||
return new DeliveryResponses.OutboundDetail(outboundRow(outbound), deliveryRow(delivery));
|
||||
List<DeliveryResponses.OutboundPalletRow> pallets = outboundPallets
|
||||
.findByOutbound(customerId, outbound.getId()).stream().map(this::outboundPalletRow).toList();
|
||||
return new DeliveryResponses.OutboundDetail(outboundRow(outbound), pallets, deliveryRow(delivery));
|
||||
}
|
||||
|
||||
public PageResult<DeliveryResponses.DeliveryRow> deliveryPage(String customerId, DeliveryRequests.Query query) {
|
||||
@@ -556,6 +592,11 @@ public class DeliveryTransferService {
|
||||
d.getDeliveryNo(), d.getStatus(), o.getPalletCount(), o.getPackageCount(), replayed);
|
||||
}
|
||||
private DeliveryResponses.OutboundRow outboundRow(OutboundOrder o) { return new DeliveryResponses.OutboundRow(o.getId(), o.getOutboundNo(), o.getDispatchNo(), o.getOverseasWarehouseId(), o.getLxCodes(), o.getStatus(), o.getPalletCount(), o.getPackageCount(), o.getCreatedAt()); }
|
||||
private DeliveryResponses.OutboundPalletRow outboundPalletRow(OutboundPalletItem item) {
|
||||
return new DeliveryResponses.OutboundPalletRow(item.getPalletNo(), item.getInboundCode(),
|
||||
item.getDestinationWarehouseCode(), item.getDestinationWarehouseName(), item.getSkuCode(),
|
||||
value(item.getPackageCount()));
|
||||
}
|
||||
private DeliveryResponses.DeliveryRow deliveryRow(DeliveryOrder d) { return new DeliveryResponses.DeliveryRow(d.getId(), d.getCustomerId(), d.getCustomerName(), d.getDeliveryNo(), d.getOutboundNo(), d.getDispatchNo(), d.getOverseasWarehouseId(), d.getOverseasWarehouseName(), d.getStatus(), d.getWaybillNo(), d.getDeliveryMethod(), d.getCarrierName(), d.getPickupMethod(), d.getLoadingType(), d.getVehicleType(), d.getVehicleSize(), d.getVehiclePlate(), d.getDriverName(), d.getDriverPhone(), d.getAppointmentAccount(), d.getSellerName(), value(d.getPalletCount()), value(d.getPackageCount()), d.getTotalWeightKg(), d.getTotalVolumeCbm(), d.getPlannedDeliveryAt(), d.getDispatchedAt(), d.getExpectedArrivalAt(), d.getSignedAt(), d.getRemark(), d.getCreatedAt()); }
|
||||
private DeliveryResponses.DeliverySku sku(LastlegOrderDetail d, LastlegOrder order) { return new DeliveryResponses.DeliverySku(order == null ? null : order.getInboundCode(), order == null ? null : order.getCustomerName(), d.getDestinationWarehouseCode(), null, d.getShipmentNo(), d.getFbaTrackingNo(), d.getSkuCode(), firstText(d.getProductNameZh(), d.getProductNameEn()), value(d.getPackageCount()), d.getGrossWeightKg(), d.getVolumeCbm()); }
|
||||
private DeliveryResponses.DeliveryFeeRow feeRow(DeliveryFee f) { return new DeliveryResponses.DeliveryFeeRow(f.getId(), f.getFeeDirection(), f.getFeeType(), f.getCurrency(), f.getAmount(), f.getRemark()); }
|
||||
|
||||
+5
-1
@@ -171,13 +171,17 @@ public class InboundPdaWorkflowService {
|
||||
if (Objects.equals(pallet.getWarehousePalletId(), resource.palletId())) return null;
|
||||
throw conflict("Destination pallet is already bound to another physical pallet");
|
||||
}
|
||||
if (resource.palletNo() == null || resource.palletNo().isBlank()) {
|
||||
throw conflict("Resolved physical pallet has no pallet code");
|
||||
}
|
||||
String destinationKey = destinationKey(pallet);
|
||||
String businessId = plan.getContainerNo() + ":" + destinationKey;
|
||||
String reservationKey = "INBOUND_CONTAINER_DESTINATION_PALLET:" + businessId + ":" + resource.palletId();
|
||||
long lockId = warehouse.reserve(customerId, resource.warehouseId(), resource.palletId(), resource.locationId(),
|
||||
"INBOUND_CONTAINER_DESTINATION_PALLET", businessId, reservationKey);
|
||||
try {
|
||||
pallet.setWarehousePalletId(resource.palletId()); pallet.setWarehouseLocationId(resource.locationId());
|
||||
pallet.setWarehousePalletId(resource.palletId()); pallet.setPalletNo(resource.palletNo().trim());
|
||||
pallet.setWarehouseLocationId(resource.locationId());
|
||||
pallet.setWarehouseResourceLockId(lockId); pallet.setAssignmentStatus("ASSIGNED");
|
||||
pallet.setLockedAt(LocalDateTime.now()); repository.update(pallet);
|
||||
return lockId;
|
||||
|
||||
@@ -564,7 +564,7 @@ paths:
|
||||
description: 权限 platform:overseas-warehouse:outbound:list;只按全局唯一 outboundNo 定位并从记录解析客户范围,不接收 customerId。
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters: [{ name: outboundNo, in: path, required: true, schema: { type: string } }]
|
||||
responses: { '200': { description: 出库单及关联派送单详情 }, '404': { description: 出库单不存在 } }
|
||||
responses: { '200': { description: 出库单、出库托盘及关联派送单详情;pallets[].palletNo 为 Warehouse 权威实物托盘码 }, '404': { description: 出库单不存在 } }
|
||||
/api/platform/v1/last-leg/outbound-orders/{outboundNo}/cancel:
|
||||
post:
|
||||
summary: 取消未执行出库单
|
||||
@@ -1537,7 +1537,7 @@ components:
|
||||
orderNo: { type: string }
|
||||
orderRefs: { type: string }
|
||||
inboundCode: { type: string }
|
||||
palletNo: { type: string }
|
||||
palletNo: { type: string, description: 未入库时为计划托盘码;绑定实物托盘后为 Warehouse 权威实物托盘码 }
|
||||
destinationWarehouseId: { type: string }
|
||||
destinationWarehouseCode: { type: string }
|
||||
destinationWarehouseName: { type: string }
|
||||
|
||||
@@ -46,6 +46,14 @@ paths:
|
||||
description: 一件代发复用统一出库任务模型;不接收customerId或warehouseId,派送不进入PDA。
|
||||
parameters: [{ name: status, in: query, required: false, schema: { type: string } }]
|
||||
responses: { '200': { description: 出库任务列表 } }
|
||||
/api/pda/v1/last-leg/outbound-tasks/resolve/{businessNo}:
|
||||
get:
|
||||
summary: 解析出库作业扫码业务号
|
||||
description: 接受一件代发任务号、出库单号或排车单号;按Token绑定仓返回 OUTBOUND 的 taskNo 或 DISPATCH 的 dispatchNo,PDA据此进入正确作业页。
|
||||
parameters: [{ name: businessNo, in: path, required: true, schema: { type: string } }]
|
||||
responses:
|
||||
'200': { description: 正确作业类型及稳定业务编号 }
|
||||
'404': { description: 当前绑定仓无此出库或排车任务 }
|
||||
/api/pda/v1/last-leg/outbound-tasks/{taskNo}:
|
||||
get:
|
||||
summary: 查询一件代发出库任务详情
|
||||
@@ -569,7 +577,7 @@ components:
|
||||
required: [outboundPalletItemId, palletNo, skuCode, inboundCode, packageCount, pickedPackageCount, status, positions]
|
||||
properties:
|
||||
outboundPalletItemId: { type: string, description: pick请求提交键,不作为用户展示编号 }
|
||||
palletNo: { type: string }
|
||||
palletNo: { type: string, description: Warehouse 权威实物托盘码 }
|
||||
skuCode: { type: string }
|
||||
inboundCode: { type: string }
|
||||
packageCount: { type: integer }
|
||||
@@ -582,7 +590,7 @@ components:
|
||||
required: [inventoryPositionId, palletNo, cartonMark, skuCode, inboundCode, availablePackages, pickedPackages]
|
||||
properties:
|
||||
inventoryPositionId: { type: string, description: pick请求提交键,不作为用户展示编号 }
|
||||
palletNo: { type: string }
|
||||
palletNo: { type: string, description: Warehouse 权威实物托盘码 }
|
||||
cartonMark: { type: string, nullable: true }
|
||||
skuCode: { type: string }
|
||||
inboundCode: { type: string }
|
||||
|
||||
+1
@@ -166,6 +166,7 @@ class PlatformDispatchOutboundContractTest {
|
||||
for (String action : Set.of(dispatchAction, transfer, outboundDetail, outboundCancel)) {
|
||||
assertFalse(action.contains("name: customerId"));
|
||||
}
|
||||
assertTrue(outboundDetail.contains("pallets[].palletNo"));
|
||||
assertTrue(yaml.contains("platform:overseas-warehouse:dispatch:edit"));
|
||||
assertTrue(yaml.contains("platform:overseas-warehouse:dispatch:cancel"));
|
||||
assertTrue(yaml.contains("platform:overseas-warehouse:dispatch:transfer-delivery"));
|
||||
|
||||
+58
-4
@@ -270,19 +270,26 @@ class DeliveryTransferServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void outboundDetailDoesNotExposeExcludedPalletOrOutboundFulfillmentRows() {
|
||||
void outboundDetailIncludesPalletCodesForDisplay() {
|
||||
OutboundOrder outbound = outbound(301L, 101L, "DSP-101", "OUT-301", "transfer-101");
|
||||
DeliveryOrder delivery = delivery(401L, outbound, "DEL-401");
|
||||
OutboundPalletItem pallet = pallet(501L, "IP-ONT8-20260907-000001-P001", "ONT8", "Ontario", "IN-A", 12);
|
||||
pallet.setSkuCode("SKU-1");
|
||||
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
|
||||
when(deliveryOrders.lockByOutbound("TENANT-A", 301L)).thenReturn(delivery);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(pallet));
|
||||
|
||||
DeliveryResponses.OutboundDetail detail = service.outboundDetail("OUT-301");
|
||||
|
||||
assertEquals("OUT-301", detail.outbound().outboundNo());
|
||||
assertEquals("DEL-401", detail.delivery().deliveryNo());
|
||||
assertTrue(java.util.Arrays.stream(DeliveryResponses.OutboundDetail.class.getRecordComponents())
|
||||
.noneMatch(component -> "pallets".equals(component.getName())));
|
||||
verify(outboundPallets, never()).selectPage(any(Page.class), any());
|
||||
assertEquals(1, detail.pallets().size());
|
||||
assertEquals("IP-ONT8-20260907-000001-P001", detail.pallets().get(0).palletNo());
|
||||
assertEquals("IN-A", detail.pallets().get(0).inboundCode());
|
||||
assertEquals("ONT8", detail.pallets().get(0).destinationWarehouseCode());
|
||||
assertEquals("SKU-1", detail.pallets().get(0).skuCode());
|
||||
assertEquals(12, detail.pallets().get(0).packageCount());
|
||||
verify(outboundPallets).findByOutbound("TENANT-A", 301L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -426,6 +433,53 @@ class DeliveryTransferServiceTest {
|
||||
verify(pdaTasks).listByWarehouse("WH-1", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void outboundNumberResolvesDispatchWorkflowInBoundWarehouse() {
|
||||
OutboundOrder outbound = outbound(301L, 401L, "DSP-401", "OUT-301", "transfer-key");
|
||||
outbound.setOverseasWarehouseId("WH-1");
|
||||
outbound.setOutboundType("DISPATCH_DELIVERY");
|
||||
DispatchOrder dispatch = new DispatchOrder();
|
||||
dispatch.setId(401L); dispatch.setDispatchNo("DSP-401"); dispatch.setOverseasWarehouseId("WH-1");
|
||||
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
|
||||
when(dispatchOrders.findGlobalByDispatchNo("DSP-401")).thenReturn(dispatch);
|
||||
|
||||
DeliveryResponses.PdaTaskResolution result = service.resolvePdaTask("WH-1", "OUT-301");
|
||||
|
||||
assertEquals("DISPATCH", result.workflow());
|
||||
assertEquals("DSP-401", result.dispatchNo());
|
||||
assertEquals("OUT-301", result.outboundNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
void outboundNumberResolvesOneClickTaskInBoundWarehouse() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "one-click-key");
|
||||
outbound.setOverseasWarehouseId("WH-1");
|
||||
outbound.setOutboundType("ONE_CLICK_DROPSHIP");
|
||||
OutboundPdaTask task = new OutboundPdaTask();
|
||||
task.setCustomerId("TENANT-A"); task.setOutboundOrderId(301L); task.setTaskNo("PDA-701");
|
||||
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
|
||||
when(pdaTasks.findByOutboundAndWarehouse("TENANT-A", 301L, "WH-1")).thenReturn(task);
|
||||
|
||||
DeliveryResponses.PdaTaskResolution result = service.resolvePdaTask("WH-1", "OUT-301");
|
||||
|
||||
assertEquals("OUTBOUND", result.workflow());
|
||||
assertEquals("PDA-701", result.taskNo());
|
||||
assertEquals("OUT-301", result.outboundNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
void pdaTaskResolutionDoesNotLeakAnotherWarehouse() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "one-click-key");
|
||||
outbound.setOverseasWarehouseId("WH-2");
|
||||
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
|
||||
|
||||
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
|
||||
() -> service.resolvePdaTask("WH-1", "OUT-301"));
|
||||
|
||||
assertEquals(404, exception.getStatusCode().value());
|
||||
verify(pdaTasks, never()).findByOutboundAndWarehouse(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void outboundPdaDetailReturnsEveryPickablePositionWithStableBusinessCodes() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "one-click-key");
|
||||
|
||||
+35
@@ -167,6 +167,41 @@ class InboundPdaWorkflowServiceTest {
|
||||
targetPallet.getWarehouseLocationId(), "assign-wrong-warehouse")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvedAssignmentReplacesPlanPalletNumberWithPhysicalWarehouseCode() {
|
||||
targetPallet.setPalletNo("IP-ACY2-20260907-597057-P001");
|
||||
targetPallet.setWarehousePalletId(null);
|
||||
targetPallet.setWarehouseLocationId(null);
|
||||
targetPallet.setWarehouseResourceLockId(null);
|
||||
targetPallet.setAssignmentStatus("PENDING_ASSIGNMENT");
|
||||
WarehouseResourceGateway.WarehousePalletReference resource =
|
||||
new WarehouseResourceGateway.WarehousePalletReference(188L, "A002", 88L, 288L,
|
||||
"IDLE", "ACY2", 1);
|
||||
when(warehouse.reserve("100", 88L, 188L, 288L, "INBOUND_CONTAINER_DESTINATION_PALLET",
|
||||
"CONT-1:WH-A", "INBOUND_CONTAINER_DESTINATION_PALLET:CONT-1:WH-A:188")).thenReturn(999L);
|
||||
|
||||
service.assignResolvedPallet("100", plan, targetPallet, resource);
|
||||
|
||||
assertEquals("A002", targetPallet.getPalletNo());
|
||||
assertEquals(188L, targetPallet.getWarehousePalletId());
|
||||
assertEquals(288L, targetPallet.getWarehouseLocationId());
|
||||
verify(repository).update(targetPallet);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvedAssignmentRejectsPhysicalPalletWithoutBusinessCodeBeforeReservation() {
|
||||
targetPallet.setWarehouseResourceLockId(null);
|
||||
WarehouseResourceGateway.WarehousePalletReference resource =
|
||||
new WarehouseResourceGateway.WarehousePalletReference(188L, " ", 88L, 288L,
|
||||
"IDLE", "ACY2", 1);
|
||||
|
||||
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
|
||||
() -> service.assignResolvedPallet("100", plan, targetPallet, resource));
|
||||
|
||||
assertEquals(409, exception.getStatusCode().value());
|
||||
verify(warehouse, never()).reserve(any(), anyLong(), anyLong(), anyLong(), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void cartonScanBindsOnlyExpectedCartonAndRemoveMakesItScannableAgain() {
|
||||
InboundPlanCarton carton = carton("BOX-001", "UNASSIGNED", targetLine.getId(), "WH-A");
|
||||
|
||||
+2
@@ -87,10 +87,12 @@ class InboundStockReceiptServiceTest {
|
||||
assertEquals("Customer", request.getValue().customerName());
|
||||
assertEquals("900", request.getValue().overseasWarehouseId());
|
||||
assertEquals("Los Angeles", request.getValue().overseasWarehouseName());
|
||||
assertEquals("PLT-21", request.getValue().palletNo());
|
||||
ArgumentCaptor<InboundStockReceipt> receipt = ArgumentCaptor.forClass(InboundStockReceipt.class);
|
||||
verify(receipts).insert(receipt.capture());
|
||||
assertEquals(5L, receipt.getValue().getReceivedPackages());
|
||||
assertEquals(10L, receipt.getValue().getInventoryPositionId());
|
||||
assertEquals("PLT-21", receipt.getValue().getPalletNo());
|
||||
assertEquals("INBOUND_COMPLETED", fixture.order.getCurrentStatus());
|
||||
assertEquals("INBOUND_PLAN:COMPLETED", fixture.order.getSubOrderStatus());
|
||||
ArgumentCaptor<LastlegOrderStatusHistory> history = ArgumentCaptor.forClass(LastlegOrderStatusHistory.class);
|
||||
|
||||
+3
-1
@@ -74,13 +74,15 @@ class PdaOperationsOpenApiContractTest {
|
||||
"/api/pda/v1/last-leg/dispatches/{dispatchNo}/complete:",
|
||||
"/api/pda/v1/last-leg/dispatches/{dispatchNo}/depart:",
|
||||
"/api/pda/v1/last-leg/outbound-tasks:",
|
||||
"/api/pda/v1/last-leg/outbound-tasks/resolve/{businessNo}:",
|
||||
"/api/pda/v1/last-leg/outbound-tasks/{taskNo}:",
|
||||
"/api/pda/v1/last-leg/outbound-tasks/{taskNo}/pick:",
|
||||
"/api/pda/v1/last-leg/outbound-tasks/{taskNo}/complete:");
|
||||
for (String path : paths) assertTrue(yaml.contains(path), path);
|
||||
assertEquals(32, paths.size());
|
||||
assertEquals(33, paths.size());
|
||||
assertTrue(yaml.contains("enum: [LOCATION, PALLET]"));
|
||||
assertTrue(yaml.contains("enum: [APPROVE, REWORK]"));
|
||||
assertTrue(yaml.contains("Warehouse 权威实物托盘码"));
|
||||
assertTrue(yaml.contains("enum: [DAMAGED, MISSING_LABEL, LABEL_MISMATCH, UNREADABLE, OTHER]"));
|
||||
assertEquals(3, occurrences(yaml, "body.code=A0404"));
|
||||
assertFalse(yaml.contains("/api/pda/v1/last-leg/delivery"));
|
||||
|
||||
Reference in New Issue
Block a user