优化
This commit is contained in:
@@ -8,6 +8,7 @@ import com.baiyue.firstleg.dto.ContainerDtos.FullUpdateRequest;
|
||||
import com.baiyue.firstleg.dto.ContainerDtos.SaveRequest;
|
||||
import com.baiyue.firstleg.dto.ContainerDtos.SimulationCreateRequest;
|
||||
import com.baiyue.firstleg.dto.ContainerDtos.OceanBookingLinkRequest;
|
||||
import com.baiyue.firstleg.dto.ContainerDtos.OceanBookingUnlinkRequest;
|
||||
import com.baiyue.firstleg.dto.ContainerDtos.TransportUpdateRequest;
|
||||
import com.baiyue.firstleg.entity.ContainerBookingEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPlanEntity;
|
||||
@@ -32,12 +33,11 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
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.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
@@ -282,94 +282,83 @@ class ContainerServiceTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("首次关联允许已有预排货的编辑计划且保持内部柜和计划身份")
|
||||
void linksConfirmedBookingAfterPreloading() {
|
||||
void linksReleasedBookingAfterPreloading() {
|
||||
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");
|
||||
booking.setId(21L); booking.setStatus("RELEASED"); 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(repository.find(11L)).thenReturn(container, container);
|
||||
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);
|
||||
when(oceanBookings.allocations(21L)).thenReturn(List.of());
|
||||
when(repository.linkReleasedBooking(eq(11L), eq(21L), eq(31L), eq("MSCU7654321"),
|
||||
same(booking), eq(2), eq(9L), eq("admin"))).thenReturn(1);
|
||||
|
||||
ContainerBookingEntity result = service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2));
|
||||
ContainerBookingEntity result = service.linkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingLinkRequest(21L, 31L, "MSCU7654321", 2));
|
||||
|
||||
assertThat(result).isSameAs(container);
|
||||
assertThat(container.getCabinetNo()).isEqualTo("柜-001");
|
||||
verify(repository, never()).hasActiveLoadingItems(11L);
|
||||
verify(repository).consumeRealSource(41L, 11L, 9L, "admin");
|
||||
verify(repository).mergeRealSource(11L, 41L, "MSCU7654321", 2, 9L, "admin");
|
||||
verify(oceanBookings).reassignAllocation(41L, 11L);
|
||||
verify(repository).linkReleasedBooking(eq(11L), eq(21L), eq(31L), eq("MSCU7654321"),
|
||||
same(booking), eq(2), eq(9L), eq("admin"));
|
||||
verify(oceanBookings).insert(any(OceanBookingContainerAllocationEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("首次关联允许消费已放舱的真实订舱柜")
|
||||
void linksReleasedBooking() {
|
||||
@DisplayName("未发布订舱不可关联")
|
||||
void rejectsDraftBooking() {
|
||||
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");
|
||||
booking.setId(21L); booking.setStatus("DRAFT");
|
||||
when(repository.find(11L)).thenReturn(container);
|
||||
when(oceanBookings.find(21L)).thenReturn(booking);
|
||||
|
||||
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingLinkRequest(21L, 31L, "MSCU7654321", 2)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("已发布");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("订舱箱型需求达到数量上限时拒绝关联")
|
||||
void rejectsRequirementOverAllocation() {
|
||||
ContainerBookingEntity container = booking("WAIT_LOADING", 2);
|
||||
OceanBookingEntity booking = new OceanBookingEntity();
|
||||
booking.setId(21L); booking.setStatus("RELEASED");
|
||||
OceanBookingContainerRequirementEntity requirement = new OceanBookingContainerRequirementEntity();
|
||||
requirement.setId(31L); requirement.setContainerType("40HC");
|
||||
requirement.setCapacityCbm(new BigDecimal("76.0000")); requirement.setMaxWeightKg(new BigDecimal("28000.000"));
|
||||
requirement.setId(31L); requirement.setQuantity(1);
|
||||
OceanBookingContainerAllocationEntity allocation = new OceanBookingContainerAllocationEntity();
|
||||
allocation.setOceanBookingId(21L); allocation.setRequirementId(31L); allocation.setContainerBookingId(41L);
|
||||
allocation.setRequirementId(31L);
|
||||
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);
|
||||
when(oceanBookings.allocations(21L)).thenReturn(List.of(allocation));
|
||||
|
||||
service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2));
|
||||
|
||||
verify(oceanBookings).reassignAllocation(41L, 11L);
|
||||
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingLinkRequest(21L, 31L, "MSCU7654321", 2)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("数量上限");
|
||||
verify(repository, never()).linkReleasedBooking(anyLong(), anyLong(), anyLong(), anyString(),
|
||||
any(), anyInt(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@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);
|
||||
@DisplayName("完全空的模拟柜直接解绑并删除当前allocation,不依赖MERGED来源柜")
|
||||
void unlinksEmptySimulationDirectly() {
|
||||
ContainerBookingEntity linked = booking("WAIT_LOADING", 2);
|
||||
linked.setOceanBookingId(21L);
|
||||
ContainerBookingEntity detached = booking("WAIT_LOADING", 3);
|
||||
when(repository.find(11L)).thenReturn(linked, detached);
|
||||
when(repository.unlinkReleasedBooking(11L, 2, 9L, "admin")).thenReturn(1);
|
||||
|
||||
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingLinkRequest(41L, 2)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("已被消费");
|
||||
ContainerBookingEntity result = service.unlinkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingUnlinkRequest(2, "换绑"));
|
||||
|
||||
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);
|
||||
assertThat(result).isSameAs(detached);
|
||||
verify(repository).unlinkReleasedBooking(11L, 2, 9L, "admin");
|
||||
verify(oceanBookings).deleteAllocation(11L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -379,21 +368,12 @@ class ContainerServiceTest {
|
||||
when(repository.find(11L)).thenReturn(container);
|
||||
when(repository.hasEvidence(11L)).thenReturn(true);
|
||||
|
||||
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin", new OceanBookingLinkRequest(41L, 2)))
|
||||
assertThatThrownBy(() -> service.linkOceanBooking(11L, 9L, "admin",
|
||||
new OceanBookingLinkRequest(21L, 31L, "MSCU7654321", 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) {
|
||||
|
||||
Reference in New Issue
Block a user