namespace :best_boy do desc "Creates consistent structure of DayReports and MonthReports for a given set of events" task :recover_report_history, [:date] => :environment do |t, args| next unless BestBoy::Event.any? # helper methods # # def month_report_id_for(year, month, owner_type, source, event) date = Date.parse("#{year}-#{month}-01") BestBoy::MonthReport.where(created_at: date.beginning_of_day..date.end_of_year.end_of_day, owner_type: owner_type, event_source: source, event: event).first.id end def flush print "." STDOUT.flush end # Read optional date # # start = args.date.present? ? Date.parse(args.date) : nil puts "" puts "> Destroying all reports ..." puts ">... that where created after beginning of day #{start}" if start.present? puts "" # Destroy all existing reports # # if start.present? BestBoy::MonthReport.between(start, Date.today).delete_all BestBoy::DayReport.where(created_at: start.beginning_of_day..Date.today.end_of_day).delete_all else BestBoy::MonthReport.delete_all BestBoy::DayReport.delete_all end puts "" puts "> Selected report data has been destroyed." puts "" owner_types = BestBoy::Event.order(:owner_type).uniq.pluck(:owner_type) available_events = {} available_event_sources = {} owner_types.each do |owner_type| available_events.merge!( { owner_type => BestBoy::Event.where(owner_type: owner_type).order(:event).uniq.pluck(:event) } ) available_event_sources.merge!( { owner_type => BestBoy::Event.where(owner_type: owner_type).order(:event_source).uniq.pluck(:event_source) } ) # explicitly including nil end start = BestBoy::Event.order('created_at ASC').first.created_at.to_date unless start.present? days = (start..BestBoy::Event.order('created_at ASC').last.created_at.to_date) puts "" puts "> Start creating new reports for #{days.count} days ..." puts "" days.each do |day| owner_types.each do |owner_type| available_events[owner_type].each do |event| available_event_sources[owner_type].each do |source| base_scope = BestBoy::Event.where(owner_type: owner_type, event: event, event_source: source).order('created_at DESC') # Create MonthReports when... # - diving into loop initially or # - a new month starts if day.day == 1 || days.first == day # Check if Events occured during the whole month. # If any, create MonthReports. month_scope = base_scope.where(created_at: day.beginning_of_month.beginning_of_day..day.end_of_month.end_of_day) monthly_occurrences = month_scope.count if monthly_occurrences > 0 artifical_created_at = month_scope.first.created_at if source.present? month_report_with_source = BestBoy::MonthReport.new month_report_with_source.owner_type = owner_type month_report_with_source.event = event month_report_with_source.event_source = source month_report_with_source.occurrences = monthly_occurrences month_report_with_source.created_at = artifical_created_at month_report_with_source.save! end month_report_without_source = BestBoy::MonthReport.new month_report_without_source.owner_type = owner_type month_report_without_source.event = event month_report_without_source.event_source = nil month_report_without_source.occurrences = monthly_occurrences month_report_without_source.created_at = artifical_created_at month_report_without_source.save! end end # Create DayReports if Events occured that specific day # # day_scope = base_scope.where(created_at: day.beginning_of_day..day.end_of_day) daily_occurrences = day_scope.count if daily_occurrences > 0 if source.present? day_report_with_source = BestBoy::DayReport.new day_report_with_source.owner_type = owner_type day_report_with_source.event = event day_report_with_source.event_source = source day_report_with_source.occurrences = daily_occurrences day_report_with_source.created_at = day_scope.first.created_at day_report_with_source.month_report_id = month_report_id_for(day.year, day.month, owner_type, source, event) day_report_with_source.save! end day_report_without_source = BestBoy::DayReport.new day_report_without_source.owner_type = owner_type day_report_without_source.event = event day_report_without_source.event_source = nil day_report_without_source.occurrences = daily_occurrences day_report_without_source.created_at = day_scope.first.created_at day_report_without_source.month_report_id = month_report_id_for(day.year, day.month, owner_type, nil, event) day_report_without_source.save! end end end end flush end puts "" puts "" puts "> Reports recovered. Done!" puts "" end end