fix: calculate jt808 mileage from total range
This commit is contained in:
@@ -63,25 +63,26 @@ public final class JdbcVehicleStatMetricRepository implements VehicleStatReposit
|
||||
}
|
||||
String normalizedVin = clean(vin);
|
||||
Date date = Date.valueOf(statDate);
|
||||
OptionalDouble existingStart = findMetric(normalizedVin, date, DAILY_MILEAGE_START_TOTAL_KEY);
|
||||
double startTotalMileage = existingStart.orElse(totalMileageKm);
|
||||
if (existingStart.isEmpty()) {
|
||||
upsertMetric(normalizedVin, date, DAILY_MILEAGE_START_TOTAL_KEY, startTotalMileage,
|
||||
DAILY_MILEAGE_UNIT, DailyMileageStrategy.JT808_TOTAL_MILEAGE_DIFF.name());
|
||||
}
|
||||
|
||||
OptionalDouble existingLatest = findMetric(normalizedVin, date, DAILY_MILEAGE_LATEST_TOTAL_KEY);
|
||||
if (existingLatest.isPresent() && totalMileageKm < existingLatest.getAsDouble()) {
|
||||
return findDailyStat(normalizedVin, statDate);
|
||||
}
|
||||
if (totalMileageKm < startTotalMileage) {
|
||||
return findDailyStat(normalizedVin, statDate);
|
||||
}
|
||||
|
||||
String strategy = DailyMileageStrategy.JT808_TOTAL_MILEAGE_DIFF.name();
|
||||
upsertMetric(normalizedVin, date, DAILY_MILEAGE_LATEST_TOTAL_KEY, totalMileageKm,
|
||||
DAILY_MILEAGE_UNIT, strategy);
|
||||
double dailyMileageKm = totalMileageKm - startTotalMileage;
|
||||
OptionalDouble existingMin = findMetric(normalizedVin, date, DAILY_MILEAGE_START_TOTAL_KEY);
|
||||
double minTotalMileage = existingMin.isPresent()
|
||||
? Math.min(existingMin.getAsDouble(), totalMileageKm)
|
||||
: totalMileageKm;
|
||||
if (existingMin.isEmpty() || Double.compare(minTotalMileage, existingMin.getAsDouble()) != 0) {
|
||||
upsertMetric(normalizedVin, date, DAILY_MILEAGE_START_TOTAL_KEY, minTotalMileage,
|
||||
DAILY_MILEAGE_UNIT, strategy);
|
||||
}
|
||||
|
||||
OptionalDouble existingMax = findMetric(normalizedVin, date, DAILY_MILEAGE_LATEST_TOTAL_KEY);
|
||||
double maxTotalMileage = existingMax.isPresent()
|
||||
? Math.max(existingMax.getAsDouble(), totalMileageKm)
|
||||
: totalMileageKm;
|
||||
if (existingMax.isEmpty() || Double.compare(maxTotalMileage, existingMax.getAsDouble()) != 0) {
|
||||
upsertMetric(normalizedVin, date, DAILY_MILEAGE_LATEST_TOTAL_KEY, maxTotalMileage,
|
||||
DAILY_MILEAGE_UNIT, strategy);
|
||||
}
|
||||
|
||||
double dailyMileageKm = maxTotalMileage - minTotalMileage;
|
||||
VehicleDailyStatResult result = new VehicleDailyStatResult(
|
||||
normalizedVin,
|
||||
statDate,
|
||||
|
||||
@@ -78,6 +78,39 @@ class JdbcVehicleStatMetricRepositoryTest {
|
||||
String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void recalculatesJt808MileageFromDailyMinAndMaxTotalsWhenSamplesArriveOutOfOrder() {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(new DriverManagerDataSource(
|
||||
"jdbc:h2:mem:vehicle_stat_metric_jt808_out_of_order;MODE=MySQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1",
|
||||
"sa",
|
||||
""));
|
||||
JdbcVehicleStatMetricRepository repository = new JdbcVehicleStatMetricRepository(jdbcTemplate);
|
||||
|
||||
repository.recordDailyMileageSample("VIN001", LocalDate.of(2026, 7, 1), 1008.75).orElseThrow();
|
||||
VehicleDailyStatResult lowerSample = repository.recordDailyMileageSample(
|
||||
"VIN001", LocalDate.of(2026, 7, 1), 1000.5).orElseThrow();
|
||||
VehicleDailyStatResult higherSample = repository.recordDailyMileageSample(
|
||||
"VIN001", LocalDate.of(2026, 7, 1), 1010.0).orElseThrow();
|
||||
|
||||
assertThat(lowerSample.dailyMileageKm()).hasValue(8.25);
|
||||
assertThat(higherSample.dailyMileageKm()).hasValue(9.5);
|
||||
assertThat(jdbcTemplate.queryForObject("""
|
||||
SELECT metric_value
|
||||
FROM vehicle_stat_metric
|
||||
WHERE vin = 'VIN001' AND metric_key = 'daily_mileage_start_total_km'
|
||||
""", Double.class)).isEqualTo(1000.5);
|
||||
assertThat(jdbcTemplate.queryForObject("""
|
||||
SELECT metric_value
|
||||
FROM vehicle_stat_metric
|
||||
WHERE vin = 'VIN001' AND metric_key = 'daily_mileage_latest_total_km'
|
||||
""", Double.class)).isEqualTo(1010.0);
|
||||
assertThat(jdbcTemplate.queryForObject("""
|
||||
SELECT metric_value
|
||||
FROM vehicle_stat_metric
|
||||
WHERE vin = 'VIN001' AND metric_key = 'daily_mileage_km'
|
||||
""", Double.class)).isEqualTo(9.5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readsLegacyCalculationMethodAsTotalMileageDifference() {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(new DriverManagerDataSource(
|
||||
|
||||
Reference in New Issue
Block a user