fix: replay completed dispatch picks
This commit is contained in:
+12
-5
@@ -77,22 +77,29 @@ public class DispatchPdaWorkflowService {
|
|||||||
DispatchPdaRequests.Pick request) {
|
DispatchPdaRequests.Pick request) {
|
||||||
DispatchOrder order = requireWarehouseOrder(warehouseId, dispatchNo);
|
DispatchOrder order = requireWarehouseOrder(warehouseId, dispatchNo);
|
||||||
String customerId = order.getCustomerId();
|
String customerId = order.getCustomerId();
|
||||||
|
DispatchPdaTask task = tasks.lockByDispatch(customerId, order.getId());
|
||||||
|
if (task == null) throw conflict("Dispatch PDA task is not available for picking");
|
||||||
|
if (!warehouseId.equals(task.getWarehouseId())) throw conflict("PDA pick warehouse does not match task warehouse");
|
||||||
|
DispatchPdaOperation replay = replay(customerId, "PICK", request.idempotencyKey(), request);
|
||||||
|
if (replay != null) {
|
||||||
|
DispatchPdaResponses.Picked result = read(replay, DispatchPdaResponses.Picked.class);
|
||||||
|
if (!task.getId().equals(replay.getTaskId()) || result.dispatchItemId() != itemId) {
|
||||||
|
throw conflict("Idempotency key was reused with a different dispatch pick request");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
requirePdaStatus(order);
|
requirePdaStatus(order);
|
||||||
requireVehicle(order);
|
requireVehicle(order);
|
||||||
items.bindReceivedPallets(customerId, order.getId());
|
items.bindReceivedPallets(customerId, order.getId());
|
||||||
DispatchPdaTask task = tasks.lockByDispatch(customerId, order.getId());
|
if (!("PDA_PENDING".equals(task.getStatus()) || "PICKING".equals(task.getStatus()))) {
|
||||||
if (task == null || !("PDA_PENDING".equals(task.getStatus()) || "PICKING".equals(task.getStatus()))) {
|
|
||||||
throw conflict("Dispatch PDA task is not available for picking");
|
throw conflict("Dispatch PDA task is not available for picking");
|
||||||
}
|
}
|
||||||
if (!warehouseId.equals(task.getWarehouseId())) throw conflict("PDA pick warehouse does not match task warehouse");
|
|
||||||
bindOperator(task, operatorId, operatorName);
|
bindOperator(task, operatorId, operatorName);
|
||||||
DispatchItem item = items.selectById(itemId);
|
DispatchItem item = items.selectById(itemId);
|
||||||
if (item == null || !customerId.equals(item.getCustomerId()) || !order.getId().equals(item.getDispatchOrderId())) {
|
if (item == null || !customerId.equals(item.getCustomerId()) || !order.getId().equals(item.getDispatchOrderId())) {
|
||||||
throw notFound("Dispatch pallet item not found");
|
throw notFound("Dispatch pallet item not found");
|
||||||
}
|
}
|
||||||
if (!warehouseId.equals(item.getOverseasWarehouseId())) throw conflict("Pallet does not belong to selected warehouse");
|
if (!warehouseId.equals(item.getOverseasWarehouseId())) throw conflict("Pallet does not belong to selected warehouse");
|
||||||
DispatchPdaOperation replay = replay(customerId, "PICK", request.idempotencyKey(), request);
|
|
||||||
if (replay != null) return read(replay, DispatchPdaResponses.Picked.class);
|
|
||||||
InventoryPosition position = positions.selectById(request.positionId());
|
InventoryPosition position = positions.selectById(request.positionId());
|
||||||
if (position == null || !customerId.equals(position.getCustomerId())
|
if (position == null || !customerId.equals(position.getCustomerId())
|
||||||
|| item.getWarehousePalletId() == null || !item.getWarehousePalletId().equals(position.getPalletId())) {
|
|| item.getWarehousePalletId() == null || !item.getWarehousePalletId().equals(position.getPalletId())) {
|
||||||
|
|||||||
+5
-6
@@ -108,18 +108,16 @@ class DispatchPdaWorkflowServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void exactPickRetryReturnsPersistedResultWithoutInventoryDeduction() throws Exception {
|
void exactPickRetryReturnsPersistedResultAfterTaskAutomaticallyCompleted() throws Exception {
|
||||||
DispatchOrder order = order("100", "DSP-1", "WH-1", "PICKING");
|
DispatchOrder order = order("100", "DSP-1", "WH-1", "READY_TO_DEPART");
|
||||||
order.setVehiclePlate("CA-100");
|
order.setVehiclePlate("CA-100");
|
||||||
DispatchPdaTask task = task(11L, "100", "WH-1", "PICKING");
|
DispatchPdaTask task = task(11L, "100", "WH-1", "COMPLETED");
|
||||||
task.setOperatorId("7");
|
task.setOperatorId("7");
|
||||||
DispatchItem item = item(21L, "100", 5);
|
|
||||||
DispatchPdaRequests.Pick request = new DispatchPdaRequests.Pick(31L, 2, 2, "pick-1", null);
|
DispatchPdaRequests.Pick request = new DispatchPdaRequests.Pick(31L, 2, 2, "pick-1", null);
|
||||||
DispatchPdaResponses.Picked persisted = new DispatchPdaResponses.Picked(21L, 31L, 2, 2, false, false);
|
DispatchPdaResponses.Picked persisted = new DispatchPdaResponses.Picked(21L, 31L, 2, 2, false, false);
|
||||||
DispatchPdaOperation replay = operation("PICK", request, persisted);
|
DispatchPdaOperation replay = operation("PICK", request, persisted);
|
||||||
when(orders.findGlobalByDispatchNo("DSP-1")).thenReturn(order);
|
when(orders.findGlobalByDispatchNo("DSP-1")).thenReturn(order);
|
||||||
when(tasks.lockByDispatch("100", 1L)).thenReturn(task);
|
when(tasks.lockByDispatch("100", 1L)).thenReturn(task);
|
||||||
when(items.selectById(21L)).thenReturn(item);
|
|
||||||
when(operations.findKey("100", "pick-1")).thenReturn(replay);
|
when(operations.findKey("100", "pick-1")).thenReturn(replay);
|
||||||
|
|
||||||
DispatchPdaResponses.Picked result = service.pick("WH-1", "DSP-1", 21L, "7", "Picker", request);
|
DispatchPdaResponses.Picked result = service.pick("WH-1", "DSP-1", 21L, "7", "Picker", request);
|
||||||
@@ -127,6 +125,7 @@ class DispatchPdaWorkflowServiceTest {
|
|||||||
assertEquals(2, result.packages());
|
assertEquals(2, result.packages());
|
||||||
verify(inventory, never()).allocate(any(), any(), any());
|
verify(inventory, never()).allocate(any(), any(), any());
|
||||||
verify(picks, never()).insert((DispatchPdaPick) any());
|
verify(picks, never()).insert((DispatchPdaPick) any());
|
||||||
|
verify(items, never()).bindReceivedPallets(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -207,7 +206,7 @@ class DispatchPdaWorkflowServiceTest {
|
|||||||
|
|
||||||
private DispatchPdaOperation operation(String type, Object request, Object result) throws Exception {
|
private DispatchPdaOperation operation(String type, Object request, Object result) throws Exception {
|
||||||
DispatchPdaOperation value = new DispatchPdaOperation();
|
DispatchPdaOperation value = new DispatchPdaOperation();
|
||||||
value.setOperationType(type); value.setStatus("COMPLETED");
|
value.setTaskId(11L); value.setOperationType(type); value.setStatus("COMPLETED");
|
||||||
value.setRequestHash(HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
|
value.setRequestHash(HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
|
||||||
.digest(objectMapper.writeValueAsString(request).getBytes(StandardCharsets.UTF_8))));
|
.digest(objectMapper.writeValueAsString(request).getBytes(StandardCharsets.UTF_8))));
|
||||||
value.setResultJson(objectMapper.writeValueAsString(result));
|
value.setResultJson(objectMapper.writeValueAsString(result));
|
||||||
|
|||||||
Reference in New Issue
Block a user