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);
|
String normalizedVin = clean(vin);
|
||||||
Date date = Date.valueOf(statDate);
|
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();
|
String strategy = DailyMileageStrategy.JT808_TOTAL_MILEAGE_DIFF.name();
|
||||||
upsertMetric(normalizedVin, date, DAILY_MILEAGE_LATEST_TOTAL_KEY, totalMileageKm,
|
OptionalDouble existingMin = findMetric(normalizedVin, date, DAILY_MILEAGE_START_TOTAL_KEY);
|
||||||
DAILY_MILEAGE_UNIT, strategy);
|
double minTotalMileage = existingMin.isPresent()
|
||||||
double dailyMileageKm = totalMileageKm - startTotalMileage;
|
? 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(
|
VehicleDailyStatResult result = new VehicleDailyStatResult(
|
||||||
normalizedVin,
|
normalizedVin,
|
||||||
statDate,
|
statDate,
|
||||||
|
|||||||
@@ -78,6 +78,39 @@ class JdbcVehicleStatMetricRepositoryTest {
|
|||||||
String.class)).isEmpty();
|
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
|
@Test
|
||||||
void readsLegacyCalculationMethodAsTotalMileageDifference() {
|
void readsLegacyCalculationMethodAsTotalMileageDifference() {
|
||||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(new DriverManagerDataSource(
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(new DriverManagerDataSource(
|
||||||
|
|||||||
Reference in New Issue
Block a user