Skip to content

Instantly share code, notes, and snippets.

@lohannon
Last active February 14, 2017 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lohannon/793d8ae1285ee898fa60c6b88fcff2c4 to your computer and use it in GitHub Desktop.
Save lohannon/793d8ae1285ee898fa60c6b88fcff2c4 to your computer and use it in GitHub Desktop.
module DateTimeHelpers
EMPTY_TIME = '12:00 am'
extend ActiveSupport::Concern
def begin_date_precedes_end_date
return if begin_date.nil? or end_date.nil?
if end_date < begin_date
if self.respond_to? :begin_time_text
errors.add(:begin_date_text, 'cannot come after the end date.')
elsif self.respond_to? :begin_date
errors.add(:begin_date, 'cannot come after the end date.')
else
errors[:base] << "Begin date cannot come after the end date."
end
end
end
# validation
def begin_date_not_on_nonschool_day
return if begin_date.nil?
if (!self.persisted? and self.nonschool_days.where(:date => self.begin_date.to_date).count == 1) or
(self.persisted? and self.begin_date_changed? and self.nonschool_days.where(:date => self.begin_date.to_date).count == 1)
if respond_to?(:is_date_shift_update?) and self.is_date_shift_update?
errors[:base] << 'Begin date cannot be a non-school day.' unless errors[:base].present?
end
if self.respond_to? :begin_date_text
errors.add(:begin_date_text, 'cannot be a non-school day.')
end
if self.respond_to? :begin_date
errors.add(:begin_date, 'cannot be a non-school day.')
end
end
end
def end_date_not_on_nonschool_day
return if end_date.nil?
if (!self.persisted? and self.nonschool_days.where(:date => self.end_date.to_date).count == 1) or
(self.persisted? and self.end_date_changed? and self.nonschool_days.where(:date => self.end_date.to_date).count == 1)
if respond_to?(:is_date_shift_update?) and self.is_date_shift_update?
errors[:base] << 'End date cannot be a non-school day.' unless errors[:base].present?
end
if self.respond_to? :end_date_text
errors.add(:end_date_text, 'cannot be a non-school day.')
end
if self.respond_to? :end_date
errors.add(:end_date, 'cannot be a non-school day.')
end
end
end
def repeating_assignment_begin_date_equals_end_date
return if begin_date.nil? || end_date.nil?
if begin_and_end_dates_different? and is_repeating
errors[:base] << "Date Given and Date Due must be the same for repeating assignments."
end
end
def day_diff (start_date, end_date)
(end_date.to_datetime.beginning_of_day - start_date.to_datetime.beginning_of_day).to_i
end
def different_days? (start_date, end_date)
(day_diff start_date, end_date) > 0
end
def same_days? (start_date, end_date)
(day_diff start_date, end_date) == 0
end
def same_day_different_times? (start_date, end_date)
(same_days? start_date, end_date) && (start_date != end_date)
end
end
class WeeklyAssignments < EventReport
self.theme = "#{self.theme} weekly-activities"
self.implicit_filters = [::Filter::CURRENT_STUDENT]
day_format = lambda { |wday|
lambda { |week|
events = week.events_for_wday(wday)
if events.empty?
"<span class='no-activity'>------------</span>"
else
events.map { |event|
display = "<div class='page-break-column-group'>"
display += "<span class='activity'>#{event[:assignment_name]}</span>"
if week.include_descriptions? and event[:description].present?
description = event[:description]
if description.length > 200
description = "#{description.slice(0, 200)}..."
end
description = description.gsub(/\n+/, "\n").gsub(/\n/, '<br/>')
display += "<span class='description'>#{description}</span>"
end
if week.include_urls?
display += "<span class='description word-wrap'>#{event[:urls]}</span>" if event[:urls].present?
end
display += "</div>"
display
}.join
end
}
}
@@seven_day_metadata = ::ReportGenerator::ColumnMetadata.new {
column('Course', emphasize(:course_info_name)).with_type('page-break-fixed-content')
column('Sunday', day_format.call(0)).with_type('seven-day')
column('Monday', day_format.call(1)).with_type('seven-day')
column('Tuesday', day_format.call(2)).with_type('seven-day')
column('Wednesday', day_format.call(3)).with_type('seven-day')
column('Thursday', day_format.call(4)).with_type('seven-day')
column('Friday', day_format.call(5)).with_type('seven-day')
column('Saturday', day_format.call(6)).with_type('seven-day')
}
@@five_day_metadata = ::ReportGenerator::ColumnMetadata.new {
column('Course', emphasize(:course_info_name)).with_type('page-break-fixed-content')
column('Monday', day_format.call(1)).with_type('five-day')
column('Tuesday', day_format.call(2)).with_type('five-day')
column('Wednesday', day_format.call(3)).with_type('five-day')
column('Thursday', day_format.call(4)).with_type('five-day')
column('Friday', day_format.call(5)).with_type('five-day')
}
class Row
include DateTimeHelpers
attr_reader :course_info_id, :course_info_name, :events
def initialize(course_info_id, course_info_name, options, events)
@course_info_id = course_info_id
@course_info_name = course_info_name
@options = options
@events = events
end
def include_descriptions?
@options.include? "Show Descriptions"
end
def include_urls?
@options.include? "Show URLs"
end
# names of events on a wday
def events_for_wday(wday)
@events.select { |e| e[:begin_date].wday == wday }
end
def empty?
@events.empty?
end
end
def format_events(events)
formatted_results = events.map do |event|
formatted_events = row_to_hash event
if (different_days? formatted_events[:begin_date], formatted_events[:end_date]) && event[7] == 'Assignment'
formatted_events = begin_end_date_rows formatted_events, 'Begin:', 'Due:'
end
formatted_events
end
formatted_results.flatten.compact.sort_by!{|r| r[:begin_date]}
end
def row_to_hash(row)
begin_date = DateTime.parse(row[0])
end_date = row[1].present? ? DateTime.parse(row[1]) : begin_date
{
:course_info_name => row[6],
:course_info_id => row[10].to_i,
:begin_date => begin_date,
:end_date => end_date,
:assignment_name => row[5],
:description => row[8],
:urls => ReportDef::event_urls_concat(row[11])
}
end
def begin_end_date_rows(row, begin_prefix, end_prefix)
begin_row = row
end_row = row.dup
begin_row[:assignment_name] = "#{begin_prefix} #{begin_row[:assignment_name]}"
end_row[:assignment_name] = "#{end_prefix} #{end_row[:assignment_name]}"
end_row[:begin_date] = end_row[:end_date]
[begin_row, end_row]
end
def generate(filters)
# default to 5-day format
@metadata = @@five_day_metadata
time_filter = lookup_filter(:begin_date, filters)
options = filter_values_for(:options, filters)
student_ids = filter_student_ids(build_implicit_filters)
course_info_ids = filter_ids_for(:course_info_id, filters)
include_lesson_plans = options.include? "Show Instructional Plans"
title = "Week of #{time_filter.start.strftime('%B %-d, %Y')}"
events = query_events time_filter, student_ids
# filter down to assignments belonging to selected courses
selected_events = events.rows.select { |row|
(row[7] == "Assignment" || (include_lesson_plans && row[7] == "LessonPlanInstruction")) and course_info_ids.include?(row[10].to_i)
}
# transfer to hash structure
assignments = (format_events selected_events).select{|event| event[:begin_date] >= time_filter.start && event[:begin_date] <= time_filter.stop }
# group by course
assignments_by_course = assignments.group_by { |a| a[:course_info_name] }
# create rows for table
rows = assignments_by_course.map { |course_info_name, events| Row.new events.first[:course_info_id], course_info_name, options, events }
# add any blank course_ids
empty_rows = CourseInfo.select('id, name').where(:id => course_info_ids - rows.map(&:course_info_id)).all
.map { |course_info| Row.new course_info.id, course_info.name, options, [] }
rows = rows + empty_rows
# sort
rows.sort_by! &:course_info_name
# determine report layout; if any assignments are on sunday/saturday, use 7 day format
@metadata = @@seven_day_metadata if assignments.any? { |a| a[:begin_date].wday == 0 or a[:begin_date].wday == 6 }
[ ::ReportGenerator::DataSet.new(title, rows) ]
end
end
@rthbound
Copy link

