2024-08-20 14:14:17 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
class StatsSerializer
|
|
|
|
|
attr_reader :user
|
|
|
|
|
|
|
|
|
|
def initialize(user)
|
|
|
|
|
@user = user
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def call
|
|
|
|
|
{
|
2025-07-08 12:10:10 -04:00
|
|
|
totalDistanceKm: total_distance_km,
|
2025-10-04 09:53:25 -04:00
|
|
|
totalPointsTracked: user.points_count.to_i,
|
2024-08-20 14:14:17 -04:00
|
|
|
totalReverseGeocodedPoints: reverse_geocoded_points,
|
|
|
|
|
totalCountriesVisited: user.countries_visited.count,
|
|
|
|
|
totalCitiesVisited: user.cities_visited.count,
|
|
|
|
|
yearlyStats: yearly_stats
|
|
|
|
|
}.to_json
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
def total_distance_km
|
|
|
|
|
total_distance_meters = user.stats.sum(:distance)
|
2025-07-08 13:23:08 -04:00
|
|
|
|
|
|
|
|
(total_distance_meters / 1000)
|
2024-08-20 14:14:17 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def reverse_geocoded_points
|
2025-12-30 11:33:56 -05:00
|
|
|
StatsQuery.new(user).points_stats[:geocoded]
|
2024-08-20 14:14:17 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def yearly_stats
|
|
|
|
|
user.stats.group_by(&:year).sort.reverse.map do |year, stats|
|
|
|
|
|
{
|
|
|
|
|
year:,
|
2025-07-08 12:10:10 -04:00
|
|
|
totalDistanceKm: stats_distance_km(stats),
|
2024-08-20 14:14:17 -04:00
|
|
|
totalCountriesVisited: user.countries_visited.count,
|
|
|
|
|
totalCitiesVisited: user.cities_visited.count,
|
|
|
|
|
monthlyDistanceKm: monthly_distance(year, stats)
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
def stats_distance_km(stats)
|
|
|
|
|
# Convert from stored meters to kilometers
|
|
|
|
|
total_meters = stats.sum(&:distance)
|
2025-07-08 13:23:08 -04:00
|
|
|
total_meters / 1000
|
2025-07-08 12:10:10 -04:00
|
|
|
end
|
|
|
|
|
|
2024-08-20 14:14:17 -04:00
|
|
|
def monthly_distance(year, stats)
|
|
|
|
|
months = {}
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
(1..12).each { |month| months[Date::MONTHNAMES[month]&.downcase] = distance_km(month, year, stats) }
|
2024-08-20 14:14:17 -04:00
|
|
|
|
|
|
|
|
months
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
def distance_km(month, year, stats)
|
|
|
|
|
# Convert from stored meters to kilometers
|
|
|
|
|
distance_meters = stats.find { _1.month == month && _1.year == year }&.distance.to_i
|
2025-07-08 13:23:08 -04:00
|
|
|
|
|
|
|
|
distance_meters / 1000
|
2024-08-20 14:14:17 -04:00
|
|
|
end
|
|
|
|
|
end
|