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/models/report/measure.rb

123 lines
4.7 KiB

module Report
class Measure
def self.create_report(schools: School.all.includes(:district), academic_years: AcademicYear.all, measures: ::Measure.all, filename: "measure_report.csv")
data = []
mutex = Thread::Mutex.new
data << ["Measure Name", "Measure ID", "District", "School", "School Code", "Academic Year", "Recorded Date Range", "Grades", "Student Score", "Student Zone", "Teacher Score",
"Teacher Zone", "Admin Score", "Admin Zone", "All Score (Average)", "All Score Zone"]
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|
measures.each do |measure|
respondents = Respondent.by_school_and_year(school:, academic_year:)
next if respondents.nil?
response_rate = measure.subcategory.response_rate(school:, academic_year:)
next unless response_rate.meets_student_threshold? || response_rate.meets_teacher_threshold?
score = measure.score(school:, academic_year:)
zone = measure.zone(school:, academic_year:).type.to_s.capitalize
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, measure, school, academic_year]
all_grades = respondents.enrollment_by_grade.keys
grades = "#{all_grades.first}-#{all_grades.last}"
mutex.synchronize do
data << [measure.name,
measure.measure_id,
school.district.name,
school.name,
school.dese_id,
academic_year.range,
date_range,
grades,
student_score(row:),
student_zone(row:),
teacher_score(row:),
teacher_zone(row:),
admin_score(row:),
admin_zone(row:),
score.average,
zone]
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
def self.student_score(row:)
row in [response_rate, measure, school, academic_year]
student_score = measure.student_score(school:, academic_year:).average if response_rate.meets_student_threshold?
student_score || "N/A"
end
def self.student_zone(row:)
row in [response_rate, measure, school, academic_year]
if response_rate.meets_student_threshold?
student_zone = measure.student_zone(school:,
academic_year:).type.to_s.capitalize
end
student_zone || "N/A"
end
def self.teacher_score(row:)
row in [response_rate, measure, school, academic_year]
teacher_score = measure.teacher_score(school:, academic_year:).average if response_rate.meets_teacher_threshold?
teacher_score || "N/A"
end
def self.teacher_zone(row:)
row in [response_rate, measure, school, academic_year]
if response_rate.meets_teacher_threshold?
teacher_zone = measure.teacher_zone(school:, academic_year:).type.to_s.capitalize
end
teacher_zone || "N/A"
end
def self.admin_score(row:)
row in [response_rate, measure, school, academic_year]
admin_score = measure.admin_score(school:, academic_year:).average
admin_score = "N/A" unless admin_score.present? && admin_score >= 0
admin_score
end
def self.admin_zone(row:)
row in [response_rate, measure, school, academic_year]
tmp_zone = measure.admin_zone(school:, academic_year:).type
tmp_zone == :insufficient_data ? "N/A" : tmp_zone.to_s.capitalize
end
end
end