require "study_engine/config" module StudyEngine class Report < Struct.new(:assessments, :field, :direction) def self.event_fields StudyEngine.events.map.with_index { |_, index| :"event_#{index}" } end def self.group_class Struct.new(:study_id, *event_fields) do def each(&block) Report.event_fields.map { |field| send(field) }.each(&block) end def max_count Report.event_fields.map { |field| send(field).count }.max end def == other values == other.values end end end def groups sort build_groups end def build_groups assessments.reduce({}) do |groups, assessment| group = groups[assessment.study_id.to_s] || new_empty_group(assessment.study_id) field = field_map[assessment.event] group.send(field).push assessment group.send(field).sort_by! { |a| a.completed_at ? -1 : 1 } groups.merge(assessment.study_id.to_s => group) end.values end def sort groups groups.sort do |a, b| a = a.send(field) b = b.send(field) ascending? ? a <=> b : b <=> a end end def ascending? direction == "ASC" end private def field_map StudyEngine.events.inject({}) do |hash, event| index = StudyEngine.events.index(event) hash.merge event => "event_#{index}" end end def new_empty_group(study_id) empty_groups = StudyEngine.events.map { |_| [] } self.class.group_class.new(study_id, *empty_groups) end end end