货柜pda 添加操作人
This commit is contained in:
+4
-2
@@ -33,8 +33,10 @@ class LoadingListControllerContractTest {
|
||||
authority("lifecycle", "platform:firstleg:preload:list", AuthenticatedUser.class, long.class, long.class);
|
||||
authority("updateTransport", "platform:firstleg:preload:edit", AuthenticatedUser.class,
|
||||
long.class, long.class, String.class, TransportUpdateRequest.class);
|
||||
authority("confirmPreload", "platform:firstleg:preload:edit", AuthenticatedUser.class,
|
||||
long.class, String.class, ConfirmPreloadRequest.class);
|
||||
Method confirm = PlatformLoadingListController.class.getDeclaredMethod("confirmPreload",
|
||||
AuthenticatedUser.class, long.class, String.class, ConfirmPreloadRequest.class);
|
||||
assertThat(confirm.getAnnotation(PreAuthorize.class).value())
|
||||
.isEqualTo("hasAuthority('platform:firstleg:preload:edit') and hasAuthority('platform:firstleg:pda:assign')");
|
||||
authority("confirmedPage", "platform:firstleg:loading-list:list", AuthenticatedUser.class,
|
||||
ConfirmedQuery.class);
|
||||
authority("confirmedDetail", "platform:firstleg:loading-list:list", AuthenticatedUser.class, long.class, long.class);
|
||||
|
||||
+3
-2
@@ -35,7 +35,7 @@ class LoadingPickPdaTaskSqlContractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void pendingTasksAreLimitedToUnassignedOrCurrentOperatorWithoutCustomerInput() throws Exception {
|
||||
void pendingTasksAreLimitedToAssignedOperatorWithoutCustomerInput() throws Exception {
|
||||
String sql = LoadingPickTaskMapper.class
|
||||
.getDeclaredMethod("selectPendingForOperator", long.class, long.class, String.class)
|
||||
.getAnnotation(Select.class).value()[0];
|
||||
@@ -54,7 +54,8 @@ class LoadingPickPdaTaskSqlContractTest {
|
||||
.contains("pick_item.item_status IN ('PENDING', 'PICKING')")
|
||||
.contains("THEN 'AWAITING_REVIEW'")
|
||||
.contains("ELSE 'IN_PROGRESS' END AS workflowStatus")
|
||||
.contains("assignment.pick_task_id IS NULL OR assignment.assignee_id = #{operatorId}")
|
||||
.contains("AND assignment.assignee_id = #{operatorId}")
|
||||
.doesNotContain("assignment.pick_task_id IS NULL OR assignment.assignee_id = #{operatorId}")
|
||||
.contains("booking.warehouse_id AS warehouseId")
|
||||
.doesNotContain("tenantId");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.baiyue.firstleg.dto.LoadingListDtos.PreloadReadiness;
|
||||
import com.baiyue.firstleg.dto.LoadingListDtos.DocumentAttachRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingListDtos.DocumentCompleteRequest;
|
||||
import com.baiyue.firstleg.client.LoadingDocumentFileClient;
|
||||
import com.baiyue.firstleg.client.DomesticPdaOperatorClient;
|
||||
import com.baiyue.firstleg.entity.LoadingPickTaskEntity;
|
||||
import com.baiyue.firstleg.entity.ContainerDocumentEntity;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.firstleg.mapper.LoadingListQueryMapper.AggregateRow;
|
||||
@@ -63,6 +65,8 @@ class LoadingListServiceTest {
|
||||
@MockBean
|
||||
private LoadingDocumentFileClient documentFiles;
|
||||
@MockBean
|
||||
private DomesticPdaOperatorClient domesticPdaOperators;
|
||||
@MockBean
|
||||
private LoadingCompletedOutboxService loadingCompletedOutboxService;
|
||||
@MockBean
|
||||
private FbaPricingService fbaPricingService;
|
||||
@@ -784,6 +788,18 @@ class LoadingListServiceTest {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void rejectsInvalidPdaOperatorBeforeConfirmingAnyPreload() {
|
||||
when(domesticPdaOperators.required(any(), eq(77L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(88L, "其他人")));
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(10L, 9L, "operator", "invalid-operator",
|
||||
new ConfirmPreloadRequest(3, 77L)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("作业员无效");
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(), anyInt(), anyLong(), anyString());
|
||||
verify(loadingPickService, never()).beginIfReady(anyLong(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void confirmsEveryLinkedPreloadAndCreatesSinglePdaTaskAtomically() {
|
||||
AggregateRow before = row("EDITING", 3);
|
||||
@@ -810,9 +826,16 @@ class LoadingListServiceTest {
|
||||
when(repository.confirmLinkedPreload(301L, "PENDING", 2, 9L, "operator")).thenReturn(1);
|
||||
when(repository.confirmLinkedPreload(302L, "CONFIRMING", 5, 9L, "operator")).thenReturn(1);
|
||||
when(repository.preloadDetail(after)).thenReturn(detail);
|
||||
when(domesticPdaOperators.required(any(), eq(77L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(77L, "作业员")));
|
||||
LoadingPickTaskEntity pickTask = new LoadingPickTaskEntity();
|
||||
pickTask.setId(80L);
|
||||
when(pickRepository.taskByPlan(10L)).thenReturn(pickTask);
|
||||
when(pickRepository.createAssignment(80L, 77L, "作业员", 9L, "operator", "ASSIGNED"))
|
||||
.thenReturn(1);
|
||||
|
||||
PreloadConfirmationResponse response = service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3));
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3, 77L));
|
||||
|
||||
assertThat(response.confirmationStatus()).isEqualTo("CONFIRMED");
|
||||
assertThat(response.version()).isEqualTo(4);
|
||||
@@ -822,6 +845,7 @@ class LoadingListServiceTest {
|
||||
verify(fbaPricingService).recalculateUnlockedContainerCustomerFees(eq(30L), eq(101L), anyString());
|
||||
verify(fbaPricingService).recalculateUnlockedContainerCustomerFees(eq(30L), eq(102L), anyString());
|
||||
verify(loadingPickService, times(1)).beginIfReady(30L, 9L, "operator");
|
||||
verify(pickRepository).createAssignment(80L, 77L, "作业员", 9L, "operator", "ASSIGNED");
|
||||
verify(repository).appendHistory(eq(10L), anyString(), eq("CONFIRM_PRELOAD"),
|
||||
eq("EDITING"), eq("EDITING"), anyString(), anyString(), eq(9L),
|
||||
eq("operator"), org.mockito.ArgumentMatchers.isNull());
|
||||
@@ -838,9 +862,11 @@ class LoadingListServiceTest {
|
||||
when(fbaPricingService.recalculateUnlockedContainerCustomerFees(eq(30L), eq(101L), anyString()))
|
||||
.thenReturn(new FbaPricingService.ContainerFeeRecalculationResult(
|
||||
FbaPricingService.ContainerFeeRecalculationStatus.NOT_READY, 0));
|
||||
when(domesticPdaOperators.required(any(), eq(77L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(77L, "作业员")));
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3)))
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3, 77L)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("初始费用");
|
||||
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(), anyInt(), anyLong(), anyString());
|
||||
@@ -852,7 +878,7 @@ class LoadingListServiceTest {
|
||||
void exactConfirmationReplayReturnsFrozenResponseWithoutTouchingPlan() throws Exception {
|
||||
PreloadConfirmationResponse expected = new PreloadConfirmationResponse(
|
||||
10L, 30L, "CONFIRMED", 4, readiness("CONFIRMED", false, true, 80L));
|
||||
String requestHash = sha256("CONFIRM_PRELOAD|10|3");
|
||||
String requestHash = sha256("CONFIRM_PRELOAD|10|3|77");
|
||||
HistoryRow replay = new HistoryRow();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
replay.setAfterSnapshot(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
|
||||
@@ -860,7 +886,7 @@ class LoadingListServiceTest {
|
||||
when(repository.history(anyString())).thenReturn(replay);
|
||||
|
||||
PreloadConfirmationResponse actual = service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3));
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3, 77L));
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
verify(loadingPickService, never()).requirePreloadConfirmationReady(anyLong());
|
||||
@@ -876,14 +902,14 @@ class LoadingListServiceTest {
|
||||
void rejectsConfirmationReplayWhenExpectedVersionDiffers() throws Exception {
|
||||
PreloadConfirmationResponse expected = new PreloadConfirmationResponse(
|
||||
10L, 30L, "CONFIRMED", 4, readiness("CONFIRMED", false, true, 80L));
|
||||
String originalHash = sha256("CONFIRM_PRELOAD|10|3");
|
||||
String originalHash = sha256("CONFIRM_PRELOAD|10|3|77");
|
||||
HistoryRow replay = new HistoryRow();
|
||||
replay.setAfterSnapshot(new ObjectMapper().writeValueAsString(
|
||||
java.util.Map.of("requestHash", originalHash, "response", expected)));
|
||||
when(repository.history(anyString())).thenReturn(replay);
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(4)))
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(4, 77L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
@@ -898,11 +924,13 @@ class LoadingListServiceTest {
|
||||
AggregateRow confirmed = row("EDITING", 4);
|
||||
when(repository.history(anyString())).thenReturn(null);
|
||||
when(repository.aggregate(10L)).thenReturn(confirmed);
|
||||
when(domesticPdaOperators.required(any(), eq(77L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(77L, "作业员")));
|
||||
when(loadingPickService.requirePreloadConfirmationReady(10L))
|
||||
.thenThrow(new BizException(ResultCode.CONFLICT, "预装计划已确认"));
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "new-confirm-key", new ConfirmPreloadRequest(4)))
|
||||
10L, 9L, "operator", "new-confirm-key", new ConfirmPreloadRequest(4, 77L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
@@ -919,11 +947,13 @@ class LoadingListServiceTest {
|
||||
AggregateRow before = row("EDITING", 3);
|
||||
when(repository.history(anyString())).thenReturn(null);
|
||||
when(repository.aggregate(10L)).thenReturn(before);
|
||||
when(domesticPdaOperators.required(any(), eq(77L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(77L, "作业员")));
|
||||
when(loadingPickService.requirePreloadConfirmationReady(10L))
|
||||
.thenThrow(new BizException(ResultCode.CONFLICT, "第二票订舱尚未放舱"));
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3)))
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(3, 77L)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("第二票");
|
||||
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(),
|
||||
@@ -940,7 +970,7 @@ class LoadingListServiceTest {
|
||||
when(repository.history(anyString())).thenReturn(replay);
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(4)))
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(4, 77L)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("不同请求");
|
||||
|
||||
verify(loadingPickService, never()).requirePreloadConfirmationReady(anyLong());
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.baiyue.firstleg.dto.LoadingPickDtos.ClaimRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.AssignRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.CompleteLoadingRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.Task;
|
||||
import com.baiyue.firstleg.client.DomesticPdaOperatorClient;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.firstleg.entity.InboundPalletAllocationEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickAssignmentEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickHistoryEntity;
|
||||
@@ -106,6 +108,8 @@ class LoadingPickServiceTest {
|
||||
private InboundHoldGuard inboundHoldGuard;
|
||||
@MockBean
|
||||
private DropshipPalletizationMapper dropshipPallets;
|
||||
@MockBean
|
||||
private DomesticPdaOperatorClient domesticPdaOperators;
|
||||
@Resource
|
||||
private LoadingPickService service;
|
||||
|
||||
@@ -565,8 +569,7 @@ class LoadingPickServiceTest {
|
||||
when(repository.operation("claim-2")).thenReturn(null);
|
||||
when(repository.task(20L)).thenReturn(task);
|
||||
when(repository.taskForUpdate(20L)).thenReturn(task);
|
||||
when(repository.assignment(20L)).thenReturn(null, assignment);
|
||||
when(repository.createAssignment(20L, 9L, "operator", 9L, "operator", "CLAIMED")).thenReturn(1);
|
||||
when(repository.assignment(20L)).thenReturn(assignment);
|
||||
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(1, 0);
|
||||
doAnswer(invocation -> {
|
||||
LoadingPickOperationEntity value = invocation.getArgument(0);
|
||||
@@ -574,9 +577,9 @@ class LoadingPickServiceTest {
|
||||
return null;
|
||||
}).when(repository).insert(any(LoadingPickOperationEntity.class));
|
||||
|
||||
service.claim(20L, new ClaimRequest(0, "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(0, "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(0, "claim-2"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(assignment.getVersion(), "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(assignment.getVersion(), "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(assignment.getVersion(), "claim-2"), 9L, "operator");
|
||||
|
||||
verify(smartLoadingRepository, times(2)).startPicking(10L, 9L, "operator");
|
||||
verify(smartLoadingRepository, times(1)).insert(argThat(
|
||||
@@ -585,7 +588,8 @@ class LoadingPickServiceTest {
|
||||
&& "EDITING".equals(history.getFromStatus())
|
||||
&& "LOADING".equals(history.getToStatus())
|
||||
&& "PDA-START-20".equals(history.getOperationId())));
|
||||
verify(repository, times(1)).createAssignment(20L, 9L, "operator", 9L, "operator", "CLAIMED");
|
||||
verify(repository, never()).createAssignment(anyLong(), anyLong(), anyString(), anyLong(),
|
||||
anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -606,6 +610,17 @@ class LoadingPickServiceTest {
|
||||
verify(smartLoadingRepository, never()).startPicking(anyLong(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void unassignedTaskCannotBeClaimedFromPda() {
|
||||
when(repository.taskForUpdate(20L)).thenReturn(task());
|
||||
|
||||
assertThatThrownBy(() -> service.claim(20L, new ClaimRequest(0, "claim-unassigned"),
|
||||
9L, "operator"))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("尚未指定作业员");
|
||||
verify(repository, never()).createAssignment(anyLong(), anyLong(), anyString(),
|
||||
anyLong(), anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void assignRechecksSameOperationAfterWaitingForTaskLock() {
|
||||
LoadingPickTaskEntity task = task();
|
||||
@@ -615,6 +630,8 @@ class LoadingPickServiceTest {
|
||||
when(repository.taskForUpdate(20L)).thenReturn(task);
|
||||
when(repository.task(20L)).thenReturn(task);
|
||||
when(repository.items(20L)).thenReturn(List.of());
|
||||
when(domesticPdaOperators.required(any(), eq(11L)))
|
||||
.thenReturn(ApiResponse.success(new DomesticPdaOperatorClient.Operator(11L, "picker")));
|
||||
|
||||
Task replay = service.assign(20L, new AssignRequest(11L, "picker", 0, "assign-race"),
|
||||
9L, "operator");
|
||||
|
||||
Reference in New Issue
Block a user