diff --git a/app/lib/seeder.rb b/app/lib/seeder.rb index f781c366..2b17fb01 100644 --- a/app/lib/seeder.rb +++ b/app/lib/seeder.rb @@ -143,6 +143,10 @@ class Seeder StaffingLoader.clone_previous_year_data end + def seed_esp_counts(esp_file) + EspLoader.load_data(filepath: esp_file) + end + private def marked?(mark) diff --git a/app/models/respondent.rb b/app/models/respondent.rb index 55ce9249..d2e1b90b 100644 --- a/app/models/respondent.rb +++ b/app/models/respondent.rb @@ -30,4 +30,8 @@ class Respondent < ApplicationRecord def for_grade(grade) send(GRADE_SYMBOLS[grade]) end + + def total_educators + (total_teachers || 0) + (total_esp || 0) + end end diff --git a/app/presenters/teacher_response_rate_presenter.rb b/app/presenters/teacher_response_rate_presenter.rb index 94eb7e84..25534ef4 100644 --- a/app/presenters/teacher_response_rate_presenter.rb +++ b/app/presenters/teacher_response_rate_presenter.rb @@ -11,7 +11,7 @@ class TeacherResponseRatePresenter < ResponseRatePresenter def respondents_count return 0 if respondents.nil? - respondents.total_teachers + respondents.total_educators end def focus diff --git a/app/services/esp_loader.rb b/app/services/esp_loader.rb new file mode 100644 index 00000000..ade643aa --- /dev/null +++ b/app/services/esp_loader.rb @@ -0,0 +1,49 @@ +require "csv" + +class EspLoader + def self.load_data(filepath:) + respondents = [] + CSV.parse(File.read(filepath), headers: true) do |row| + row = EspRowValues.new(row:) + next unless row.school.present? && row.academic_years.size.positive? + + respondents.concat(create_esp_entry(row:)) + end + + Respondent.import respondents, batch_size: 1000, on_duplicate_key_update: [:total_esp] + end + + def self.create_esp_entry(row:) + row.academic_years.map do |academic_year| + respondent = Respondent.find_or_initialize_by(school: row.school, academic_year:) + respondent.total_esp = row.total_esp + respondent + end + end +end + +class EspRowValues + attr_reader :row + + def initialize(row:) + @row = row + end + + def school + @school ||= begin + dese_id = row["DESE ID"]&.strip.to_i + School.find_by_dese_id(dese_id) + end + end + + def academic_years + @academic_year ||= begin + year = row["Academic Year"]&.strip + AcademicYear.of_year(year) + end + end + + def total_esp + row["School Totals"]&.strip&.gsub(",", "").to_i + end +end diff --git a/data/staffing/esp_counts.csv b/data/staffing/esp_counts.csv new file mode 100644 index 00000000..66874bae --- /dev/null +++ b/data/staffing/esp_counts.csv @@ -0,0 +1,14 @@ +DESE ID,Academic Year,School Name,School Totals, +3440045,2024-25,Ambrose,16, +3440005,2024-25,Lincoln,11, +3440020,2024-25,Lynch ,25, +3440040,2024-25,Muraco,15, +3440025,2024-25,VO,18, +3440305,2024-25,McCall,14, +3440505,2024-25,WHS,14, +1850505,2024-25,Milford High School,18, +3010020,2024-25,Tyngsborough Elementary School,29, +3010305,2024-25,Tyngsborough Middle School,6, +3010505,2024-25,Tyngsborough High School,2, +1500025,2023-24,Lee Elementary School,20,TEST ONLY +1500505,2023-24,Lee Middle/High School,40,TEST ONLY diff --git a/db/migrate/20250115011457_add_total_esp_to_respondents.rb b/db/migrate/20250115011457_add_total_esp_to_respondents.rb new file mode 100644 index 00000000..43a15633 --- /dev/null +++ b/db/migrate/20250115011457_add_total_esp_to_respondents.rb @@ -0,0 +1,5 @@ +class AddTotalEspToRespondents < ActiveRecord::Migration[8.0] + def change + add_column :respondents, :total_esp, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 23802336..82843c9f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2024_11_26_005312) do +ActiveRecord::Schema[8.0].define(version: 2025_01_15_011457) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -370,6 +370,7 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_26_005312) do t.integer "ten" t.integer "eleven" t.integer "twelve" + t.integer "total_esp" t.index ["academic_year_id"], name: "index_respondents_on_academic_year_id" t.index ["school_id", "academic_year_id"], name: "index_respondents_on_school_id_and_academic_year_id", unique: true end diff --git a/db/seeds.rb b/db/seeds.rb index 1332c57b..7fe7e58e 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -10,3 +10,4 @@ seeder.seed_sqm_framework Rails.root.join("data", "sqm_framework.csv") seeder.seed_demographics Rails.root.join("data", "demographics.csv") seeder.seed_enrollment Rails.root.join("data", "enrollment", "enrollment.csv") seeder.seed_staffing Rails.root.join("data", "staffing", "staffing.csv") +seeder.seed_esp_counts Rails.root.join("data", "staffing", "esp_counts.csv") diff --git a/lib/tasks/one_off.rake b/lib/tasks/one_off.rake index f6a053e9..6d3f115e 100644 --- a/lib/tasks/one_off.rake +++ b/lib/tasks/one_off.rake @@ -60,6 +60,7 @@ namespace :one_off do seeder.seed_staffing Rails.root.join("data", "staffing", "staffing.csv") seeder.seed_staffing Rails.root.join("data", "staffing", "nj_staffing.csv") seeder.seed_staffing Rails.root.join("data", "staffing", "wi_staffing.csv") + seeder.seed_esp_counts Rails.root.join("data", "staffing", "esp_counts.csv") end desc "delete 2022-24 AcademicYear and all responses, admin data, enrollment numbers and staffing numbers" diff --git a/spec/fixtures/sample_esp_counts.csv b/spec/fixtures/sample_esp_counts.csv new file mode 100644 index 00000000..529e5e3d --- /dev/null +++ b/spec/fixtures/sample_esp_counts.csv @@ -0,0 +1,12 @@ +DESE ID,Academic Year,School Name,School Totals +3440045,2024-25,Ambrose,16 +3440005,2024-25,Lincoln,11 +3440020,2024-25,Lynch ,25 +3440040,2024-25,Muraco,15 +3440025,2024-25,VO,18 +3440305,2024-25,McCall,14 +3440505,2024-25,WHS,14 +1850505,2024-25,Milford High School,18 +3010020,2024-25,Tyngsborough Elementary School,29 +3010305,2024-25,Tyngsborough Middle School,6 +3010505,2024-25,Tyngsborough Hight School,2 diff --git a/spec/lib/seeder_spec.rb b/spec/lib/seeder_spec.rb index 76cccf1a..e90e418e 100644 --- a/spec/lib/seeder_spec.rb +++ b/spec/lib/seeder_spec.rb @@ -142,6 +142,40 @@ describe Seeder do # end # end + context "esp counts" do + context "when esp counts are loaded from a file" do + before :each do + create(:school, dese_id: 3_440_045, name: "Ambrose") + create(:school, dese_id: 3_440_005, name: "Lincoln") + create(:school, dese_id: 3_440_020, name: "Lynch") + create(:school, dese_id: 3_440_040, name: "Muraco") + create(:school, dese_id: 3_440_025, name: "VO") + create(:school, dese_id: 3_440_305, name: "McCall Elementary") + create(:school, dese_id: 3_440_505, name: "WHS") + create(:school, dese_id: 1_850_505, name: "Milford") + create(:school, dese_id: 3_010_020, name: "Tyngsborough Elemenatary") + create(:school, dese_id: 3_010_305, name: "Tyngsborough Middle") + create(:school, dese_id: 3_010_505, name: "Tyngsborough High") + create(:academic_year, range: "2024-25 Fall") + create(:academic_year, range: "2024-25 Spring") + + seeder.seed_esp_counts(sample_esp_csv) + end + + it "loads esp information into the database" do + fall = AcademicYear.find_by_range("2024-25 Fall") + spring = AcademicYear.find_by_range("2024-25 Spring") + ambrose = School.find_by_dese_id 3_440_045 + + respondents = Respondent.find_by(school: ambrose, academic_year: fall) + expect(respondents.total_esp).to eq 16 + + respondents = Respondent.find_by(school: ambrose, academic_year: spring) + expect(respondents.total_esp).to eq 16 + end + end + end + context "admin data items" do context "when deprecated admin items exist in the database" do before :each do @@ -273,4 +307,8 @@ describe Seeder do def sample_sqm_framework_csv Rails.root.join("spec", "fixtures", "sample_sqm_framework.csv") end + + def sample_esp_csv + Rails.root.join("spec", "fixtures", "sample_esp_counts.csv") + end end