This commit is contained in:
2026-08-17 12:31:24 +08:00
parent 8566c6ea9e
commit ac6cf9c904
23 changed files with 396 additions and 58 deletions
@@ -28,8 +28,13 @@ class InitialWarehouseResourceSeedSqlContractTest {
private static void assertSeed(String sql, String yiwuId, String dongguanId, String idPrefix) {
assertThat(sql)
.contains("0," + yiwuId + ",'TP-001'")
.contains("0," + dongguanId + ",'TP-002'")
.contains("0," + yiwuId + ",'TP-001','木托盘'")
.contains("0," + dongguanId + ",'TP-002','塑料托盘'")
.contains("0," + yiwuId + ",'YW-TP-002','塑料托盘'")
.contains("0," + dongguanId + ",'DG-TP-002','木托盘'")
.contains("COUNT(DISTINCT pallet.pallet_type)")
.contains("国内作业仓木托盘、塑料托盘初始化不完整")
.doesNotContain("'胶托盘'")
.contains("WHEN zones.zone_index = 0 AND slots.slot_number = 1 THEN 201")
.contains("ELSE 203 + zones.zone_index * 15 + slots.slot_number")
.contains("SELECT zone_index + 1 FROM zones WHERE zone_index < 5")
@@ -72,6 +72,43 @@ class LocationResourceServiceTest {
});
}
@Test
void preservesZeroPackageOccupiedResourceForImageBasedAllocation() {
LocationOccupancyEntity active = occupancy(201L, 101L, 9L, "A1", 501L);
active.setAllocatedPackageCount(0);
when(repository.findOccupanciesByBusiness(10001L, "FIRSTLEG", 301L)).thenReturn(List.of(active));
assertThat(service.findOccupiedResources(10001L, "FIRSTLEG", 301L)).singleElement()
.extracting(item -> item.allocatedPackageCount()).isEqualTo(0);
}
@Test
void rejectsReplayWhenConfirmedImageReferencesChanged() {
LocationReservationEntity reservation = reservation("RESERVED");
reservation.setIdempotencyKey("measure-001:7001");
when(repository.findReservationsByBusiness(10001L, "FIRSTLEG", 301L))
.thenReturn(List.of(reservation));
assertThatThrownBy(() -> service.requireSameActiveReservations(10001L, 88L, "FIRSTLEG", 301L,
"measure-001", List.of(new com.baiyue.warehouse.dto.PalletAllocationDtos.PalletReference(7002L, 501L))))
.isInstanceOf(com.baiyue.common.core.exception.BizException.class);
}
@Test
void allowsReplayWhenMultipleImagesReuseSamePalletMaster() {
LocationReservationEntity first = reservation("RESERVED");
first.setIdempotencyKey("measure-001:7001");
LocationReservationEntity second = reservation("RESERVED");
second.setId(102L);
second.setIdempotencyKey("measure-001:7002");
when(repository.findReservationsByBusiness(10001L, "FIRSTLEG", 301L))
.thenReturn(List.of(first, second));
service.requireSameActiveReservations(10001L, 88L, "FIRSTLEG", 301L, "measure-001", List.of(
new com.baiyue.warehouse.dto.PalletAllocationDtos.PalletReference(7001L, 501L),
new com.baiyue.warehouse.dto.PalletAllocationDtos.PalletReference(7002L, 501L)));
}
@Test
void shouldHandleCase01() {
when(repository.findWarehouse(10001L, 88L)).thenReturn(warehouse());
@@ -257,6 +294,22 @@ class LocationResourceServiceTest {
verify(repository, never()).releaseOccupancy(first, "PDA full pick");
}
@Test
void shouldReleaseZeroPackageLocationCreatedForConfirmedImage() {
LocationOccupancyEntity occupancy = occupancy(201L, 101L, 9L, "A1", 501L);
occupancy.setAllocatedPackageCount(0);
when(repository.lockOccupiedByBusiness(10001L, "FIRSTLEG", 301L)).thenReturn(List.of(occupancy));
when(repository.findOwned(10001L, 88L, 9L)).thenReturn(occupiedLocation(9L, "A1"));
when(repository.releaseOccupancy(occupancy, "PDA full pick")).thenReturn(1);
when(repository.changeStatus(10001L, 88L, 9L, "OCCUPIED", "AVAILABLE", 0, 7L)).thenReturn(1);
var result = service.releaseSelectedExactly(new com.baiyue.warehouse.dto.LocationDtos.ExactSelectiveReleaseCommand(
10001L, "FIRSTLEG", 301L, 7L, "PDA full pick", List.of(9L)));
assertThat(result).singleElement()
.extracting(item -> item.allocatedPackageCount()).isEqualTo(0);
}
@Test
void shouldReleasePublicResourcesInAllocationOrderWhenLocationsAreNotSpecified() {
LocationOccupancyEntity allocationThree = occupancy(203L, 103L, 11L, "A3", 503L);
@@ -122,6 +122,7 @@ class PalletLocationAllocationServiceTest {
LocationDtos.ActiveResource resource = new LocationDtos.ActiveResource(
101, null, 20, 30, "TP-001", 40, "A-01", false, "RESERVED");
when(locations.findActiveResources(10001, "FIRSTLEG", 88)).thenReturn(List.of(resource));
when(pallets.findOwnedIncludingDeleted(10001, 20, 30)).thenReturn(pallet(30, "TP-001"));
var result = service.reserve(reserve(88));
@@ -130,6 +131,26 @@ class PalletLocationAllocationServiceTest {
verify(pallets, never()).findOwned(anyLong(), anyLong(), anyLong());
}
@Test
void validatesConfirmedImageReferencesBeforeReplayingAllocation() {
LocationDtos.ActiveResource resource = new LocationDtos.ActiveResource(
101L, null, 20L, 30L, "TP-001", 40L, "A-01", false, "RESERVED");
when(locations.findActiveResources(10001L, "FIRSTLEG", 88L)).thenReturn(List.of(resource));
when(pallets.findOwnedIncludingDeleted(10001L, 20L, 30L)).thenReturn(pallet(30L, "TP-001"));
service.reserve(reserve(88L));
org.mockito.ArgumentCaptor<List<PalletAllocationDtos.PalletReference>> targets =
org.mockito.ArgumentCaptor.forClass(List.class);
verify(locations).requireSameActiveReservations(eq(10001L), eq(20L), eq("FIRSTLEG"), eq(88L),
eq("measure-001"), targets.capture());
assertThat(targets.getValue()).singleElement().satisfies(item -> {
assertThat(item.weightResultId()).isEqualTo(7001L);
assertThat(item.palletId()).isEqualTo(30L);
});
verify(locations, never()).reserveAvailable(any());
}
@Test
void confirmPersistsPackageCountOnEveryOccupancyTarget() {
LocationDtos.ActiveResource resource = new LocationDtos.ActiveResource(