This commit is contained in:
2026-08-10 09:11:57 +08:00
67 changed files with 3329 additions and 208 deletions
@@ -54,7 +54,7 @@ class InboundOrderControllerContractTest {
.contains("[WAIT_MEASURE, WAIT_REVIEW, WAIT_FEE_SEND, INBOUNDED]")
.contains("platform:firstleg:inbound:list")
.doesNotContain("WAIT_CUSTOMER_CONFIRM")
.contains("WAIT_SPLIT");
.doesNotContain("WAIT_SPLIT");
assertThat(inboundList).contains("#/components/schemas/InboundOrderPageEnvelope");
assertThat(taskList).doesNotContain("InboundOrderPageEnvelope");
}
@@ -38,7 +38,7 @@ class MerchantInboundBillingControllerContractTest {
String openapi = new ClassPathResource("openapi/firstleg-v1.yaml")
.getContentAsString(StandardCharsets.UTF_8);
assertThat(openapi).contains("/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing:")
.contains("仅 WAIT_SPLIT + APPROVED + CONFIRMED 的二期终态可见");
.contains("INBOUNDED + APPROVED + CONFIRMED");
}
@Test
@@ -11,18 +11,18 @@ import static org.assertj.core.api.Assertions.assertThat;
class InboundStatusUnificationSqlContractTest {
@Test
void preservesWaitSplitWithoutDataRewrite() throws Exception {
void preservesHistoricalWaitSplitWithoutDataRewrite() throws Exception {
String module = normalize(new ClassPathResource("db/phase3-inbounded-status-unification.sql")
.getContentAsString(StandardCharsets.UTF_8)).trim();
String unified = normalize(Files.readString(unifiedPath(), StandardCharsets.UTF_8));
assertThat(module)
.contains("CREATE PROCEDURE assert_wait_split_compatibility()")
.contains("WAIT_SPLIT 是二期当前有效终点")
.contains("CREATE PROCEDURE assert_inbounded_compatibility()")
.contains("二、三期对外统一使用 INBOUNDED")
.doesNotContain("UPDATE fl_inbound_order")
.doesNotContain("UPDATE fl_inbound_status_history");
assertThat(unified)
.contains("WAIT_SPLIT 是二期当前有效终点;统一迁移不得改写主表或历史状态")
.contains("二、三期对外统一使用 INBOUNDED")
.doesNotContain("SET process_status = 'INBOUNDED'")
.doesNotContain("SET from_status = 'INBOUNDED'")
.doesNotContain("SET to_status = 'INBOUNDED'");
@@ -37,7 +37,8 @@ class LoadingPickItemMapperContractTest {
@Test
void pdaWritesAndReadsRequireWarehouseScope() throws Exception {
Method list = LoadingPickItemMapper.class.getDeclaredMethod("selectTaskItemsWithAccount", long.class, long.class);
Method pick = LoadingPickItemMapper.class.getDeclaredMethod("pick", long.class, int.class, int.class, long.class);
Method pick = LoadingPickItemMapper.class.getDeclaredMethod("pick", long.class, int.class,
String.class, String.class, int.class, long.class);
assertThat(list.getAnnotation(Select.class).value()[0])
.contains("booking.warehouse_id = #{warehouseId}")
@@ -41,8 +41,8 @@ class InboundOrderQueryServiceTest {
}
@Test
void shouldAcceptCurrentPhase2TerminalStatusFilters() {
InboundOrderQuery query = new InboundOrderQuery(null, null, "WAIT_SPLIT", null,
void shouldAcceptInboundedAsThePhase2TerminalStatusFilter() {
InboundOrderQuery query = new InboundOrderQuery(null, null, "INBOUNDED", null,
"APPROVED", "CONFIRMED", null, null, null, null, null, null, null,
null, null, null, null, 1, 200);
PageResult<InboundOrderSummary> expected = new PageResult<>(List.of(), 1, 200, 0, 0);
@@ -1,23 +1,27 @@
package com.baiyue.firstleg.service;
import com.baiyue.firstleg.dto.LoadingPickDtos.PickRequest;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.dto.LoadingPickDtos.PartialPickRequest;
import com.baiyue.firstleg.dto.LoadingPickDtos.SkipRequest;
import com.baiyue.firstleg.dto.LoadingPickDtos.PickRequest;
import com.baiyue.firstleg.dto.LoadingPickDtos.ReviewRequest;
import com.baiyue.firstleg.entity.LoadingPickHistoryEntity;
import com.baiyue.firstleg.entity.LoadingPickOperationEntity;
import com.baiyue.firstleg.dto.LoadingPickDtos.SkipRequest;
import com.baiyue.firstleg.entity.LoadingPickAssignmentEntity;
import com.baiyue.firstleg.entity.LoadingPickHistoryEntity;
import com.baiyue.firstleg.entity.LoadingPickItemEntity;
import com.baiyue.firstleg.entity.LoadingPickOperationEntity;
import com.baiyue.firstleg.entity.LoadingPickTaskEntity;
import com.baiyue.firstleg.repository.LoadingPickRepository;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,6 +32,8 @@ class LoadingPickServiceTest {
private LoadingPickRepository repository;
@MockBean
private LoadingListService loadingListService;
@MockBean
private PdaPickSettlementService settlementService;
@Resource
private LoadingPickService service;
@@ -35,78 +41,77 @@ class LoadingPickServiceTest {
void keepsPlanLoadingWhenItemsRemain() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
when(repository.history("pick-1")).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.pick(30L, 2, 0, 101L)).thenReturn(1);
when(repository.allPlanItemsPicked(10L)).thenReturn(false);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
preparePick(task, item, "pick-1");
when(repository.allTaskItemsResolved(20L)).thenReturn(false);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-1"), 9L, "operator");
verify(repository).touchTask(20L, 0);
verify(repository).syncInboundProjections(20L, 9L, "operator");
verify(settlementService, never()).settle(20L, 9L, "operator");
verify(loadingListService, never()).finishFromPda(10L, 20L, 9L, "operator");
}
@Test
void completesPlanWhenLastItemIsPicked() {
void touchesTaskBeforeCompletingLastPickedItem() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
when(repository.history("pick-2")).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.pick(30L, 2, 0, 101L)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.touchTask(20L, 0)).thenReturn(1);
preparePick(task, item, "pick-2");
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-2"), 9L, "operator");
verify(loadingListService, never()).finishFromPda(10L, 20L, 9L, "operator");
InOrder order = inOrder(repository, settlementService, loadingListService);
order.verify(repository).touchTask(20L, 0);
order.verify(settlementService).settle(20L, 9L, "operator");
order.verify(loadingListService).finishFromPda(10L, 20L, 9L, "operator");
order.verify(repository).syncInboundProjections(20L, 9L, "operator");
verify(repository).insert(any(LoadingPickHistoryEntity.class));
}
@Test
void completesPlanWhenLastItemIsPartiallyPicked() {
void touchesTaskBeforeCompletingLastPartialItem() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
when(repository.history("partial-1")).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.partial(30L, 1, 0, 101L)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.touchTask(20L, 0)).thenReturn(1);
preparePartial(task, item, "partial-1");
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
service.partial(20L, 30L, new PartialPickRequest(101L, 1, List.of(), 0, "partial-1"), 9L, "operator");
service.partial(20L, 30L, new PartialPickRequest(101L, 1, List.of(), 0, "partial-1"),
9L, "operator");
verify(loadingListService, never()).finishFromPda(10L, 20L, 9L, "operator");
InOrder order = inOrder(repository, settlementService, loadingListService);
order.verify(repository).touchTask(20L, 0);
order.verify(settlementService).settle(20L, 9L, "operator");
order.verify(loadingListService).finishFromPda(10L, 20L, 9L, "operator");
order.verify(repository).syncInboundProjections(20L, 9L, "operator");
}
@Test
void completesPlanWhenLastItemIsSkipped() {
void rejectsSkipWhenInboundAlreadyHasPickedItem() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
LoadingPickItemEntity skipped = item();
LoadingPickItemEntity picked = item();
picked.setId(31L);
picked.setItemStatus("PICKED");
picked.setPickedPackageCount(2);
when(repository.history("skip-1")).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.skip(30L, 0, 101L)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.item(20L, 30L, 101L)).thenReturn(skipped);
when(repository.hasPickedOrPartialItem(20L, 50L)).thenReturn(true);
service.skip(20L, 30L, new SkipRequest(101L, 0, "skip-1", "fixture unavailable"), 9L, "operator");
assertThatThrownBy(() -> service.skip(20L, 30L,
new SkipRequest(101L, 0, "skip-1", "fixture unavailable"), 9L, "operator"))
.isInstanceOf(BizException.class);
verify(loadingListService, never()).finishFromPda(10L, 20L, 9L, "operator");
verify(repository, never()).skip(30L, 0, 101L);
verify(settlementService, never()).settle(20L, 9L, "operator");
}
@Test
void reviewSettlesPartialItemsBeforeCompletingPlan() {
void reviewSettlesResolvedItemsAndCompletesPlan() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
item.setPlannedPackageCount(5);
@@ -115,6 +120,7 @@ class LoadingPickServiceTest {
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.task(20L)).thenReturn(task);
when(repository.items(20L)).thenReturn(List.of(item));
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.settlePartial(40L, 30L, 3, 5, 9L, "operator")).thenReturn(1);
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
@@ -123,9 +129,32 @@ class LoadingPickServiceTest {
verify(repository).insert(any(LoadingPickOperationEntity.class));
verify(loadingListService).finishFromPda(10L, 20L, 9L, "operator");
verify(settlementService, never()).settle(20L, 9L, "operator");
verify(repository).syncInboundProjections(20L, 9L, "operator");
}
private void preparePick(LoadingPickTaskEntity task, LoadingPickItemEntity item, String operationId) {
when(repository.history(operationId)).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.pick(30L, 2, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
}
private void preparePartial(LoadingPickTaskEntity task, LoadingPickItemEntity item, String operationId) {
when(repository.history(operationId)).thenReturn(null);
when(repository.task(20L)).thenReturn(task);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.partial(30L, 1, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
}
private static LoadingPickTaskEntity task() {
LoadingPickTaskEntity task = new LoadingPickTaskEntity();
task.setId(20L);
@@ -36,7 +36,7 @@ class MerchantInboundBillingServiceTest {
@Test
void shouldHandleCase01() {
InboundOrderEntity inbound = inbound("WAIT_SPLIT", "APPROVED", "CONFIRMED");
InboundOrderEntity inbound = inbound("INBOUNDED", "APPROVED", "CONFIRMED");
InboundOrderDetail detail = new InboundOrderDetail(mock(com.baiyue.firstleg.dto.InboundOrderSummary.class),
"客户备注", List.of(), List.of(
new InboundOrderDetail.FileSummary(1L, "RELATED", "public.pdf", "PUBLIC", 1, 1L, null),
@@ -0,0 +1,206 @@
package com.baiyue.firstleg.service;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.firstleg.client.WarehousePalletLocationClient;
import com.baiyue.firstleg.entity.InboundPalletAllocationEntity;
import com.baiyue.firstleg.entity.LoadingPickItemEntity;
import com.baiyue.firstleg.mapper.InboundSplitSettlementMapper;
import com.baiyue.firstleg.mapper.InboundSplitSettlementMapper.MeasurementItemRow;
import com.baiyue.firstleg.mapper.InboundSplitSettlementMapper.ParentRow;
import com.baiyue.firstleg.repository.InboundPalletAllocationRepository;
import com.baiyue.firstleg.repository.LoadingPickRepository;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SpringJUnitConfig(PdaPickSettlementService.class)
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
class PdaPickSettlementServiceTest {
@MockBean private LoadingPickRepository picks;
@MockBean private InboundSplitSettlementMapper splits;
@MockBean private InboundPalletAllocationRepository allocations;
@MockBean private WarehousePalletLocationClient warehouse;
@Resource private PdaPickSettlementService service;
@Test
void createsChildForAllUnloadedPackagesAndTransfersRemainingAllocations() {
LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 10, 8, "PARTIAL");
resolved(List.of(item));
when(splits.lockParent(31L)).thenReturn(parent(20));
when(splits.childId(10001L, 31L)).thenReturn(null);
when(splits.lockLatestApprovedItemsForInbound(10001L, 31L))
.thenReturn(List.of(new MeasurementItemRow(51L, 61L, 41L, 20)));
when(allocations.lockConfirmed(10001L, 31L))
.thenReturn(List.of(allocation(1L, 1, 501L, 10), allocation(2L, 2, 502L, 10)));
when(warehouse.settle(eq("internal-token"), any())).thenReturn(ApiResponse.success(
new WarehousePalletLocationClient.SettlementResult(List.of(), List.of(
transfer(1, 501L, 2), transfer(2, 502L, 10)))));
writes(12, 8);
service.settle(1L, 9L, "operator");
verify(splits).cloneChild(eq(10001L), eq(31L), anyLong(), anyString(), eq(12), eq(9L), eq("operator"));
verify(splits).updateSourceMeasurementPackageCount(10001L, 31L, 61L, 8);
verify(splits).updateSourceMeasurementItemPackageCount(10001L, 61L, 51L, 8);
verify(allocations).consume(10001L, 31L, 1L, 8);
verify(warehouse).settle(eq("internal-token"), org.mockito.ArgumentMatchers.argThat(request ->
request.warehouseId() == 701L && request.sourceBusinessId() == 31L
&& request.idempotencyKey().equals("PDA-SETTLE-1-31")
&& request.releasedReservationIds().isEmpty()
&& request.remainingItems().equals(List.of(new WarehousePalletLocationClient.SettlementTransferItem(91L, 2),
new WarehousePalletLocationClient.SettlementTransferItem(92L, 10)))));
verify(allocations).copyRemainingToChild(eq(10001L), anyLong(), any());
verify(allocations).markTransferred(eq(10001L), eq(31L), any(), eq(List.of()));
verify(splits).convergePartialPlanItem(21L, 9L, "operator");
}
@Test
void repeatedSettleWithExistingChildDoesNotConsumeOrTransferAgain() {
LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 10, 6, "PARTIAL");
resolved(List.of(item));
when(splits.lockParent(31L)).thenReturn(parent(10));
when(splits.childId(10001L, 31L)).thenReturn(71L);
service.settle(1L, 9L, "operator");
verify(warehouse, never()).settle(anyString(), any());
verify(splits, never()).convergePartialPlanItem(anyLong(), anyLong(), anyString());
}
@Test
void releasesFullyPickedAllocationBeforeTransferringChildResources() {
LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 10, 10, "PICKED");
resolved(List.of(item));
when(splits.lockParent(31L)).thenReturn(parent(20));
when(splits.childId(10001L, 31L)).thenReturn(null);
when(splits.lockLatestApprovedItemsForInbound(10001L, 31L))
.thenReturn(List.of(new MeasurementItemRow(51L, 61L, 41L, 20)));
when(allocations.lockConfirmed(10001L, 31L))
.thenReturn(List.of(allocation(1L, 1, 501L, 10), allocation(2L, 2, 502L, 10)));
when(warehouse.settle(eq("internal-token"), any())).thenReturn(ApiResponse.success(
new WarehousePalletLocationClient.SettlementResult(List.of(released(91L, 501L)),
List.of(transfer(2, 502L, 10)))));
writes(10, 10);
service.settle(1L, 9L, "operator");
verify(warehouse).settle(eq("internal-token"), org.mockito.ArgumentMatchers.argThat(request ->
request.idempotencyKey().equals("PDA-SETTLE-1-31")
&& request.releasedReservationIds().equals(List.of(91L))
&& request.remainingItems().equals(List.of(new WarehousePalletLocationClient.SettlementTransferItem(92L, 10)))));
}
@Test
void fullyPickedInboundReleasesAllResourcesWithoutCreatingChild() {
LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 20, 20, "PICKED");
resolved(List.of(item));
when(splits.lockParent(31L)).thenReturn(parent(20));
when(splits.childId(10001L, 31L)).thenReturn(null);
when(allocations.lockConfirmed(10001L, 31L))
.thenReturn(List.of(allocation(1L, 1, 501L, 10), allocation(2L, 2, 502L, 10)));
when(warehouse.settle(eq("internal-token"), any())).thenReturn(ApiResponse.success(
new WarehousePalletLocationClient.SettlementResult(List.of(released(91L, 501L), released(92L, 502L)),
List.of())));
service.settle(1L, 9L, "operator");
verify(allocations).consume(10001L, 31L, 1L, 10);
verify(allocations).consume(10001L, 31L, 2L, 10);
verify(splits, never()).cloneChild(anyLong(), anyLong(), anyLong(), anyString(), anyInt(), anyLong(), anyString());
verify(warehouse).settle(eq("internal-token"), org.mockito.ArgumentMatchers.argThat(request ->
request.targetBusinessId() == 0L && request.targetPackageCount() == 0
&& request.releasedReservationIds().equals(List.of(91L, 92L))
&& request.remainingItems().isEmpty()));
}
@Test
void onlyPureSkippedInboundRestoresCandidate() {
LoadingPickItemEntity item = item(12L, 22L, 32L, 42L, 8, 0, "SKIPPED");
resolved(List.of(item));
when(splits.removeSkippedPlanItem(22L, 9L, "operator")).thenReturn(1);
service.settle(1L, 9L, "operator");
verify(splits).removeSkippedPlanItem(22L, 9L, "operator");
}
@Test
void mixedSkippedInboundIsNotRestored() {
LoadingPickItemEntity picked = item(11L, 21L, 31L, 41L, 8, 8, "PICKED");
LoadingPickItemEntity skipped = item(12L, 22L, 31L, 42L, 8, 0, "SKIPPED");
PdaPickSettlementPlan.Resolution resolution = PdaPickSettlementPlan.resolve(List.of(picked, skipped));
assertThat(resolution.skippedPlanItemIds()).isEmpty();
}
private void resolved(List<LoadingPickItemEntity> items) {
when(picks.allTaskItemsResolved(1L)).thenReturn(true);
when(picks.items(1L)).thenReturn(items);
}
private void writes(int childCount, int pickedCount) {
when(splits.cloneChild(eq(10001L), eq(31L), anyLong(), anyString(), eq(childCount), eq(9L), eq("operator")))
.thenReturn(1);
when(splits.insertBatch(anyLong(), eq(10001L), eq(31L), anyString(), anyString(), eq(3),
eq(childCount), anyString(), eq(9L), eq("operator"))).thenReturn(1);
when(splits.cloneMeasurement(eq(10001L), eq(31L), eq(61L), anyLong(), anyLong(), anyLong(),
eq(childCount), eq(9L))).thenReturn(1);
when(splits.insertSplitItem(anyLong(), eq(10001L), anyLong(), eq(31L), anyLong(), eq(1),
eq(41L), eq(61L), eq(51L), eq(childCount))).thenReturn(1);
when(splits.cloneMeasurementItem(eq(10001L), eq(61L), eq(51L), anyLong(), anyLong(), anyLong(),
eq(1), eq(childCount))).thenReturn(1);
when(splits.updateSourceMeasurementPackageCount(10001L, 31L, 61L, pickedCount)).thenReturn(1);
when(splits.updateSourceMeasurementItemPackageCount(10001L, 61L, 51L, pickedCount)).thenReturn(1);
when(splits.markParentPartiallySplit(10001L, 31L, childCount, 9L, 3)).thenReturn(1);
when(splits.applyBatch(eq(10001L), anyLong())).thenReturn(1);
when(splits.insertHistory(anyLong(), eq(10001L), anyLong(), anyString(), anyString(), eq(9L),
eq("operator"), anyString())).thenReturn(1);
when(splits.convergePartialPlanItem(21L, 9L, "operator")).thenReturn(1);
}
private static ParentRow parent(int packageCount) {
return new ParentRow(31L, 10001L, "IN-001", "MASTER", "INBOUNDED", packageCount, packageCount, 3);
}
private static InboundPalletAllocationEntity allocation(long id, int no, long locationId, int allocated) {
InboundPalletAllocationEntity value = new InboundPalletAllocationEntity();
value.setId(id); value.setAllocationNo(no); value.setLocationId(locationId); value.setWarehouseId(701L);
value.setReservationId(90L + no);
value.setAllocatedPackageCount(allocated); value.setPickedPackageCount(0);
return value;
}
private static WarehousePalletLocationClient.TransferResult transfer(int no, long locationId, int remaining) {
return new WarehousePalletLocationClient.TransferResult(90L + no, "RES-" + no, 92L + no, no,
0L, 701L, 801L + no, "PALLET-" + no, null, locationId, "L-" + no, null, remaining, "OCCUPIED");
}
private static WarehousePalletLocationClient.SelectiveReleaseResult released(long reservationId, long locationId) {
return new WarehousePalletLocationClient.SelectiveReleaseResult(reservationId, 92L, 1, 801L,
locationId, "L-1", 10);
}
private static LoadingPickItemEntity item(long id, long planItemId, long inboundId, long detailId,
int planned, int picked, String status) {
LoadingPickItemEntity value = new LoadingPickItemEntity();
value.setId(id); value.setLoadingPlanItemId(planItemId); value.setInboundId(inboundId);
value.setInboundDetailId(detailId); value.setPlannedPackageCount(planned);
value.setPickedPackageCount(picked); value.setItemStatus(status);
return value;
}
}
@@ -31,7 +31,7 @@ class UnifiedInboundQueryServiceTest {
assertThat(UnifiedInboundQueryService.mainStatus("WAIT_PRICING")).isEqualTo("INBOUNDED");
assertThat(UnifiedInboundQueryService.mainStatus("FEE_CONFIRMING")).isEqualTo("INBOUNDED");
assertThat(UnifiedInboundQueryService.mainStatus("INBOUNDING")).isEqualTo("INBOUNDED");
assertThat(UnifiedInboundQueryService.mainStatus("WAIT_SPLIT")).isEqualTo("WAIT_SPLIT");
assertThat(UnifiedInboundQueryService.mainStatus("WAIT_SPLIT")).isEqualTo("INBOUNDED");
assertThat(UnifiedInboundQueryService.mainStatus("INBOUNDED")).isEqualTo("INBOUNDED");
assertThat(UnifiedInboundQueryService.mainStatus("LOADING")).isEqualTo("LOADING");
assertThat(UnifiedInboundQueryService.mainStatus("LOADED")).isEqualTo("LOADED");
@@ -51,29 +51,27 @@ class UnifiedInboundQueryServiceTest {
assertThat(UnifiedInboundQueryService.nextAction("INBOUNDED", "INBOUNDING", null)).isNull();
assertThat(UnifiedInboundQueryService.nextAction("INBOUNDED", "INBOUNDED", "CONFIRMED")).isNull();
assertThat(UnifiedInboundQueryService.nextAction("INBOUNDED", "WAIT_SPLIT", null))
.isNull();
assertThat(UnifiedInboundQueryService.nextAction("WAIT_SPLIT", "WAIT_SPLIT", null)).isNull();
.isEqualTo("SMART_SPLIT");
assertThat(UnifiedInboundQueryService.nextAction("LOADED", "LOADED", null))
.isEqualTo("COMPLETE_DELIVERY");
assertThat(UnifiedInboundQueryService.nextAction("DELIVERED", "DELIVERED", null)).isNull();
}
@Test
void waitSplitFilterRemainsSeparateFromInbounded() throws Exception {
void inboundedFilterIncludesHistoricalWaitSplitRows() throws Exception {
var method = UnifiedInboundQueryService.class.getDeclaredMethod("internalStatuses", String.class);
method.setAccessible(true);
assertThat(method.invoke(new UnifiedInboundQueryService(), "WAIT_SPLIT"))
.isEqualTo(java.util.List.of("WAIT_SPLIT"));
assertThat(method.invoke(new UnifiedInboundQueryService(), "INBOUNDED"))
.isEqualTo(java.util.List.of("WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING", "INBOUNDED"));
.isEqualTo(java.util.List.of("WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING", "INBOUNDED", "WAIT_SPLIT"));
assertThat(method.invoke(new UnifiedInboundQueryService(), "WAIT_SPLIT"))
.isEqualTo(java.util.List.of("WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING", "INBOUNDED", "WAIT_SPLIT"));
}
@Test
void phaseTwoMeasurementStatusesDoNotRequireUndeployedPhaseThreeTables() {
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("WAIT_MEASURE")).isFalse();
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("INBOUNDED")).isFalse();
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("WAIT_SPLIT")).isFalse();
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("LOADING")).isTrue();
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("LOADED")).isTrue();
assertThat(UnifiedInboundQueryService.requiresPhaseThreeSummary("DELIVERED")).isTrue();