app.kluk.fr/app/services/mood_calendar_service.rb
2026-03-15 19:27:25 +01:00

71 lines
2.6 KiB
Ruby

# app/services/mood_calendar_service.rb
class MoodCalendarService
def self.generate_calendar(moods, start_date: nil, end_date: Date.current)
# Convertir la relation ActiveRecord en tableau de hash
data = moods.joins(:mode)
.order(:recorded_at)
.pluck(:recorded_at, "modes.label", "modes.color")
.map { |recorded_at, label, color| { mode: { label: label, color: color }, recorded_at: recorded_at } }
if data.empty?
start_date = Date.current
else
start_date ||= data.first[:recorded_at].to_date
end
if end_date < (start_date + 5.months)
end_date = start_date + 5.months
end
# Convertir en Date si ce sont des DateTime ou Time
start_date = start_date.to_date
end_date = end_date&.to_date
# Grouper par jour et garder le plus récent pour chaque jour
data_by_date = data.group_by { |d| d[:recorded_at].to_date }
.transform_values { |entries| entries.max_by { |e| e[:recorded_at] } }
# Trouver le dernier mood avant start_date pour initialiser le guess
last_mode = data.select { |d| d[:recorded_at].to_date < start_date }
.max_by { |d| d[:recorded_at] }
&.[](:mode)
# Générer le tableau complet avec tous les jours
complete_data = (start_date..end_date).map do |date|
if data_by_date[date]
last_mode = data_by_date[date][:mode]
data_by_date[date]
else
{ mode: nil, recorded_at: date.to_datetime, guess: last_mode }
end
end
# Regrouper par mois avec semaines commençant au premier lundi
complete_data.group_by { |d| d[:recorded_at].to_date.beginning_of_month }
.map do |month_start, month_data|
first_monday = month_start
first_monday = first_monday.next_occurring(:monday) unless first_monday.monday?
next_month_start = month_start.next_month.beginning_of_month
next_first_monday = next_month_start
next_first_monday = next_first_monday.next_occurring(:monday) unless next_first_monday.monday?
month_end = next_first_monday - 1.day
data_hash = complete_data.index_by { |d| d[:recorded_at].to_date }
all_days = (first_monday..month_end).map do |date|
data_hash[date] || { mode: nil, recorded_at: date.to_datetime, guess: nil }
end
weeks = all_days.group_by { |d| d[:recorded_at].to_date.beginning_of_week(:monday) }
.sort_by { |week_start, _| week_start }
.map { |_, week_moods| week_moods }
{
month: month_start,
weeks: weeks
}
end
end
end#