fix(lastleg): expose authoritative outbound type to PDA
This commit is contained in:
+2
-1
@@ -75,7 +75,8 @@ public final class DeliveryResponses {
|
||||
Long palletId, Long warehousePalletId, String palletNo,
|
||||
int packageCount, BigDecimal grossWeightKg,
|
||||
BigDecimal volumeCbm) {}
|
||||
public record PdaTask(Long id, String taskNo, String status, String outboundNo, LocalDateTime pushedAt, LocalDateTime completedAt) {}
|
||||
public record PdaTask(Long id, String taskNo, String status, String outboundNo, String outboundType,
|
||||
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,
|
||||
|
||||
+1
-1
@@ -1114,7 +1114,7 @@ public class DeliveryTransferService {
|
||||
&& Objects.equals(item.getInboundCode(), balance.getInboundCode());
|
||||
}
|
||||
|
||||
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.PdaTask taskResult(OutboundOrder outbound, OutboundPdaTask task) { return new DeliveryResponses.PdaTask(task.getId(), task.getTaskNo(), task.getStatus(), outbound.getOutboundNo(), outbound.getOutboundType(), task.getPushedAt(), task.getCompletedAt()); }
|
||||
private DeliveryResponses.PdaTaskResolution outboundResolution(OutboundOrder outbound, OutboundPdaTask task) {
|
||||
return new DeliveryResponses.PdaTaskResolution("OUTBOUND", task.getTaskNo(), outbound.getOutboundNo(),
|
||||
outbound.getDispatchNo());
|
||||
|
||||
@@ -45,7 +45,15 @@ paths:
|
||||
summary: 查询Token绑定仓的一件代发出库任务
|
||||
description: 一件代发复用统一出库任务模型;不接收customerId或warehouseId,派送不进入PDA。
|
||||
parameters: [{ name: status, in: query, required: false, schema: { type: string } }]
|
||||
responses: { '200': { description: 出库任务列表 } }
|
||||
responses:
|
||||
'200':
|
||||
description: 出库任务列表;每项包含服务端出库类型 outboundType
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data: { type: array, items: { $ref: '#/components/schemas/PdaOutboundTask' } }
|
||||
/api/pda/v1/last-leg/outbound-tasks/resolve/{businessNo}:
|
||||
get:
|
||||
summary: 解析出库作业扫码业务号
|
||||
@@ -68,7 +76,7 @@ paths:
|
||||
summary: 扫码拣取一件代发箱件
|
||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OutboundPick' } } } }
|
||||
responses: { '200': { description: 更新后的统一出库任务 }, '409': { description: 库存、数量或幂等冲突 } }
|
||||
responses: { '200': { description: 更新后的统一出库任务, content: { application/json: { schema: { $ref: '#/components/schemas/PdaOutboundTaskResponse' } } } }, '409': { description: 库存、数量或幂等冲突 } }
|
||||
/api/pda/v1/last-leg/outbound-tasks/{taskNo}/pallets/{palletNo}/pick:
|
||||
post:
|
||||
summary: 扫描一件代发托盘并原子拣取整托剩余箱件
|
||||
@@ -77,14 +85,14 @@ paths:
|
||||
- { name: taskNo, in: path, required: true, schema: { type: string } }
|
||||
- { name: palletNo, in: path, required: true, schema: { type: string } }
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IdempotentAction' } } } }
|
||||
responses: { '200': { description: 整托拣货后的任务 }, '404': { description: 当前任务没有该托盘 }, '409': { description: 非一件代发、库存不足或幂等冲突 } }
|
||||
responses: { '200': { description: 整托拣货后的任务, content: { application/json: { schema: { $ref: '#/components/schemas/PdaOutboundTaskResponse' } } } }, '404': { description: 当前任务没有该托盘 }, '409': { description: 非一件代发、库存不足或幂等冲突 } }
|
||||
/api/pda/v1/last-leg/outbound-tasks/{taskNo}/complete:
|
||||
post:
|
||||
summary: 完成一件代发出库任务
|
||||
description: 全部托盘及箱件精确拣完后完成;同一完成幂等键返回既有结果,其他键明确冲突。
|
||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IdempotentAction' } } } }
|
||||
responses: { '200': { description: COMPLETED任务 }, '409': { description: 未全部拣货或幂等冲突 } }
|
||||
responses: { '200': { description: COMPLETED任务, content: { application/json: { schema: { $ref: '#/components/schemas/PdaOutboundTaskResponse' } } } }, '409': { description: 未全部拣货或幂等冲突 } }
|
||||
/api/pda/v1/last-leg/stocktakes:
|
||||
get:
|
||||
summary: 查询Token绑定仓盘点任务
|
||||
@@ -868,19 +876,27 @@ components:
|
||||
maxItems: 500
|
||||
description: 本次实际扫描的箱唛。一件代发指定箱唛任务分批拣货时必须提交本次子集,数量与 packages 一致;换标任务仍须提交全部指定箱唛。
|
||||
items: { type: string, minLength: 1, maxLength: 255 }
|
||||
PdaOutboundTaskResponse:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: string }
|
||||
data: { $ref: '#/components/schemas/PdaOutboundTask' }
|
||||
PdaOutboundTask:
|
||||
type: object
|
||||
required: [taskNo, status, outboundNo, outboundType]
|
||||
properties:
|
||||
id: { type: string, description: 内部任务键,不作为用户展示编号 }
|
||||
taskNo: { type: string }
|
||||
status: { type: string }
|
||||
outboundNo: { type: string }
|
||||
outboundType: { type: string, enum: [ONE_CLICK_DROPSHIP, RETURN_OUTBOUND, RELABEL_OUTBOUND, WAREHOUSE_TRANSFER_OUTBOUND, DISPATCH_DELIVERY], description: 正式出库单类型;列表、详情及写操作结果共用此响应 }
|
||||
pushedAt: { type: string, format: date-time, nullable: true }
|
||||
completedAt: { type: string, format: date-time, nullable: true }
|
||||
PdaOutboundTaskDetail:
|
||||
type: object
|
||||
required: [task, items]
|
||||
properties:
|
||||
task:
|
||||
type: object
|
||||
required: [taskNo, status, outboundNo]
|
||||
properties:
|
||||
taskNo: { type: string }
|
||||
status: { type: string }
|
||||
outboundNo: { type: string }
|
||||
pushedAt: { type: string, format: date-time, nullable: true }
|
||||
completedAt: { type: string, format: date-time, nullable: true }
|
||||
task: { $ref: '#/components/schemas/PdaOutboundTask' }
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
|
||||
+21
@@ -66,6 +66,27 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DeliveryTransferServiceTest {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.ValueSource(strings = {"ONE_CLICK_DROPSHIP", "RETURN_OUTBOUND", "RELABEL_OUTBOUND", "WAREHOUSE_TRANSFER_OUTBOUND", "DISPATCH_DELIVERY"})
|
||||
void pdaListAndDetailExposeAuthoritativeOutboundType(String outboundType) {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "type-key");
|
||||
outbound.setOverseasWarehouseId("WH-1");
|
||||
outbound.setOutboundType(outboundType);
|
||||
OutboundPdaTask task = new OutboundPdaTask();
|
||||
task.setId(701L); task.setCustomerId("TENANT-A"); task.setOutboundOrderId(301L);
|
||||
task.setTaskNo("PDA-701"); task.setStatus("PENDING");
|
||||
when(pdaTasks.listByWarehouse("WH-1", null)).thenReturn(List.of(task));
|
||||
when(pdaTasks.findByNoAndWarehouse("PDA-701", "WH-1")).thenReturn(task);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of());
|
||||
|
||||
assertEquals(outboundType, service.pdaTasks("WH-1", null).get(0).outboundType());
|
||||
var detail = service.pdaTaskDetail("WH-1", "PDA-701");
|
||||
assertEquals(outboundType, detail.task().outboundType());
|
||||
assertEquals(outboundType, new com.fasterxml.jackson.databind.ObjectMapper()
|
||||
.valueToTree(detail).path("task").path("outboundType").asText());
|
||||
}
|
||||
|
||||
@Mock DispatchOrderMapper dispatchOrders;
|
||||
@Mock DispatchItemMapper dispatchItems;
|
||||
@Mock OutboundOrderMapper outboundOrders;
|
||||
|
||||
Reference in New Issue
Block a user