fix: link terminal drayage carrier events
This commit is contained in:
+7
@@ -47,6 +47,13 @@ public interface CarrierScheduleQueryMapper extends BaseMapper<CarrierScheduleQu
|
||||
@Param("oceanBookingId") long oceanBookingId,
|
||||
@Param("containerBookingId") long containerBookingId);
|
||||
|
||||
@Select("""
|
||||
SELECT * FROM fl_carrier_schedule_query
|
||||
WHERE container_booking_id=#{containerBookingId}
|
||||
ORDER BY id DESC LIMIT 1
|
||||
""")
|
||||
CarrierScheduleQueryEntity findByContainerBookingId(@Param("containerBookingId") long containerBookingId);
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
SELECT b.id AS containerBookingId,q.id AS queryId,q.version AS queryVersion,
|
||||
|
||||
+3
@@ -41,6 +41,9 @@ public class CarrierScheduleQueryRepository {
|
||||
public CarrierScheduleQueryEntity findByBusinessScope(long customerId, long oceanBookingId, long containerBookingId) {
|
||||
return queries.findByBusinessScope(customerId, oceanBookingId, containerBookingId);
|
||||
}
|
||||
public CarrierScheduleQueryEntity findByContainerBookingId(long containerBookingId) {
|
||||
return queries.findByContainerBookingId(containerBookingId);
|
||||
}
|
||||
public List<ContainerActualFacts> containerActualFacts(List<Long> containerBookingIds) {
|
||||
return queries.selectContainerActualFacts(containerBookingIds);
|
||||
}
|
||||
|
||||
+17
-3
@@ -262,13 +262,27 @@ public class CarrierScheduleQueryService {
|
||||
ContainerBookingEntity container = portSchedules.containerBooking(containerBookingId);
|
||||
if (container == null) throw new BizException(ResultCode.NOT_FOUND, "货柜不存在");
|
||||
CarrierScheduleNode node = CarrierScheduleNode.require(request.standardNode());
|
||||
CarrierScheduleQueryEntity found = repository.findByContainerBookingId(containerBookingId);
|
||||
CarrierScheduleQueryEntity query = found == null ? null : requiredLocked(found.getId());
|
||||
String providerEventId = sha256("CONTAINER_MANUAL|" + containerBookingId + '|' + key);
|
||||
String payloadHash = hash("CONTAINER_MANUAL_NODE", containerBookingId, request);
|
||||
CarrierScheduleNodeFactEntity fact = addNode(null, containerBookingId, "MANUAL", providerEventId,
|
||||
CarrierScheduleNodeFactEntity fact = addNode(query == null ? null : query.getId(), containerBookingId,
|
||||
"MANUAL", providerEventId,
|
||||
node.name(), node, request.observedAt(), request.estimatedAt(), request.actualAt(),
|
||||
request.locationCode(), request.locationName(), "MANUAL:" + operatorId, payloadHash);
|
||||
if (fact != null) nodeOutbox.publishContainerNode(container.getOceanBookingId(), containerBookingId,
|
||||
fact, normalizedContainerNo(container));
|
||||
if (fact != null && query != null) {
|
||||
CarrierScheduleQueryEntity before = copy(query);
|
||||
requireManualActualAdvance(query, node, request.actualAt());
|
||||
boolean advanced = advanceActualNode(query, node, request.actualAt(), request.observedAt(),
|
||||
operatorId, operatorName);
|
||||
CarrierScheduleQueryEntity after = advanced ? required(query.getId()) : query;
|
||||
addHistory(query.getId(), "MANUAL_NODE", before.getVersion(), after.getVersion(), request.reason(),
|
||||
before, after, operatorId, operatorName);
|
||||
nodeOutbox.publish(after, fact, normalizedContainerNo(container));
|
||||
} else if (fact != null) {
|
||||
nodeOutbox.publishContainerNode(container.getOceanBookingId(), containerBookingId,
|
||||
fact, normalizedContainerNo(container));
|
||||
}
|
||||
return containerNodeDetail(containerBookingId, repository.nodesByContainer(containerBookingId));
|
||||
}
|
||||
|
||||
|
||||
+40
@@ -474,6 +474,38 @@ class CarrierScheduleQueryServiceTest {
|
||||
verify(repository).updateState(before, 3, 7L, "admin");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerManualNodeJoinsAndAdvancesExistingCarrierTask() {
|
||||
CarrierScheduleQueryEntity task = task(0, 8);
|
||||
task.setTrackingType("CONTAINER_NO"); task.setTrackingNo("ZCSU7881970");
|
||||
task.setStatus("READY"); task.setLatestStandardNode("PICKUP_READY");
|
||||
task.setLatestNodeObservedAt(NOW.minusHours(1));
|
||||
CarrierScheduleQueryEntity stored = copyTask(task);
|
||||
stored.setVersion(9); stored.setLatestStandardNode("PICKED_UP");
|
||||
stored.setLatestNodeObservedAt(NOW);
|
||||
when(repository.findByContainerBookingId(20L)).thenReturn(task);
|
||||
when(repository.lock(1L)).thenReturn(task);
|
||||
when(repository.find(1L)).thenReturn(stored);
|
||||
when(repository.insertIfAbsent(any(CarrierScheduleNodeFactEntity.class))).thenReturn(true);
|
||||
when(repository.updateState(any(), eq(8), eq(7L), eq("admin"))).thenReturn(1);
|
||||
when(repository.nodesByContainer(20L)).thenReturn(List.of());
|
||||
|
||||
service.addContainerManualNode(20L, 7L, "admin", "terminal-pickup",
|
||||
new com.baiyue.firstleg.portschedule.dto.CarrierScheduleQueryDtos.ContainerManualNodeRequest(
|
||||
"PICKED_UP", NOW, null, NOW, "USLAX", "Los Angeles", "terminal pickup"));
|
||||
|
||||
verify(repository).insertIfAbsent(argThat((CarrierScheduleNodeFactEntity fact) -> Long.valueOf(1L).equals(fact.getQueryId())
|
||||
&& fact.getContainerBookingId() == 20L && "PICKED_UP".equals(fact.getStandardNode())));
|
||||
verify(repository).updateState(task, 8, 7L, "admin");
|
||||
verify(repository).insert(argThat((CarrierScheduleQueryHistoryEntity history) ->
|
||||
"MANUAL_NODE".equals(history.getAction()) && Long.valueOf(1L).equals(history.getQueryId())
|
||||
&& Integer.valueOf(8).equals(history.getFromVersion())
|
||||
&& Integer.valueOf(9).equals(history.getToVersion())));
|
||||
verify(nodeOutbox).publish(eq(stored), argThat(fact -> Long.valueOf(1L).equals(fact.getQueryId())),
|
||||
eq("ZCSU7881970"));
|
||||
verify(nodeOutbox, never()).publishContainerNode(any(), anyLong(), any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void manualActualFactRejectsCurrentOrEarlierBusinessNodeBeforeWritingFact() {
|
||||
CarrierScheduleQueryEntity task = task(0, 3);
|
||||
@@ -771,6 +803,14 @@ class CarrierScheduleQueryServiceTest {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static CarrierScheduleQueryEntity copyTask(CarrierScheduleQueryEntity source) {
|
||||
CarrierScheduleQueryEntity value = task(source.getAttemptCount(), source.getVersion());
|
||||
value.setTrackingType(source.getTrackingType()); value.setTrackingNo(source.getTrackingNo());
|
||||
value.setStatus(source.getStatus()); value.setLatestStandardNode(source.getLatestStandardNode());
|
||||
value.setLatestNodeObservedAt(source.getLatestNodeObservedAt());
|
||||
return value;
|
||||
}
|
||||
|
||||
private void set(String fieldName, Object value) throws Exception {
|
||||
var field = CarrierScheduleQueryService.class.getDeclaredField(fieldName);
|
||||
field.setAccessible(true); field.set(service, value);
|
||||
|
||||
Reference in New Issue
Block a user