class ResponseRatePresenter attr_reader :focus, :academic_year, :school, :survey_items def initialize(focus:, academic_year:, school:) @focus = focus @academic_year = academic_year @school = school if focus == :student @survey_items = Measure.all.flat_map do |measure| measure.student_survey_items_with_sufficient_responses(school:, academic_year:) end end @survey_items = SurveyItem.teacher_survey_items if focus == :teacher end def date SurveyItemResponse.where(survey_item: survey_items, school:, academic_year:).order(recorded_date: :DESC).first&.recorded_date end def percentage return 0 if respondents_count.nil? || respondents_count.zero? cap_at_100(actual_count.to_f / respondents_count.to_f * 100).round end def color percentage > 75 ? "purple" : "gold" end def date_message return "" if date.nil? "Response rate as of #{date.to_date.strftime('%m/%d/%y')}" end def hover_message return "" if date.nil? "Percentages based on #{actual_count} out of #{respondents_count.round} #{focus}s completing at least 25% of the survey." end private def cap_at_100(value) value > 100 ? 100 : value end def actual_count if focus == :teacher response_count_for_survey_items(survey_items:) else non_early_ed_items = survey_items - SurveyItem.early_education_survey_items non_early_ed_count = response_count_for_survey_items(survey_items: non_early_ed_items) early_ed_items = survey_items & SurveyItem.early_education_survey_items early_ed_count = SurveyItemResponse.where(school:, academic_year:, survey_item: early_ed_items) .group(:survey_item) .select(:response_id) .distinct .count .reduce(0) do |largest, row| count = row[1] if count > largest count else largest end end non_early_ed_count + early_ed_count end end def response_count_for_survey_items(survey_items:) SurveyItemResponse.where(school:, academic_year:, survey_item: survey_items).select(:response_id).distinct.count || 0 end def respondents_count return 0 if respondents.nil? count = enrollment if focus == :student count = respondents.total_teachers if focus == :teacher count end def enrollment SurveyItemResponse.where(school:, academic_year:, grade: grades, survey_item: SurveyItem.student_survey_items) .select(:grade) .distinct .pluck(:grade) .reject(&:nil?) .map do |grade| respondents.enrollment_by_grade[grade] end.sum.to_f end def respondents @respondents ||= Respondent.by_school_and_year(school:, academic_year:) end def grades respondents.enrollment_by_grade.keys end end