diff --git a/app/models/report/measure_by_grade.rb b/app/models/report/measure_by_grade.rb index e75450f8..b3755c25 100644 --- a/app/models/report/measure_by_grade.rb +++ b/app/models/report/measure_by_grade.rb @@ -4,26 +4,80 @@ module Report data = to_csv(schools:, academic_years:, measures:) FileUtils.mkdir_p Rails.root.join("tmp", "reports") filepath = Rails.root.join("tmp", "reports", filename) - write_csv(data:, filepath:) + write_csv(data: data, filepath: filepath) data end def self.to_csv(schools:, academic_years:, measures:) - ::School.all.map do |school| - ::AcademicYear.all.map do |academic_year| - ::Measure.all.map do |measure| - next 0 if measure.student_survey_items.count.zero? - - measure.student_survey_items.map do |survey_item| - ::SurveyItemResponse.where(survey_item:, school: school, academic_year: academic_year).average(:likert_score).to_f.round(2) - end.remove_blanks.average + headers = ["Measure Name", "Measure ID", "Academic Year", "Averages - ALL MCIEA Schools - Student + Teacher + Admin", "Averages - ALL MCIEA Schools - Students only"] + grades = (0..12).to_a.map(&:to_s).map { |grade| grade == "0" ? "Kindergarten" : "Grade #{grade}" } + headers.concat(grades) + + CSV.generate(headers: true) do |csv| + csv << headers + academic_years.each do |academic_year| + measures.each do |measure| + scores = schools.map do |school| + measure.score(school:, academic_year:).average + end.remove_blanks + + avg_score = scores.count.positive? ? scores.average : nil + avg_score = avg_score.round(2) unless avg_score.nil? + avg_score = "N/A" if avg_score.nil? + + student_scores = schools.map do |school| + measure.student_score(school:, academic_year:).average + end.remove_blanks + + student_avg = student_scores.count.positive? ? student_scores.average : nil + student_avg = student_avg.round(2) unless student_avg.nil? + student_avg = "N/A" if student_avg.nil? + + tmp1 = [ + measure.name, + measure.measure_id, + academic_year.range, + avg_score, + student_avg + ] + + tmp2 = (0..12).to_a.map do |grade| + s_averages = schools.each.map do |school| + next unless StudentResponseRateCalculator.new(subcategory: measure.subcategory, school:, academic_year:).meets_student_threshold? + + student_survey_items = ::SurveyItem.where(id: ::SurveyItem.joins("inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id") + .student_survey_items + .where("survey_item_responses.school": school, + "survey_item_responses.academic_year": academic_year, + "survey_item_responses.survey_item_id": measure.student_survey_items, + "survey_item_responses.grade": grade) + .group("survey_items.id") + .having("count(*) >= 10") + .count.keys) + + ::SurveyItemResponse.where(survey_item: student_survey_items, school:, academic_year:, grade:).average(:likert_score) + end.remove_blanks.average + + if s_averages.positive? + s_averages.round(2) + else + "N/A" + end + end + + csv << tmp1.concat(tmp2) end end end end def self.write_csv(data:, filepath:) - File.write(filepath, csv) + File.write(filepath, data) + end + + def self.run(filepath: Rails.root.join("tmp", "exports", "measure_by_grade", "measure_by_grade.csv")) + data = to_csv(schools: ::School.all, academic_years: ::AcademicYear.all, measures: ::Measure.all) + write_csv(data:, filepath:) end end end diff --git a/lib/tasks/report.rake b/lib/tasks/report.rake index 43b6b811..3ece9bfe 100644 --- a/lib/tasks/report.rake +++ b/lib/tasks/report.rake @@ -184,6 +184,13 @@ namespace :report do end end + # Usage example + # bundle exec rake "report:averages_by_grade" + task averages_by_grade: :environment do + FileUtils.mkdir_p(Rails.root.join("tmp", "exports", "measure_by_grade")) + Report::MeasureByGrade.run(filepath: Rails.root.join("tmp", "exports", "measure_by_grade", "measure_by_grade.csv")) + end + # Usage example # bundle exec rake "report:survey_item_response:create[Hampden-Wilbraham,2023-24 Spring]" namespace :survey_item_response do