装柜修改

This commit is contained in:
2026-08-10 20:52:46 +08:00
parent 4630186a56
commit e915086133
6 changed files with 133 additions and 70 deletions
@@ -39,8 +39,10 @@ class ContainerBookingMapperContractTest {
.reduce("", (left, right) -> left + "\n" + right);
assertThat(allSql)
.contains("capacity_cbm")
.contains("p.plan_status<>'EDITING'")
.contains("p.plan_status!='EDITING'")
.contains("p.plan_status='COMPLETED'")
.contains("version=#{expectedVersion}");
.contains("version=#{expectedVersion}")
.doesNotContain("<")
.doesNotContain(">");
}
}
@@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -77,6 +78,28 @@ class SmartLoadingServiceTest {
assertThat(service.detail(1L).bookingId()).isEqualTo(99L);
}
@Test
void restoresLoadingPlanForContinuedAssignment() {
LoadingPlanEntity plan = plan("LOADING", 3);
when(repository.booking(99L)).thenReturn(booking());
when(repository.planByBooking(99L)).thenReturn(plan);
when(repository.items(1L)).thenReturn(List.of());
assertThat(service.draftByBooking(99L).status()).isEqualTo("LOADING");
}
@Test
void doesNotRestoreCompletedPlanInTheLoadingWorkbench() {
when(repository.booking(99L)).thenReturn(booking());
when(repository.planByBooking(99L)).thenReturn(plan("COMPLETED", 4));
BizException error = catchThrowableOfType(
() -> service.draftByBooking(99L), BizException.class);
assertThat(error.getResultCode()).isEqualTo(ResultCode.CONFLICT);
verify(repository, never()).items(anyLong());
}
@Test
void returnsExistingDraftOnCreate() {
LoadingPlanEntity plan = plan("EDITING", 2);
@@ -105,6 +128,35 @@ class SmartLoadingServiceTest {
verify(repository, never()).touch(anyLong(), anyInt(), anyLong(), any());
}
@Test
void allowsVolumeAndWeightWithinOneHundredTenPercent() {
stubAssignment();
ContainerBookingEntity tolerant = booking();
tolerant.setCapacityCbm(new BigDecimal("0.91"));
tolerant.setMaxWeightKg(new BigDecimal("3.64"));
when(repository.booking(99L)).thenReturn(tolerant);
service.assign(1, new AssignRequest(10L, 20L, 2, 0, "assign-110-ok"), 7, "u");
verify(repository).touch(1, 0, 7, "u");
}
@Test
void rejectsVolumeOrWeightAboveOneHundredTenPercent() {
stubAssignment();
ContainerBookingEntity exceeded = booking();
exceeded.setCapacityCbm(new BigDecimal("0.90"));
exceeded.setMaxWeightKg(new BigDecimal("3.63"));
when(repository.booking(99L)).thenReturn(exceeded);
BizException error = catchThrowableOfType(() -> service.assign(1,
new AssignRequest(10L, 20L, 2, 0, "assign-110-exceeded"), 7, "u"), BizException.class);
assertThat(error.getResultCode()).isEqualTo(ResultCode.VALIDATION_FAILED);
assertThat(error.getMessage()).contains("110%");
verify(repository, never()).touch(anyLong(), anyInt(), anyLong(), any());
}
@Test
void snapshotsCargoFields() {
stubAssignment();
@@ -296,6 +348,46 @@ class SmartLoadingServiceTest {
verify(repository).push(1, "key", 3, 7, "u");
}
@Test
void rejectsOverweightPlanBeforePushEvenWithoutContainerNumber() {
LoadingPlanEntity editing = plan("EDITING", 1);
ContainerBookingEntity booking = booking();
booking.setContainerNo(null);
booking.setMaxWeightKg(new BigDecimal("1"));
LoadingPlanItemEntity overweight = item(8, 9, 20, 1);
overweight.setGrossWeightKg(new BigDecimal("2"));
when(repository.plan(1)).thenReturn(editing);
when(repository.booking(99)).thenReturn(booking);
when(repository.items(1)).thenReturn(List.of(overweight));
BizException error = catchThrowableOfType(
() -> service.pushPreload(1, "weight-key", new PushRequest(1), 7, "u"),
BizException.class);
assertThat(error.getResultCode()).isEqualTo(ResultCode.VALIDATION_FAILED);
assertThat(error.getMessage()).contains("重量").contains("110%");
verify(repository, never()).push(anyLong(), anyString(), anyInt(), anyLong(), anyString());
verify(loadingPickService, never()).begin(anyLong(), any(), anyLong(), anyString(), anyList());
}
@Test
void pushesWithoutContainerNumberWhenCapacityIsWithinLimit() {
LoadingPlanEntity editing = plan("EDITING", 1);
LoadingPlanEntity pushed = plan("LOADING", 2);
ContainerBookingEntity booking = booking();
booking.setContainerNo(null);
when(repository.plan(1)).thenReturn(editing, pushed);
when(repository.booking(99)).thenReturn(booking);
when(repository.items(1)).thenReturn(List.of(item(8, 9, 20, 1)));
when(repository.push(1, "no-container-key", 1, 7, "u")).thenReturn(1);
Plan result = service.pushPreload(1, "no-container-key", new PushRequest(1), 7, "u");
assertThat(result.status()).isEqualTo("LOADING");
verify(repository).push(1, "no-container-key", 1, 7, "u");
verify(loadingPickService, never()).begin(anyLong(), any(), anyLong(), anyString(), anyList());
}
private void stubAssignment() {
LoadingPlanEntity plan = plan("EDITING", 0);
when(repository.plan(1)).thenReturn(plan, plan("EDITING", 1));