Created
September 16, 2011 19:08
-
-
Save sixtyfive/1222856 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Datespan < ActiveRecord::Base | |
include Enumerable | |
attr_accessor :results | |
def initialize(start_date, end_date, user) | |
build_results(start_date, end_date, user) | |
end | |
def each(&block) | |
@results.each(&block) | |
end | |
private | |
def build_results(start_date, end_date, user) | |
r = {} | |
years = Year.date_range_scoped_by_user(start_date, end_date, user) | |
r[:years] = {} | |
# Loop through all Years contained in the given range, | |
# adding each year to the array. | |
for year in years do | |
months = Month.date_range_scoped_by_user_and_year(start_date, end_date, user, year) | |
r[:years][year.id] = { | |
:name => year.name, | |
:number_of_months => months.count, | |
:total_hours => year.total_hours.human_duration, | |
:target_hours => year.target_hours.human_duration, | |
:overtime_hours => year.overtime_hours.human_duration | |
} | |
r[:years][year.id][:months] = {} | |
# Likewise, loop through all the Months in the given range | |
# now, and add them to the respective year they belong in. | |
for month in months do | |
weeks = Week.date_range_scoped_by_user_and_month(start_date, end_date, user, month) | |
r[:years][year.id][:months][month.id] = { | |
:name => month.name, | |
:number_of_weeks => weeks.count, | |
:total_hours => month.total_hours.human_duration, | |
:target_hours => month.target_hours.human_duration, | |
:overtime_hours => month.overtime_hours.human_duration | |
} | |
r[:years][year.id][:months][month.id][:weeks] = {} | |
# Same thing again, only do it with the weeks now. Note that | |
# the weeks were obtained above by giving them the month they're | |
# supposed to belong to, so some weeks will be shown twice in the | |
# results! | |
for week in weeks do | |
r[:years][year.id][:months][month.id][:weeks][week.id] = { | |
:name => week.name, | |
:number_of_days => week.days.count, | |
:total_hours => week.total_hours.human_duration, | |
:target_hours => week.target_hours.human_duration, | |
:overtime_hours => week.overtime_hours.human_duration | |
} | |
r[:years][year.id][:months][month.id][:weeks][week.id][:days] = {} | |
# And another loop to get through the days that are in a week. | |
# Here it is clear again where a day belongs, and every day must | |
# only appear once in a given range or result. | |
for day in week.days do | |
# Usually, only Mondays to Fridays are added to the list. Saturdays and Sundays | |
# will be added if there are Activities associated with them. Other holidays would | |
# be added regardless of wether or not they have any activities. | |
if (day.is_weekday? || (day.is_weekend_day? && day.activities.any?)) | |
r[:years][year.id][:months][month.id][:weeks][week.id][:days][day.id] = { | |
:in_range => day.within_range?(start_date, end_date), | |
:name => day.name, | |
:date => day.date.strftime('%d.%m.%Y'), | |
:activity_count => day.activities.count, | |
:total_hours => day.total_hours.human_duration, | |
:target_hours => day.target_hours.human_duration, | |
:overtime_hours => day.overtime_hours.human_duration | |
} | |
r[:years][year.id][:months][month.id][:weeks][week.id][:days][day.id][:activities] = {} | |
# The last of these nested loops will add a day's activities | |
# to the array. The line above will create an empty hash for | |
# the activities anyways, whether there are any or not. This | |
# is in order for the array to be consistent and not cause nil | |
# errors when it is being looped through. | |
for activity in day.activities do | |
r[:years][year.id][:months][month.id][:weeks][week.id][:days][day.id][:activities][activity.id] = { | |
:category => activity.category.name, | |
:description => activity.description.html_safe, | |
:duration => activity.duration(day.date.beginning_of_day, day.date.end_of_day).human_duration | |
} | |
end | |
end | |
end | |
end | |
end | |
end | |
@results = r | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment