This commit is contained in:
2026-08-17 13:24:48 +08:00
parent ac6cf9c904
commit 6739c83467
43 changed files with 1049 additions and 315 deletions
@@ -20,6 +20,7 @@ import com.baiyue.firstleg.repository.PriceBookQueryRepository;
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerAllocationEntity;
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerRequirementEntity;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.DisplayName;
@@ -285,23 +286,90 @@ class ContainerServiceTest {
ContainerBookingEntity container = booking("EDITING", 2);
container.setWarehouseId(101L); container.setChannelCode("SEA-US"); container.setContainerType("40HC");
container.setCapacityCbm(new BigDecimal("76.0000")); container.setMaxWeightKg(new BigDecimal("28000.000"));
ContainerBookingEntity realContainer = realContainer(41L, 21L, 31L);
OceanBookingEntity booking = new OceanBookingEntity();
booking.setId(21L); booking.setStatus("CONFIRMED"); booking.setWarehouseId(101L); booking.setChannelCode("SEA-US");
OceanBookingContainerRequirementEntity requirement = new OceanBookingContainerRequirementEntity();
requirement.setId(31L); requirement.setQuantity(1); requirement.setContainerType("40HC"); requirement.setCapacityCbm(new BigDecimal("76.0000")); requirement.setMaxWeightKg(new BigDecimal("28000.000"));
OceanBookingContainerAllocationEntity allocation = new OceanBookingContainerAllocationEntity();
allocation.setOceanBookingId(21L); allocation.setRequirementId(31L); allocation.setContainerBookingId(41L);
when(repository.find(11L)).thenReturn(container);
when(repository.findForUpdate(41L)).thenReturn(realContainer);
when(oceanBookings.find(21L)).thenReturn(booking);
when(oceanBookings.requirement(21L, 31L)).thenReturn(requirement);
when(oceanBookings.allocations(21L)).thenReturn(java.util.List.of());
when(repository.updateLink(any(), org.mockito.ArgumentMatchers.eq(2), org.mockito.ArgumentMatchers.eq(9L), org.mockito.ArgumentMatchers.eq("admin"))).thenReturn(1);
when(oceanBookings.allocationByContainer(41L)).thenReturn(allocation);
when(repository.consumeRealSource(41L, 11L, 9L, "admin")).thenReturn(1);
when(repository.mergeRealSource(11L, 41L, "MSCU7654321", 2, 9L, "admin")).thenReturn(1);
when(oceanBookings.reassignAllocation(41L, 11L)).thenReturn(1);
ContainerBookingEntity result = service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(21L, 31L, 2));
ContainerBookingEntity result = service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2));
assertThat(result).isSameAs(container);
assertThat(container.getCabinetNo()).isEqualTo("柜-001");
assertThat(container.getOceanBookingId()).isEqualTo(21L);
verify(repository, never()).hasActiveLoadingItems(11L);
verify(oceanBookings).insert(any(com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerAllocationEntity.class));
verify(repository).consumeRealSource(41L, 11L, 9L, "admin");
verify(repository).mergeRealSource(11L, 41L, "MSCU7654321", 2, 9L, "admin");
verify(oceanBookings).reassignAllocation(41L, 11L);
}
@Test
@DisplayName("首次关联允许消费已放舱的真实订舱柜")
void linksReleasedBooking() {
ContainerBookingEntity container = booking("WAIT_LOADING", 2);
container.setWarehouseId(101L); container.setChannelCode("SEA-US"); container.setContainerType("40HC");
container.setCapacityCbm(new BigDecimal("76.0000")); container.setMaxWeightKg(new BigDecimal("28000.000"));
ContainerBookingEntity realContainer = realContainer(41L, 21L, 31L);
OceanBookingEntity booking = new OceanBookingEntity();
booking.setId(21L); booking.setStatus("RELEASED"); booking.setWarehouseId(101L); booking.setChannelCode("SEA-US");
OceanBookingContainerRequirementEntity requirement = new OceanBookingContainerRequirementEntity();
requirement.setId(31L); requirement.setContainerType("40HC");
requirement.setCapacityCbm(new BigDecimal("76.0000")); requirement.setMaxWeightKg(new BigDecimal("28000.000"));
OceanBookingContainerAllocationEntity allocation = new OceanBookingContainerAllocationEntity();
allocation.setOceanBookingId(21L); allocation.setRequirementId(31L); allocation.setContainerBookingId(41L);
when(repository.find(11L)).thenReturn(container);
when(repository.findForUpdate(41L)).thenReturn(realContainer);
when(oceanBookings.find(21L)).thenReturn(booking);
when(oceanBookings.requirement(21L, 31L)).thenReturn(requirement);
when(oceanBookings.allocationByContainer(41L)).thenReturn(allocation);
when(repository.consumeRealSource(41L, 11L, 9L, "admin")).thenReturn(1);
when(repository.mergeRealSource(11L, 41L, "MSCU7654321", 2, 9L, "admin")).thenReturn(1);
when(oceanBookings.reassignAllocation(41L, 11L)).thenReturn(1);
service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2));
verify(oceanBookings).reassignAllocation(41L, 11L);
}
@Test
@DisplayName("已合并的真实订舱柜不可再次关联")
void rejectsConsumedRealContainer() {
ContainerBookingEntity container = booking("WAIT_LOADING", 2);
ContainerBookingEntity consumed = realContainer(41L, 21L, 31L);
consumed.setRecordStatus("MERGED"); consumed.setMergedIntoContainerBookingId(99L);
when(repository.find(11L)).thenReturn(container);
when(repository.findForUpdate(41L)).thenReturn(consumed);
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
new OceanBookingLinkRequest(41L, 2)))
.isInstanceOf(BizException.class).hasMessageContaining("已被消费");
verifyNoInteractions(oceanBookings);
}
@Test
@DisplayName("已有装柜计划的真实订舱柜不可被模拟柜消费")
void rejectsRealContainerWithLoadingPlan() {
ContainerBookingEntity container = booking("WAIT_LOADING", 2);
ContainerBookingEntity realContainer = realContainer(41L, 21L, 31L);
when(repository.find(11L)).thenReturn(container);
when(repository.findForUpdate(41L)).thenReturn(realContainer);
when(repository.hasLoadingPlan(41L)).thenReturn(true);
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
new OceanBookingLinkRequest(41L, 2)))
.isInstanceOf(BizException.class).hasMessageContaining("已有装柜计划");
verifyNoInteractions(oceanBookings);
}
@Test
@@ -311,11 +379,21 @@ class ContainerServiceTest {
when(repository.find(11L)).thenReturn(container);
when(repository.hasEvidence(11L)).thenReturn(true);
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(21L, 31L, 2)))
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2)))
.isInstanceOf(BizException.class).hasMessageContaining("证据");
verifyNoInteractions(oceanBookings);
}
private static ContainerBookingEntity realContainer(long id, long oceanBookingId, long requirementId) {
ContainerBookingEntity value = new ContainerBookingEntity();
value.setId(id); value.setContainerNo("MSCU7654321"); value.setCabinetNo("CAB-REAL");
value.setSourceType("OCEAN_BOOKING"); value.setRecordStatus("ACTIVE");
value.setOceanBookingId(oceanBookingId); value.setOceanBookingRequirementId(requirementId);
value.setWarehouseId(101L); value.setChannelCode("SEA-US"); value.setContainerType("40HC");
value.setCapacityCbm(new BigDecimal("76.0000")); value.setMaxWeightKg(new BigDecimal("28000.000"));
return value;
}
private static ApiResponse<WarehouseMasterDataClient.Detail> activeWarehouse(long warehouseId,
String type,
String name) {