app.kluk.fr/app/services/mood_calendar_service.rb

70 lines
2.2 KiB
Ruby
Raw Normal View History

2026-02-07 12:09:06 +01:00
class MoodCalendarService
2026-03-22 16:32:01 +01:00
def self.generate_calendar(user, start_date: nil, end_date: nil)
2026-03-21 20:28:56 +01:00
data = user.moods.includes(:mode)
2026-03-19 19:04:16 +01:00
.order(:recorded_at)
.map { |mood| { mode: mood.mode, recorded_at: mood.recorded_at } }
2026-02-07 12:09:06 +01:00
2026-03-22 16:32:01 +01:00
day_logs_by_date = user.day_logs.index_by(&:day)
if data.empty?
start_date = Date.current
else
start_date ||= data.first[:recorded_at].to_date
end
2026-02-07 12:09:06 +01:00
start_date = start_date.to_date
end_date = end_date ? end_date.to_date : [ Date.current, start_date + 5.months ].max
=begin
if end_date.nil?
end_date = start_date + 5.months
else
end_date = end_date.to_date
end
=end
2026-02-07 12:09:06 +01:00
data_by_date = data.group_by { |d| d[:recorded_at].to_date }
.transform_values { |entries| entries.max_by { |e| e[:recorded_at] } }
2026-02-07 12:09:06 +01:00
last_mode = data.select { |d| d[:recorded_at].to_date < start_date }
.max_by { |d| d[:recorded_at] }
&.[](:mode)
2026-02-07 12:09:06 +01:00
complete_data = (start_date..end_date).map do |date|
2026-03-22 16:32:01 +01:00
day_log = day_logs_by_date[date]
2026-02-07 12:09:06 +01:00
if data_by_date[date]
last_mode = data_by_date[date][:mode]
2026-03-22 16:32:01 +01:00
data_by_date[date].merge(day_log: day_log)
2026-02-07 12:09:06 +01:00
else
2026-03-22 16:32:01 +01:00
{ mode: nil, recorded_at: date.to_datetime, guess: last_mode, day_log: day_log }
2026-02-07 12:09:06 +01:00
end
end
complete_data.group_by { |d| d[:recorded_at].to_date.beginning_of_month }
2026-03-22 16:32:01 +01:00
.map do |month_start, _|
first_monday = month_start
first_monday = first_monday.next_occurring(:monday) unless first_monday.monday?
2026-02-07 12:09:06 +01:00
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?
2026-02-07 12:09:06 +01:00
month_end = next_first_monday - 1.day
2026-02-07 12:09:06 +01:00
data_hash = complete_data.index_by { |d| d[:recorded_at].to_date }
2026-02-07 12:09:06 +01:00
all_days = (first_monday..month_end).map do |date|
2026-03-22 16:32:01 +01:00
data_hash[date] || { mode: nil, recorded_at: date.to_datetime, guess: nil, day_log: nil }
end
2026-02-07 12:09:06 +01:00
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 }
2026-02-07 12:09:06 +01:00
{
month: month_start,
weeks: weeks
}
end
2026-02-07 12:09:06 +01:00
end
end