Merge pull request 'fix(lastleg): 修复取货车次导致出车记录 S0500' (#39) from hotfix-trip-operations into main

This commit was merged in pull request #39.
This commit is contained in:
2026-10-26 18:00:51 +08:00
3 changed files with 77 additions and 2 deletions
@@ -0,0 +1,74 @@
package com.baiyue.lastleg.fleet.reporting;
import com.baiyue.lastleg.fleet.trip.FleetTripCostService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.time.Instant;
import java.util.UUID;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.mock;
class TripOperationsRepositoryTest {
private JdbcTemplate jdbc;
private TripOperationsRepository repository;
@BeforeEach void setUp() {
jdbc = new JdbcTemplate(new DriverManagerDataSource(
"jdbc:h2:mem:trip-report-" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", ""));
jdbc.execute("CREATE TABLE ll_fleet_trip(id BIGINT PRIMARY KEY,trip_no VARCHAR(64),trip_purpose VARCHAR(16),status VARCHAR(32),warehouse_id BIGINT,departed_at TIMESTAMP,completed_at TIMESTAMP)");
jdbc.execute("CREATE TABLE ll_fleet_trip_history(trip_id BIGINT,record_version BIGINT,action VARCHAR(32),snapshot_json CLOB)");
jdbc.execute("CREATE TABLE ll_fleet_trip_operations_record(trip_no VARCHAR(64),record_version BIGINT,details_json CLOB)");
repository = new TripOperationsRepository(jdbc);
}
@Test void pickupAndLocalTruckFactsDoNotBreakDeliveryReport() {
trip(1, "TR-A", "DELIVERY", "IN_TRANSIT", 1, "2026-10-01 00:00:00");
jdbc.update("INSERT INTO ll_fleet_trip_history VALUES(1,3,'DEPART',?)", TripOperationsServiceTest.DEPARTURE);
trip(2, "PICKUP-A", "PICKUP", "COMPLETED", 1, "2026-10-02 00:00:00");
jdbc.update("INSERT INTO ll_fleet_trip_history VALUES(2,3,'PICKUP_PICKED','{}'),(2,4,'PICKUP_ARRIVED','{}')");
trip(3, "TRUCK-A", "LOCAL_TRUCK", "IN_TRANSIT", 1, "2026-10-02 00:00:00");
var result = service().report(query(null, null), false);
assertThat(result.page().records()).extracting(TripOperationsModels.Row::tripNo).containsExactly("TR-A");
assertThat(result.summary().trips()).isEqualTo(1);
assertThat(result.summary().physicalPallets()).isEqualTo(1);
assertThat(result.summary().ownPackages()).isEqualTo(11);
assertThat(result.summary().externalPackages()).isEqualTo(4);
}
@Test void deliveryFiltersKeepInclusiveStartExclusiveEndAndWarehouseStatus() {
trip(1, "START", "DELIVERY", "COMPLETED", 1, "2026-10-01 00:00:00");
trip(2, "END", "DELIVERY", "COMPLETED", 1, "2026-10-03 00:00:00");
trip(3, "BEFORE", "DELIVERY", "COMPLETED", 1, "2026-09-30 23:59:59");
trip(4, "OTHER-WAREHOUSE", "DELIVERY", "COMPLETED", 2, "2026-10-02 00:00:00");
trip(5, "IN-TRANSIT", "DELIVERY", "IN_TRANSIT", 1, "2026-10-02 00:00:00");
assertThat(repository.departures(query(1L, "COMPLETED")))
.extracting(TripOperationsRepository.Departure::tripNo).containsExactly("START");
}
@Test void missingDeliveryHistoryStillFailsInsteadOfSilentlyDroppingTheTrip() {
trip(1, "MISSING", "DELIVERY", "IN_TRANSIT", 1, "2026-10-01 00:00:00");
assertThatThrownBy(() -> service().report(query(null, null), false))
.isInstanceOf(IllegalStateException.class).hasMessageContaining("不可变历史").hasMessageContaining("MISSING");
}
private void trip(long id, String number, String purpose, String status, long warehouse, String departed) {
jdbc.update("INSERT INTO ll_fleet_trip VALUES(?,?,?,?,?,?,NULL)", id, number, purpose, status, warehouse, departed);
}
private TripOperationsModels.Query query(Long warehouse, String status) {
return new TripOperationsModels.Query(1, 20, Instant.parse("2026-10-01T00:00:00Z"),
Instant.parse("2026-10-03T00:00:00Z"), warehouse, null, null, status);
}
private TripOperationsService service() {
return new TripOperationsService(repository, new ObjectMapper().registerModule(new JavaTimeModule()), mock(FleetTripCostService.class));
}
}