fix(firstleg): persist ocean container allocation
This commit is contained in:
+6
-2
@@ -167,7 +167,11 @@ public class OceanBookingService {
|
||||
String action = "ALLOCATE_CONTAINER";
|
||||
Detail replay = claimOrReplay(id, operatorId, action, key, hash(action, id, request));
|
||||
if (replay != null) return replay;
|
||||
requiredVersion(id, request.expectedVersion());
|
||||
OceanBookingEntity booking = requiredVersion(id, request.expectedVersion());
|
||||
if (!Set.of(OceanBookingStatus.SUBMITTED.name(), OceanBookingStatus.CONFIRMED.name(),
|
||||
OceanBookingStatus.CHANGE_PENDING.name()).contains(booking.getStatus())) {
|
||||
throw conflict("当前订舱状态不可分配柜次");
|
||||
}
|
||||
OceanBookingContainerRequirementEntity requirement = repository.requirement(id, request.requirementId());
|
||||
if (requirement == null) throw new BizException(ResultCode.NOT_FOUND, "箱型需求不存在");
|
||||
ContainerBookingEntity container = repository.containerBooking(request.containerBookingId());
|
||||
@@ -179,7 +183,7 @@ public class OceanBookingService {
|
||||
OceanBookingContainerAllocationEntity allocation = new OceanBookingContainerAllocationEntity();
|
||||
allocation.setId(IdWorker.getId()); allocation.setOceanBookingId(id);
|
||||
allocation.setRequirementId(request.requirementId()); allocation.setContainerBookingId(request.containerBookingId());
|
||||
allocation.setAllocatedBy(operatorId); allocation.setAllocatedByName(name);
|
||||
allocation.setAllocatedBy(operatorId); allocation.setAllocatedByName(name); allocation.setAllocatedAt(LocalDateTime.now());
|
||||
try { repository.insert(allocation); } catch (DuplicateKeyException ex) { throw conflict("柜次已被其他订舱占用"); }
|
||||
return complete(id, operatorId, action, key, detail(id));
|
||||
}
|
||||
|
||||
+42
@@ -4,6 +4,10 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.oceanbooking.dto.OceanBookingDtos.ActionRequest;
|
||||
import com.baiyue.firstleg.oceanbooking.dto.OceanBookingDtos.ChangeRequest;
|
||||
import com.baiyue.firstleg.oceanbooking.dto.OceanBookingDtos.Detail;
|
||||
import com.baiyue.firstleg.oceanbooking.dto.OceanBookingDtos.AllocationRequest;
|
||||
import com.baiyue.firstleg.entity.ContainerBookingEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerAllocationEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerRequirementEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingOperationEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingStatusHistoryEntity;
|
||||
@@ -107,6 +111,44 @@ class OceanBookingServiceTest {
|
||||
verify(repository, never()).find(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void allocatesContainerWithExplicitTimestampAndVersionGuard() {
|
||||
when(repository.find(1L)).thenReturn(booking("CONFIRMED", 5), booking("CONFIRMED", 6));
|
||||
OceanBookingContainerRequirementEntity requirement = new OceanBookingContainerRequirementEntity();
|
||||
requirement.setId(11L); requirement.setOceanBookingId(1L); requirement.setContainerType("40HQ");
|
||||
requirement.setQuantity(1);
|
||||
ContainerBookingEntity container = new ContainerBookingEntity();
|
||||
container.setId(12L); container.setContainerType("40HQ");
|
||||
when(repository.requirement(1L, 11L)).thenReturn(requirement);
|
||||
when(repository.containerBooking(12L)).thenReturn(container);
|
||||
when(repository.touchForAllocation(1L, 5, 9L, "admin")).thenReturn(1);
|
||||
|
||||
Detail result = service.allocate(1L, 9L, "admin", "allocate-1",
|
||||
new AllocationRequest(11L, 12L, 5));
|
||||
|
||||
ArgumentCaptor<OceanBookingContainerAllocationEntity> allocation =
|
||||
ArgumentCaptor.forClass(OceanBookingContainerAllocationEntity.class);
|
||||
verify(repository).insert(allocation.capture());
|
||||
assertThat(allocation.getValue().getOceanBookingId()).isEqualTo(1L);
|
||||
assertThat(allocation.getValue().getRequirementId()).isEqualTo(11L);
|
||||
assertThat(allocation.getValue().getContainerBookingId()).isEqualTo(12L);
|
||||
assertThat(allocation.getValue().getAllocatedAt()).isNotNull();
|
||||
assertThat(result.oceanBooking().getVersion()).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsAllocationAfterReleaseBeforeMutation() {
|
||||
when(repository.find(1L)).thenReturn(booking("RELEASED", 5));
|
||||
|
||||
assertThatThrownBy(() -> service.allocate(1L, 9L, "admin", "allocate-released",
|
||||
new AllocationRequest(11L, 12L, 5)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("当前订舱状态不可分配柜次");
|
||||
|
||||
verify(repository, never()).touchForAllocation(anyLong(), anyInt(), anyLong(), anyString());
|
||||
verify(repository, never()).insert(any(OceanBookingContainerAllocationEntity.class));
|
||||
}
|
||||
|
||||
private String hashForSubmit() throws Exception {
|
||||
var method = OceanBookingService.class.getDeclaredMethod("hash", String.class, Long.class, Object.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
Reference in New Issue
Block a user