You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sqm-dashboards/app/presenters/response_rate_presenter.rb

109 lines
3.1 KiB

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.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