diff --git a/app/models/report/beyond_learning_loss.rb b/app/models/report/beyond_learning_loss.rb new file mode 100644 index 00000000..f3a268c2 --- /dev/null +++ b/app/models/report/beyond_learning_loss.rb @@ -0,0 +1,69 @@ +module Report + class BeyondLearningLoss + def self.create_report(schools: School.all.includes(:district), academic_years: AcademicYear.all, scales: ::Scale.all, filename: "bll_report.csv") + data = [] + mutex = Thread::Mutex.new + data << ["District", "School", "School Code", "Academic Year", "Recorded Date Range", "Grades", "Measure", "Scale", + "All Score (Average)"] + pool_size = 2 + jobs = Queue.new + schools.each { |school| jobs << school } + + workers = pool_size.times.map do + Thread.new do + while school = jobs.pop(true) + academic_years.each do |academic_year| + scales.each do |scale| + respondents = Respondent.by_school_and_year(school:, academic_year:) + next if respondents.nil? + + response_rate = scale.measure.subcategory.response_rate(school:, academic_year:) + next unless response_rate.meets_student_threshold? || response_rate.meets_teacher_threshold? + + score = scale.score(school:, academic_year:) + + begin_date = SurveyItemResponse.where(school:, + academic_year:).where.not(recorded_date: nil).order(:recorded_date).first&.recorded_date&.to_date + end_date = SurveyItemResponse.where(school:, + academic_year:).where.not(recorded_date: nil).order(:recorded_date).last&.recorded_date&.to_date + date_range = "#{begin_date} - #{end_date}" + + row = [response_rate, scale, school, academic_year] + + all_grades = respondents.enrollment_by_grade.keys + grades = "#{all_grades.first}-#{all_grades.last}" + mutex.synchronize do + data << [school.district.name, + school.name, + school.dese_id, + academic_year.range, + date_range, + grades, + scale.measure.measure_id, + scale.scale_id, + score] + end + end + end + end + rescue ThreadError + end + end + + workers.each(&:join) + FileUtils.mkdir_p Rails.root.join("tmp", "reports") + filepath = Rails.root.join("tmp", "reports", filename) + write_csv(data:, filepath:) + data + end + + def self.write_csv(data:, filepath:) + csv = CSV.generate do |csv| + data.each do |row| + csv << row + end + end + File.write(filepath, csv) + end + end +end diff --git a/lib/tasks/report.rake b/lib/tasks/report.rake index c4977dc8..221a93d0 100644 --- a/lib/tasks/report.rake +++ b/lib/tasks/report.rake @@ -1,6 +1,72 @@ namespace :report do - desc 'create a report of the scores for all subcategories' + desc "create a report of the scores for all subcategories" task subcategory: :environment do - Report::Subcategory.create_report(filename: 'rpp_subcategory_report.csv') + Report::Subcategory.create_report(filename: "ecp_subcategory_report.csv") + end + + namespace :measure do + task sqm: :environment do + measure_ids = %w[ + 1A-i + 1A-ii + 1A-iii + 1B-i + 1B-ii + 2A-i + 2A-ii + 2B-i + 2B-ii + 2C-i + 2C-ii + 3A-i + 3A-ii + 3B-i + 3B-ii + 3B-iii + 3C-i + 3C-ii + 4A-i + 4B-i + 4B-ii + 4C-i + 4D-i + 4D-ii + 5A-i + 5A-ii + 5B-i + 5B-ii + 5C-i + 5C-ii + 5D-i + 5D-ii + ] + + measures = measure_ids.map { |measure_id| Measure.find_by_measure_id(measure_id) } + + Report::Measure.create_report(filename: "measure_report.csv", measures:) + end + + task bll: :environment do + measure_ids = %w[ + 2A-i + 2A-ii + 2A-ii + 2B-i + 2B-i + 2B-ii + 2C-i + 2C-ii + 2C-ii + 4B-i + 5B-i + ] + + measures = measure_ids.map { |measure_id| Measure.find_by_measure_id(measure_id) } + scales = [] + measures.each { |measure| scales << measure.scales } + scales = scales.flatten.compact + + Report::BeyondLearningLoss.create_report(filename: "bll_report.csv", scales:) + end end end