feat(stats): project elected mileage source
This commit is contained in:
@@ -12,6 +12,7 @@ const (
|
||||
QualityOK = "OK"
|
||||
QualityNoPreviousBaseline = "NO_PREVIOUS_BASELINE"
|
||||
QualityInvalidDelta = "INVALID_DELTA"
|
||||
maxSelectedDailyMileageKM = 1000
|
||||
)
|
||||
|
||||
type SourceMileageSample struct {
|
||||
@@ -99,6 +100,28 @@ func UpsertSourceMileage(ctx context.Context, exec Execer, sample SourceMileageS
|
||||
return err
|
||||
}
|
||||
|
||||
func ProjectDailyMileage(ctx context.Context, exec Execer, vin string, statDate string, protocol envelope.Protocol) error {
|
||||
if exec == nil {
|
||||
panic("stats execer must not be nil")
|
||||
}
|
||||
if strings.TrimSpace(vin) == "" || strings.TrimSpace(statDate) == "" {
|
||||
return nil
|
||||
}
|
||||
if _, err := exec.ExecContext(ctx, clearSelectedSourceSQL, vin, statDate, string(protocol)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := exec.ExecContext(ctx, projectDailyMileageSQL,
|
||||
vin,
|
||||
statDate,
|
||||
string(protocol),
|
||||
maxSelectedDailyMileageKM,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := exec.ExecContext(ctx, markSelectedSourceSQL, vin, statDate, string(protocol))
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertSourceMileageSQL = `
|
||||
INSERT INTO vehicle_daily_mileage_source
|
||||
(vin, stat_date, protocol, source_key, source_ip, source_endpoint, phone, device_id, platform_name,
|
||||
@@ -148,3 +171,61 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
quality_reason = VALUES(quality_reason),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
`
|
||||
|
||||
const clearSelectedSourceSQL = `
|
||||
UPDATE vehicle_daily_mileage_source
|
||||
SET is_selected = 0
|
||||
WHERE vin = ? AND stat_date = ? AND protocol = ?
|
||||
`
|
||||
|
||||
const projectDailyMileageSQL = `
|
||||
INSERT INTO vehicle_daily_mileage
|
||||
(vin, stat_date, protocol, daily_mileage_km,
|
||||
first_total_mileage_km, latest_total_mileage_km,
|
||||
trusted_source_key, trusted_phone, trusted_source_endpoint, sample_count)
|
||||
SELECT
|
||||
s.vin,
|
||||
s.stat_date,
|
||||
s.protocol,
|
||||
s.daily_mileage_km,
|
||||
s.first_total_mileage_km,
|
||||
s.latest_total_mileage_km,
|
||||
s.source_key,
|
||||
s.phone,
|
||||
s.source_endpoint,
|
||||
s.sample_count
|
||||
FROM vehicle_daily_mileage_source s
|
||||
LEFT JOIN vehicle_data_source ds
|
||||
ON ds.protocol = s.protocol AND ds.source_ip = s.source_ip
|
||||
WHERE s.vin = ?
|
||||
AND s.stat_date = ?
|
||||
AND s.protocol = ?
|
||||
AND s.quality_status = 'OK'
|
||||
AND s.daily_mileage_km BETWEEN 0 AND ?
|
||||
AND COALESCE(ds.enabled, 1) = 1
|
||||
ORDER BY COALESCE(ds.trust_priority, 100),
|
||||
s.sample_count DESC,
|
||||
s.latest_event_time DESC,
|
||||
s.source_key ASC
|
||||
LIMIT 1
|
||||
ON DUPLICATE KEY UPDATE
|
||||
daily_mileage_km = VALUES(daily_mileage_km),
|
||||
first_total_mileage_km = VALUES(first_total_mileage_km),
|
||||
latest_total_mileage_km = VALUES(latest_total_mileage_km),
|
||||
trusted_source_key = VALUES(trusted_source_key),
|
||||
trusted_phone = VALUES(trusted_phone),
|
||||
trusted_source_endpoint = VALUES(trusted_source_endpoint),
|
||||
sample_count = VALUES(sample_count),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
`
|
||||
|
||||
const markSelectedSourceSQL = `
|
||||
UPDATE vehicle_daily_mileage_source s
|
||||
JOIN vehicle_daily_mileage m
|
||||
ON m.vin = s.vin
|
||||
AND m.stat_date = s.stat_date
|
||||
AND m.protocol = s.protocol
|
||||
AND m.trusted_source_key = s.source_key
|
||||
SET s.is_selected = 1
|
||||
WHERE s.vin = ? AND s.stat_date = ? AND s.protocol = ?
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user