fix(firstleg): finish only actual picked cargo owners
This commit is contained in:
@@ -165,6 +165,21 @@ public interface LoadingPickItemMapper extends BaseMapper<LoadingPickItemEntity>
|
||||
""")
|
||||
java.util.List<InboundOwner> selectInboundOwners(@Param("taskId") long taskId);
|
||||
|
||||
/** Only physical cargo owns completion checkpoints; retained SKIPPED rows are plan history. */
|
||||
@Select("""
|
||||
SELECT plan_item.account_id tenantId,plan_item.inbound_id inboundId
|
||||
FROM fl_loading_pick_item pick_item
|
||||
JOIN fl_loading_pick_task task ON task.id=pick_item.pick_task_id
|
||||
JOIN fl_loading_plan_item plan_item ON plan_item.id=pick_item.loading_plan_item_id
|
||||
AND plan_item.loading_plan_id=task.loading_plan_id AND plan_item.deleted=0
|
||||
WHERE pick_item.pick_task_id=#{taskId}
|
||||
AND pick_item.item_status IN ('PICKED','PARTIAL')
|
||||
AND pick_item.picked_package_count>0
|
||||
GROUP BY plan_item.account_id,plan_item.inbound_id
|
||||
ORDER BY plan_item.account_id,plan_item.inbound_id
|
||||
""")
|
||||
java.util.List<InboundOwner> selectCompletionOwners(@Param("taskId") long taskId);
|
||||
|
||||
record InboundOwner(Long tenantId, Long inboundId) {}
|
||||
|
||||
@Select("""
|
||||
|
||||
@@ -246,6 +246,10 @@ public class LoadingPickRepository {
|
||||
return items.selectInboundOwners(taskId);
|
||||
}
|
||||
|
||||
public List<LoadingPickItemMapper.InboundOwner> completionOwners(long taskId) {
|
||||
return items.selectCompletionOwners(taskId);
|
||||
}
|
||||
|
||||
public LoadingInboundMapper.Snapshot inbound(long tenantId, long inboundId) {
|
||||
return inbounds.find(tenantId, inboundId);
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ public class LoadingPickService {
|
||||
throw conflict("存在尚未处理的PDA拣货明细,不能确认装柜完成");
|
||||
}
|
||||
if (repository.review(taskId) != null) throw conflict("PDA任务已经确认装柜完成");
|
||||
List<LoadingPickItemMapper.InboundOwner> discoveredOwners = repository.inboundOwners(taskId).stream()
|
||||
List<LoadingPickItemMapper.InboundOwner> discoveredOwners = repository.completionOwners(taskId).stream()
|
||||
.filter(owner -> owner.tenantId() != null && owner.inboundId() != null)
|
||||
.toList();
|
||||
if (discoveredOwners.isEmpty()) throw conflict("PDA任务未关联有效入库单");
|
||||
@@ -618,7 +618,7 @@ public class LoadingPickService {
|
||||
long taskId = command.getPickTaskId();
|
||||
inboundHoldGuard.requireTaskNotHeld(taskId);
|
||||
LoadingPickTaskEntity task = requiredTask(taskId);
|
||||
List<LoadingPickItemMapper.InboundOwner> owners = repository.inboundOwners(taskId).stream()
|
||||
List<LoadingPickItemMapper.InboundOwner> owners = repository.completionOwners(taskId).stream()
|
||||
.filter(owner -> owner.tenantId() != null && owner.inboundId() != null)
|
||||
.sorted(Comparator.comparing(LoadingPickItemMapper.InboundOwner::tenantId)
|
||||
.thenComparing(LoadingPickItemMapper.InboundOwner::inboundId))
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.baiyue.firstleg.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||
import com.baiyue.firstleg.mapper.LoadingCompletionCommandMapper;
|
||||
import com.baiyue.firstleg.mapper.LoadingPickItemMapper;
|
||||
import com.baiyue.firstleg.mapper.LoadingPickItemMapper.InboundOwner;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/** Execute actual owner and checkpoint Mapper SQL against persisted resolved pick facts. */
|
||||
class LoadingCompletionOwnerPersistenceTest {
|
||||
private JdbcTemplate jdbc;
|
||||
private LoadingPickItemMapper owners;
|
||||
private LoadingCompletionCommandMapper checkpoints;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
var ds = new JdbcDataSource();
|
||||
ds.setURL("jdbc:h2:mem:completion-owners-" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1");
|
||||
jdbc = new JdbcTemplate(ds);
|
||||
jdbc.execute("CREATE TABLE fl_loading_pick_task(id BIGINT,loading_plan_id BIGINT)");
|
||||
jdbc.execute("CREATE TABLE fl_loading_plan_item(id BIGINT,loading_plan_id BIGINT,account_id BIGINT,inbound_id BIGINT,deleted INT,package_count INT)");
|
||||
jdbc.execute("CREATE TABLE fl_loading_pick_item(id BIGINT,pick_task_id BIGINT,loading_plan_item_id BIGINT,item_status VARCHAR,picked_package_count INT)");
|
||||
jdbc.execute("CREATE TABLE fl_loading_completion_checkpoint(command_id BIGINT,tenant_id BIGINT,inbound_id BIGINT,owner_sequence INT,checkpoint_stage VARCHAR(24),updated_at TIMESTAMP,PRIMARY KEY(command_id,tenant_id,inbound_id))");
|
||||
jdbc.update("INSERT INTO fl_loading_pick_task VALUES(20,10)");
|
||||
row(1, 101, 50, 3, "PARTIAL", 2, 10, 0);
|
||||
row(2, 101, 50, 1, "SKIPPED", 0, 10, 0); // same source SKU history
|
||||
row(3, 202, 60, 1, "PICKED", 1, 10, 0);
|
||||
row(4, 303, 70, 1, "SKIPPED", 0, 10, 0); // whole skipped customer
|
||||
row(5, 404, 80, 1, "PICKED", 0, 10, 0); // nonphysical count
|
||||
row(6, 505, 90, 1, "PICKED", 1, 10, 1); // historical deleted cargo
|
||||
row(7, 606, 100, 1, "PICKED", 1, 999, 0); // wrong plan cannot prove loading
|
||||
row(8, 707, 110, 1, "PENDING", 1, 10, 0); // unresolved status
|
||||
var config = new MybatisConfiguration();
|
||||
config.setMapUnderscoreToCamelCase(true);
|
||||
config.addMapper(LoadingPickItemMapper.class);
|
||||
config.addMapper(LoadingCompletionCommandMapper.class);
|
||||
var factory = new MybatisSqlSessionFactoryBean();
|
||||
factory.setDataSource(ds); factory.setConfiguration(config);
|
||||
var session = new SqlSessionTemplate(factory.getObject());
|
||||
owners = session.getMapper(LoadingPickItemMapper.class);
|
||||
checkpoints = session.getMapper(LoadingCompletionCommandMapper.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void unreconciledPartialAndFullCargoOwnCompletionButSkippedAndInvalidScopeDoNot() {
|
||||
assertThat(owners.selectCompletionOwners(20)).containsExactly(new InboundOwner(101L, 50L), new InboundOwner(202L, 60L));
|
||||
// Planned owner lookup still serves claims, holds and plan operations; its scope is not weakened.
|
||||
assertThat(owners.selectInboundOwners(20)).contains(new InboundOwner(303L, 70L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void partialSettlementAndSkippedHistoryRemovalCannotChangeActualOwnerSequence() {
|
||||
List<InboundOwner> before = owners.selectCompletionOwners(20);
|
||||
jdbc.update("UPDATE fl_loading_plan_item SET package_count=2 WHERE id=1");
|
||||
jdbc.update("UPDATE fl_loading_plan_item SET deleted=1 WHERE id IN (2,4)");
|
||||
assertThat(owners.selectCompletionOwners(20)).isEqualTo(before);
|
||||
}
|
||||
|
||||
@Test
|
||||
void allActualRowsMayBePartialAndAnEntirelySkippedTaskHasNoCompletionOwner() {
|
||||
jdbc.update("UPDATE fl_loading_pick_item SET item_status='SKIPPED',picked_package_count=0 WHERE id=3");
|
||||
assertThat(owners.selectCompletionOwners(20)).containsExactly(new InboundOwner(101L, 50L));
|
||||
jdbc.update("UPDATE fl_loading_pick_item SET item_status='SKIPPED',picked_package_count=0 WHERE id=1");
|
||||
assertThat(owners.selectCompletionOwners(20)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void completedActualCheckpointsAreReadBackUnchangedAndSkippedReadyCheckpointIsNotACompletionOwner() {
|
||||
checkpoints.checkpointCompleted(900, 101, 50, 1, "READY");
|
||||
checkpoints.checkpointCompleted(900, 101, 50, 1, "SETTLED");
|
||||
checkpoints.checkpointCompleted(900, 101, 50, 1, "INBOUND_COMPLETED");
|
||||
checkpoints.checkpointCompleted(900, 202, 60, 2, "INBOUND_COMPLETED");
|
||||
checkpoints.checkpointCompleted(900, 303, 70, 3, "READY");
|
||||
assertThat(checkpoints.checkpoint(900, 101, 50)).isEqualTo("INBOUND_COMPLETED");
|
||||
assertThat(checkpoints.checkpoint(900, 202, 60)).isEqualTo("INBOUND_COMPLETED");
|
||||
assertThat(checkpoints.checkpoint(900, 303, 70)).isEqualTo("READY");
|
||||
assertThat(owners.selectCompletionOwners(20)).containsExactly(new InboundOwner(101L, 50L), new InboundOwner(202L, 60L));
|
||||
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM fl_loading_completion_checkpoint", Integer.class)).isEqualTo(3);
|
||||
}
|
||||
|
||||
private void row(long id, long tenant, long inbound, int planned, String status, int picked, long plan, int deleted) {
|
||||
jdbc.update("INSERT INTO fl_loading_plan_item VALUES(?,?,?,?,?,?)", id, plan, tenant, inbound, deleted, planned);
|
||||
jdbc.update("INSERT INTO fl_loading_pick_item VALUES(?,20,?,?,?)", id, id, status, picked);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -123,7 +123,7 @@ class LoadingCompletedPreflightDatabaseTest {
|
||||
var task = new com.baiyue.firstleg.entity.LoadingPickTaskEntity();
|
||||
task.setId(92L); task.setLoadingPlanId(90L); task.setContainerBookingId(91L);
|
||||
when(repository.task(92L)).thenReturn(task);
|
||||
when(repository.inboundOwners(92L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(92L)).thenReturn(List.of(
|
||||
new com.baiyue.firstleg.mapper.LoadingPickItemMapper.InboundOwner(11L,1L),
|
||||
new com.baiyue.firstleg.mapper.LoadingPickItemMapper.InboundOwner(22L,2L)));
|
||||
var command = new com.baiyue.firstleg.entity.LoadingCompletionCommandEntity();
|
||||
|
||||
@@ -157,6 +157,8 @@ class LoadingPickServiceTest {
|
||||
when(repository.acceptCompletion(anyLong(), anyInt())).thenReturn(1);
|
||||
when(repository.inboundOwners(anyLong())).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
|
||||
when(repository.completionOwners(anyLong())).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
|
||||
when(repository.inbound(anyLong(), anyLong())).thenAnswer(invocation ->
|
||||
new LoadingInboundMapper.Snapshot(invocation.getArgument(1), invocation.getArgument(0), "LOADING", 1));
|
||||
when(dropshipPallets.physicalMetricsByPalletIds(any())).thenReturn(List.of(
|
||||
@@ -1033,6 +1035,92 @@ class LoadingPickServiceTest {
|
||||
verify(settlementService, never()).settleOwner(anyLong(), anyLong(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void workerNeverSettlesAWholeSkippedOwnerAlongsideActualPartialAndFullCargo() {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L),
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 60L),
|
||||
new LoadingPickItemMapper.InboundOwner(303L, 70L)));
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L),
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 60L)));
|
||||
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
|
||||
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
|
||||
when(repository.completeAccepted(20L, 9L, "operator")).thenReturn(1);
|
||||
when(completionCommands.complete(930L, "worker-actual-only")).thenReturn(true);
|
||||
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT, "PDA任务不包含指定入库单"))
|
||||
.when(settlementService).settleOwner(20L, 70L, 9L, "operator");
|
||||
|
||||
service.processCompletion(completionCommand(930L, "actual-only"), "worker-actual-only");
|
||||
|
||||
verify(loadingDeliveryService, never()).requirePdaCompletionReady(303L, 70L);
|
||||
verify(settlementService, never()).settleOwner(20L, 70L, 9L, "operator");
|
||||
verify(loadingDeliveryService, never()).completeAfterPdaSettlement(eq(303L), eq(70L), anyLong(),
|
||||
anyString(), anyString(), anyString());
|
||||
verify(loadingListService).publishCompletedEvent(10L);
|
||||
verify(completionCommands).complete(930L, "worker-actual-only");
|
||||
}
|
||||
|
||||
@Test
|
||||
void completedActualOwnerCheckpointsBypassReadyAndSettlementWithoutTouchingSkippedReadyCheckpoint() {
|
||||
LoadingPickTaskEntity completing = task(); completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L), new LoadingPickItemMapper.InboundOwner(202L, 60L),
|
||||
new LoadingPickItemMapper.InboundOwner(303L, 70L)));
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L), new LoadingPickItemMapper.InboundOwner(202L, 60L)));
|
||||
when(completionCommands.checkpoint(931L, 101L, 50L)).thenReturn("INBOUND_COMPLETED");
|
||||
when(completionCommands.checkpoint(931L, 202L, 60L)).thenReturn("INBOUND_COMPLETED");
|
||||
when(completionCommands.checkpoint(931L, 303L, 70L)).thenReturn("READY");
|
||||
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT, "实际来源已经LOADED"))
|
||||
.when(loadingDeliveryService).requirePdaCompletionReady(anyLong(), anyLong());
|
||||
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
|
||||
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
|
||||
when(repository.completeAccepted(20L, 9L, "operator")).thenReturn(1);
|
||||
when(completionCommands.complete(931L, "worker-completed-checkpoints")).thenReturn(true);
|
||||
|
||||
service.processCompletion(completionCommand(931L, "completed-checkpoints"), "worker-completed-checkpoints");
|
||||
|
||||
verify(loadingDeliveryService, never()).requirePdaCompletionReady(anyLong(), anyLong());
|
||||
verify(settlementService, never()).settleOwner(anyLong(), anyLong(), anyLong(), anyString());
|
||||
verify(loadingDeliveryService, never()).completeAfterPdaSettlement(anyLong(), anyLong(), anyLong(), anyString(), anyString(), anyString());
|
||||
verify(completionCommands, never()).checkpoint(eq(931L), eq(303L), eq(70L));
|
||||
verify(completionCommands, never()).checkpoint(eq(931L), anyLong(), anyLong(), anyInt(), anyString());
|
||||
verify(loadingListService).publishCompletedEvent(10L);
|
||||
verify(completionCommands).complete(931L, "worker-completed-checkpoints");
|
||||
}
|
||||
|
||||
@Test
|
||||
void actualLoadedOwnerWithoutCompletedCheckpointStillFailsItsExistingReadyGate() {
|
||||
LoadingPickTaskEntity completing = task(); completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(new LoadingPickItemMapper.InboundOwner(101L, 50L)));
|
||||
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT, "实际来源已经LOADED且无完成检查点"))
|
||||
.when(loadingDeliveryService).requirePdaCompletionReady(101L, 50L);
|
||||
|
||||
assertThatThrownBy(() -> service.processCompletion(completionCommand(932L, "missing-checkpoint"), "worker-missing-checkpoint"))
|
||||
.isInstanceOf(LoadingPickService.CompletionProcessingException.class)
|
||||
.satisfies(error -> assertThat(((LoadingPickService.CompletionProcessingException) error).stage()).isEqualTo("OWNER_READY"));
|
||||
verify(settlementService, never()).settleOwner(anyLong(), anyLong(), anyLong(), anyString());
|
||||
verify(loadingListService, never()).publishCompletedEvent(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void anEntirelySkippedTaskCannotCreateACompletionCommand() {
|
||||
when(repository.taskForUpdate(20L)).thenReturn(task());
|
||||
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of());
|
||||
|
||||
assertThatThrownBy(() -> service.complete(20L, new CompleteLoadingRequest(0, "all-skipped", "checked"), 9L, "operator"))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("未关联有效入库单");
|
||||
verify(completionCommands, never()).insert(any());
|
||||
verify(repository, never()).acceptCompletion(anyLong(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void workerProcessesFifteenInboundOwnersInStableOrderAndFinalizesOnce() {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
@@ -1040,7 +1128,7 @@ class LoadingPickServiceTest {
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
List<LoadingPickItemMapper.InboundOwner> owners = java.util.stream.IntStream.range(0, 15)
|
||||
.mapToObj(index -> new LoadingPickItemMapper.InboundOwner(101L, 1014L - index)).toList();
|
||||
when(repository.inboundOwners(20L)).thenReturn(owners);
|
||||
when(repository.completionOwners(20L)).thenReturn(owners);
|
||||
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
|
||||
when(repository.review(20L)).thenReturn(null);
|
||||
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
|
||||
@@ -1066,7 +1154,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity task = task();
|
||||
task.setTaskStatus(initialTaskStatus);
|
||||
when(repository.task(20L)).thenReturn(task);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
|
||||
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
|
||||
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
|
||||
@@ -1102,7 +1190,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
|
||||
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
|
||||
when(repository.review(20L)).thenReturn(null);
|
||||
@@ -1129,7 +1217,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 80L),
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 60L),
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 70L),
|
||||
@@ -1168,7 +1256,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L),
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 70L)));
|
||||
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT, "第二客户门禁未就绪"))
|
||||
@@ -1196,7 +1284,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L),
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 60L)));
|
||||
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT,
|
||||
@@ -1224,7 +1312,7 @@ class LoadingPickServiceTest {
|
||||
LoadingPickTaskEntity completing = task();
|
||||
completing.setTaskStatus("COMPLETING");
|
||||
when(repository.task(20L)).thenReturn(completing);
|
||||
when(repository.inboundOwners(20L)).thenReturn(List.of(
|
||||
when(repository.completionOwners(20L)).thenReturn(List.of(
|
||||
new LoadingPickItemMapper.InboundOwner(101L, 50L),
|
||||
new LoadingPickItemMapper.InboundOwner(202L, 60L)));
|
||||
when(completionCommands.checkpoint(901L, 101L, 50L)).thenReturn("INBOUND_COMPLETED");
|
||||
|
||||
Reference in New Issue
Block a user