fix: allocate pallet locations on weight confirmation
This commit is contained in:
+16
@@ -98,6 +98,22 @@ class InternalPalletLocationControllerTest {
|
||||
.isEqualTo(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void expandsWholeBlockOnlyForInternalCaller() {
|
||||
LocationBlockDtos.ExpandRequest request = new LocationBlockDtos.ExpandRequest(
|
||||
700L, 88L, 4, "expand-block-1", 9001L);
|
||||
LocationBlockDtos.BlockResult expected = new LocationBlockDtos.BlockResult(700L, "OCCUPIED", List.of(
|
||||
new LocationBlockDtos.Resource(700L, 704L, 43L, "A04", 4, false, "OCCUPIED")));
|
||||
when(blockService.expand(request)).thenReturn(expected);
|
||||
|
||||
assertThat(controller.expandBlock(INTERNAL_TOKEN, request).data()).isEqualTo(expected);
|
||||
verify(blockService).expand(request);
|
||||
assertThatThrownBy(() -> controller.expandBlock("invalid", request))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
private static PalletAllocationDtos.TransferRequest request() {
|
||||
return new PalletAllocationDtos.TransferRequest(10001L, "FIRSTLEG", 88L, 89L,
|
||||
"RK-001-S1", "transfer-88-89", 9001L, List.of(new PalletAllocationDtos.TransferItem(40L, 5)));
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.baiyue.warehouse.controller;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class LocationBlockOpenApiContractTest {
|
||||
@Test
|
||||
void publishesAtomicExpansionWithoutShrinkOrReplacementFields() throws Exception {
|
||||
String yaml = Files.readString(Path.of("src/main/resources/openapi/location-block-v1.yaml"));
|
||||
|
||||
assertThat(yaml)
|
||||
.contains("/internal/warehouse/v1/pallet-locations/blocks/expand:")
|
||||
.contains("required: [blockId, businessId, requiredSlotCount, idempotencyKey, operatorId]")
|
||||
.contains("requiredSlotCount: { type: integer, minimum: 1, maximum: 200 }")
|
||||
.contains("保留原资源标识")
|
||||
.contains("缺口共享A0")
|
||||
.doesNotContain("replacementBlockId")
|
||||
.doesNotContain("releaseSlotNos");
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
@@ -122,6 +123,59 @@ class LocationBlockServiceTest {
|
||||
verify(locations, never()).lockOwned(0L, 20L, 99L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void expandsOccupiedBlockWithAdjacentLocationThenA0WithoutChangingExistingSlots() {
|
||||
LocationBlockEntity block = block("OCCUPIED", 88L, null);
|
||||
LocationBlockSlotEntity first = slot(701L, 1, 1L, "A01", false, "OCCUPIED");
|
||||
LocationBlockSlotEntity second = slot(702L, 2, 2L, "A02", false, "OCCUPIED");
|
||||
LocationEntity overflow = location(99L, "OVERFLOW", "A0");
|
||||
overflow.setSharedOverflow(true);
|
||||
when(blocks.lockById(700L)).thenReturn(block);
|
||||
when(slots.lockByBlockId(700L)).thenReturn(List.of(first, second));
|
||||
when(locations.lockOwned(0L, 20L, 2L)).thenReturn(location(2L, "A", "A02", "OCCUPIED"));
|
||||
when(locations.lockAvailable(0L, 20L, 1000)).thenReturn(List.of(
|
||||
location(3L, "A", "A03"), location(5L, "A", "A05"), location(20L, "B", "B01")));
|
||||
when(locations.lockOrCreateSharedOverflow(0L, 20L, 9001L)).thenReturn(overflow);
|
||||
when(blocks.expand(700L, 88L, 2, 5, "expand-1", 0)).thenReturn(1);
|
||||
|
||||
LocationBlockDtos.BlockResult result = service.expand(
|
||||
new LocationBlockDtos.ExpandRequest(700L, 88L, 5, "expand-1", 9001L));
|
||||
|
||||
assertThat(result.blockId()).isEqualTo(700L);
|
||||
assertThat(result.blockStatus()).isEqualTo("OCCUPIED");
|
||||
assertThat(result.resources()).extracting(LocationBlockDtos.Resource::reservationId)
|
||||
.startsWith(701L, 702L);
|
||||
assertThat(result.resources()).extracting(LocationBlockDtos.Resource::locationCode)
|
||||
.containsExactly("A01", "A02", "A03", "A0", "A0");
|
||||
assertThat(result.resources()).extracting(LocationBlockDtos.Resource::slotNo)
|
||||
.containsExactly(1, 2, 3, 4, 5);
|
||||
assertThat(result.resources()).extracting(LocationBlockDtos.Resource::resourceStatus)
|
||||
.containsOnly("OCCUPIED");
|
||||
verify(locations).changeStatus(0L, 20L, 3L, "AVAILABLE", "OCCUPIED", 0, 9001L);
|
||||
verify(locations, never()).changeStatus(eq(0L), eq(20L), eq(5L), any(), any(), anyInt(), anyLong());
|
||||
verify(blocks).expand(700L, 88L, 2, 5, "expand-1", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaysSameExpansionAndRejectsShrink() {
|
||||
LocationBlockEntity replay = block("RESERVED", 88L, "expand-1");
|
||||
replay.setSlotCount(3);
|
||||
List<LocationBlockSlotEntity> expanded = List.of(
|
||||
slot(701L, 1, 1L, "A01", false, "RESERVED"),
|
||||
slot(702L, 2, 2L, "A02", false, "RESERVED"),
|
||||
slot(703L, 3, 3L, "A03", false, "RESERVED"));
|
||||
when(blocks.lockById(700L)).thenReturn(replay);
|
||||
when(slots.lockByBlockId(700L)).thenReturn(expanded);
|
||||
|
||||
assertThat(service.expand(new LocationBlockDtos.ExpandRequest(700L, 88L, 3, "expand-1", 9001L))
|
||||
.resources()).hasSize(3);
|
||||
assertThatThrownBy(() -> service.expand(
|
||||
new LocationBlockDtos.ExpandRequest(700L, 88L, 2, "expand-2", 9001L)))
|
||||
.isInstanceOf(com.baiyue.common.core.exception.BizException.class)
|
||||
.hasMessageContaining("不允许缩容");
|
||||
verify(blocks, never()).expand(anyLong(), anyLong(), anyInt(), anyInt(), any(), anyInt());
|
||||
}
|
||||
|
||||
private static LocationBlockDtos.ReserveRequest request(int slots) {
|
||||
return new LocationBlockDtos.ReserveRequest(20L, "firstleg-service", 88L, "RK-001", slots,
|
||||
"reserve-1", 9001L, LocalDateTime.now().plusHours(1));
|
||||
|
||||
Reference in New Issue
Block a user