irb(main):001:0> module DateTimeHelpers
irb(main):002:1>   def different_days?
irb(main):003:2>   end
irb(main):004:1> end
=> :different_days?
irb(main):005:0>
irb(main):006:0* module ReportDef
irb(main):007:1>   class WeeklyAssignments
irb(main):008:2>     include DateTimeHelpers
irb(main):009:2>     class Row
irb(main):010:3>       def do_the_thing
irb(main):011:4>         different_days?
irb(main):012:4>       end
irb(main):013:3>     end
irb(main):014:2>   end
irb(main):015:1> end
=> :do_the_thing
irb(main):016:0> ReportDef::WeeklyAssignments::Row.new.do_the_thing
NoMethodError: undefined method `different_days?' for #<ReportDef::WeeklyAssignments::Row:0x007f884aa464e0>
	from (irb):11:in `do_the_thing'
	from (irb):16
	from /Users/Tad/.rbenv/versions/2.1.5/bin/irb:11:in `<main>'

@rthbound
Copy link

module DateTimeHelpers
  def different_days?
  end
end

module ReportDef
  class WeeklyAssignments
    include DateTimeHelpers
    class Row
      def do_the_thing
        different_days?
      end
    end
  end
end

something simpler to play with

@rthbound
Copy link

Looks like this might be what we're after:

module DateTimeHelpers
  def different_days?
  end
end

module ReportDef
  class WeeklyAssignments
    class Row
      include DateTimeHelpers
      def do_the_thing
        different_days?
      end
    end
  end
end

ReportDef::WeeklyAssignments::Row.new.do_the_thing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment