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,
|
Long palletId, Long warehousePalletId, String palletNo,
|
||||||
int packageCount, BigDecimal grossWeightKg,
|
int packageCount, BigDecimal grossWeightKg,
|
||||||
BigDecimal volumeCbm) {}
|
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 PdaTaskResolution(String workflow, String taskNo, String outboundNo, String dispatchNo) {}
|
||||||
public record PdaPickPosition(Long inventoryPositionId, String palletNo, String cartonMark,
|
public record PdaPickPosition(Long inventoryPositionId, String palletNo, String cartonMark,
|
||||||
String skuCode, String inboundCode, long availablePackages,
|
String skuCode, String inboundCode, long availablePackages,
|
||||||
|
|||||||
+1
-1
@@ -1114,7 +1114,7 @@ public class DeliveryTransferService {
|
|||||||
&& Objects.equals(item.getInboundCode(), balance.getInboundCode());
|
&& 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) {
|
private DeliveryResponses.PdaTaskResolution outboundResolution(OutboundOrder outbound, OutboundPdaTask task) {
|
||||||
return new DeliveryResponses.PdaTaskResolution("OUTBOUND", task.getTaskNo(), outbound.getOutboundNo(),
|
return new DeliveryResponses.PdaTaskResolution("OUTBOUND", task.getTaskNo(), outbound.getOutboundNo(),
|
||||||
outbound.getDispatchNo());
|
outbound.getDispatchNo());
|
||||||
|
|||||||
@@ -45,7 +45,15 @@ paths:
|
|||||||
summary: 查询Token绑定仓的一件代发出库任务
|
summary: 查询Token绑定仓的一件代发出库任务
|
||||||
description: 一件代发复用统一出库任务模型;不接收customerId或warehouseId,派送不进入PDA。
|
description: 一件代发复用统一出库任务模型;不接收customerId或warehouseId,派送不进入PDA。
|
||||||
parameters: [{ name: status, in: query, required: false, schema: { type: string } }]
|
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}:
|
/api/pda/v1/last-leg/outbound-tasks/resolve/{businessNo}:
|
||||||
get:
|
get:
|
||||||
summary: 解析出库作业扫码业务号
|
summary: 解析出库作业扫码业务号
|
||||||
@@ -68,7 +76,7 @@ paths:
|
|||||||
summary: 扫码拣取一件代发箱件
|
summary: 扫码拣取一件代发箱件
|
||||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OutboundPick' } } } }
|
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:
|
/api/pda/v1/last-leg/outbound-tasks/{taskNo}/pallets/{palletNo}/pick:
|
||||||
post:
|
post:
|
||||||
summary: 扫描一件代发托盘并原子拣取整托剩余箱件
|
summary: 扫描一件代发托盘并原子拣取整托剩余箱件
|
||||||
@@ -77,14 +85,14 @@ paths:
|
|||||||
- { name: taskNo, in: path, required: true, schema: { type: string } }
|
- { name: taskNo, in: path, required: true, schema: { type: string } }
|
||||||
- { name: palletNo, 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' } } } }
|
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:
|
/api/pda/v1/last-leg/outbound-tasks/{taskNo}/complete:
|
||||||
post:
|
post:
|
||||||
summary: 完成一件代发出库任务
|
summary: 完成一件代发出库任务
|
||||||
description: 全部托盘及箱件精确拣完后完成;同一完成幂等键返回既有结果,其他键明确冲突。
|
description: 全部托盘及箱件精确拣完后完成;同一完成幂等键返回既有结果,其他键明确冲突。
|
||||||
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
parameters: [{ name: taskNo, in: path, required: true, schema: { type: string } }]
|
||||||
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IdempotentAction' } } } }
|
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:
|
/api/pda/v1/last-leg/stocktakes:
|
||||||
get:
|
get:
|
||||||
summary: 查询Token绑定仓盘点任务
|
summary: 查询Token绑定仓盘点任务
|
||||||
@@ -868,19 +876,27 @@ components:
|
|||||||
maxItems: 500
|
maxItems: 500
|
||||||
description: 本次实际扫描的箱唛。一件代发指定箱唛任务分批拣货时必须提交本次子集,数量与 packages 一致;换标任务仍须提交全部指定箱唛。
|
description: 本次实际扫描的箱唛。一件代发指定箱唛任务分批拣货时必须提交本次子集,数量与 packages 一致;换标任务仍须提交全部指定箱唛。
|
||||||
items: { type: string, minLength: 1, maxLength: 255 }
|
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:
|
PdaOutboundTaskDetail:
|
||||||
type: object
|
type: object
|
||||||
required: [task, items]
|
required: [task, items]
|
||||||
properties:
|
properties:
|
||||||
task:
|
task: { $ref: '#/components/schemas/PdaOutboundTask' }
|
||||||
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 }
|
|
||||||
items:
|
items:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
|||||||
+21
@@ -66,6 +66,27 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class DeliveryTransferServiceTest {
|
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 DispatchOrderMapper dispatchOrders;
|
||||||
@Mock DispatchItemMapper dispatchItems;
|
@Mock DispatchItemMapper dispatchItems;
|
||||||
@Mock OutboundOrderMapper outboundOrders;
|
@Mock OutboundOrderMapper outboundOrders;
|
||||||
|
|||||||
Reference in New Issue
Block a user