diff --git a/app/controllers/gps_controller.rb b/app/controllers/gps_controller.rb
new file mode 100644
index 00000000..986ee4a6
--- /dev/null
+++ b/app/controllers/gps_controller.rb
@@ -0,0 +1,8 @@
+class GpsController < ActionController::Base
+ def index
+ respond_to do |format|
+ format.html
+ format.csv { send_data Report::Gps.to_csv }
+ end
+ end
+end
diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb
new file mode 100644
index 00000000..5ab4246c
--- /dev/null
+++ b/app/controllers/reports_controller.rb
@@ -0,0 +1,3 @@
+class ReportsController < ApplicationController
+ def index; end
+end
diff --git a/app/models/report/gps.rb b/app/models/report/gps.rb
new file mode 100644
index 00000000..ef8be041
--- /dev/null
+++ b/app/models/report/gps.rb
@@ -0,0 +1,32 @@
+module Report
+ class Gps
+ def self.to_csv
+ headers = ['School', 'Pillar', 'Indicator', 'Period', 'HALS Category', 'Measures', 'Score', 'Zone']
+ attributes = %w[school_name pillar indicator period category measure_ids score zone]
+ pillars = generate_pillars
+ CSV.generate(headers: true) do |csv|
+ csv << headers
+ pillars.each do |gps|
+ csv << attributes.map { |attr| gps.send(attr) }
+ end
+ end
+ end
+
+ def self.generate_pillars
+ schools = School.all
+ academic_years = AcademicYear.order(range: :desc).first(2)
+ periods = %w[Current Previous]
+ indicator_1 = 'Teaching'
+ measures_1 = [Measure.find_by_measure_id('1A-iii'), Measure.find_by_measure_id('1B-ii')]
+
+ [].tap do |pillars|
+ schools.each do |school|
+ academic_years.zip(periods).each do |academic_year, period|
+ pillars << Pillar.new(school:, measures: measures_1, indicator: indicator_1, period:,
+ academic_year:)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/report/pillar.rb b/app/models/report/pillar.rb
new file mode 100644
index 00000000..1d6d1448
--- /dev/null
+++ b/app/models/report/pillar.rb
@@ -0,0 +1,84 @@
+module Report
+ class Pillar
+ attr_reader :period, :measures, :indicator, :school, :academic_year
+
+ def initialize(school:, period:, measures:, indicator:, academic_year:)
+ @school = school
+ @measures = measures
+ @indicator = indicator
+ @period = period
+ @academic_year = academic_year
+ end
+
+ def school_name
+ school.name
+ end
+
+ def pillar
+ pillars[indicator.to_sym]
+ end
+
+ def score
+ measures.map do |measure|
+ measure.score(school:, academic_year:).average
+ end.flatten.compact.average
+ end
+
+ def category
+ measures.first.category.name
+ end
+
+ def measure_ids
+ measures.map(&:measure_id).join(' & ')
+ end
+
+ def zone
+ zones = Zones.new(watch_low_benchmark:,
+ growth_low_benchmark:,
+ approval_low_benchmark:,
+ ideal_low_benchmark:)
+
+ zones.zone_for_score(score).type.to_s
+ end
+
+ private
+
+ def pillars
+ { "Teaching Environment": 'Operational Efficiency',
+ "Safety": 'Safe and Welcoming Environment',
+ "Relationships": 'Safe and Welcoming Environment',
+ "Academic Orientation": 'Safe and Welcoming Environment',
+ "Facilities & Personnel": 'Operational Efficiency',
+ "Family-School Relationships": 'Family and Community Engagement',
+ "Community Involvement & External Partners": 'Family and Community Engagement',
+ "Perception of Performance": 'Academics and Student Achievement',
+ "Student Commitment To Learning": 'Academics and Student Achievement',
+ "Critical Thinking": 'Academics and Student Achievement',
+ "College & Career Readiness": 'Academics and Student Achievement' }
+ end
+
+ def watch_low_benchmark
+ measures.map do |measure|
+ measure.watch_low_benchmark
+ end.average
+ end
+
+ def growth_low_benchmark
+ measures.map do |measure|
+ measure.growth_low_benchmark
+ end.average
+ end
+
+ def approval_low_benchmark
+ measures.map do |measure|
+ measure.approval_low_benchmark
+ end.average
+ end
+
+ def ideal_low_benchmark
+ measures.map do |measure|
+ measure.ideal_low_benchmark
+ end.average
+ end
+ end
+end
diff --git a/app/views/gps/index.html.erb b/app/views/gps/index.html.erb
new file mode 100644
index 00000000..dba305ac
--- /dev/null
+++ b/app/views/gps/index.html.erb
@@ -0,0 +1,5 @@
+
GPS
+
+
+<%= link_to "GPS source of truth", 'gps.csv' %>
+
diff --git a/app/views/layouts/reports.html.erb b/app/views/layouts/reports.html.erb
new file mode 100644
index 00000000..61ac8d2d
--- /dev/null
+++ b/app/views/layouts/reports.html.erb
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+ HALS
+ <%= csp_meta_tag %>
+ <%= stylesheet_link_tag '', media: 'all', 'data-turbo-track': 'reload' %>
+ <%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/reports/index.html.erb b/app/views/reports/index.html.erb
new file mode 100644
index 00000000..5a67ca88
--- /dev/null
+++ b/app/views/reports/index.html.erb
@@ -0,0 +1,2 @@
+Reports
+<%= link_to "gps", reports_gps_path %>
diff --git a/config/routes.rb b/config/routes.rb
index 25c03ee7..653d539a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -7,6 +7,9 @@ Rails.application.routes.draw do
end
end
+ get :reports, to: 'reports#index'
+ get 'reports/gps', to: 'gps#index'
+
get '/welcome', to: 'home#index'
root to: 'home#index'
end
diff --git a/spec/models/pillar_spec.rb b/spec/models/pillar_spec.rb
new file mode 100644
index 00000000..3424b2d9
--- /dev/null
+++ b/spec/models/pillar_spec.rb
@@ -0,0 +1,76 @@
+require 'rails_helper'
+
+RSpec.describe Report::Pillar, type: :model do
+ let(:school) { create(:school, name: 'Abraham Lincoln Elementary School') }
+ let(:subcategory) { create(:subcategory, subcategory_id: '1A') }
+ let(:measure_1) { create(:measure, measure_id: '1A-iii', subcategory:) }
+ let(:measure_2) { create(:measure, measure_id: '1B-ii', subcategory:) }
+ let(:scale_1) { create(:scale, measure: measure_1) }
+ let(:scale_2) { create(:scale, measure: measure_2) }
+ let(:survey_item_1) { create(:student_survey_item, scale: scale_1) }
+ let(:survey_item_2) do
+ create(:student_survey_item, scale: scale_2, ideal_low_benchmark: 5)
+ end
+ let(:measures) do
+ subcategory.measures
+ end
+ let(:academic_year_1) { create(:academic_year, range: '2017-2018') }
+ let(:academic_year_2) { create(:academic_year, range: '2018-2019') }
+ let(:academic_years) { [academic_year_1, academic_year_2] }
+
+ before :each do
+ create(:respondent, school:, academic_year: academic_year_1)
+ create(:survey, school:, academic_year: academic_year_1)
+ measures
+ end
+
+ context '.pillar' do
+ it 'returns the GPS pillar' do
+ pillar = Report::Pillar.new(school:, measures:, indicator: 'Teaching Environment',
+ period: 'Current', academic_year: academic_year_1)
+ expect(pillar.pillar).to eq('Operational Efficiency')
+ end
+ end
+
+ context '.school' do
+ it 'returns the name of the school' do
+ pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
+ academic_year: academic_year_1)
+ expect(pillar.school_name).to eq('Abraham Lincoln Elementary School')
+ end
+ end
+
+ context '.score' do
+ before do
+ create(:survey_item_response, survey_item: survey_item_1, school:, academic_year: academic_year_1,
+ likert_score: 3)
+ create(:survey_item_response, survey_item: survey_item_1, school:, academic_year: academic_year_1,
+ likert_score: 5)
+ end
+ it 'returns the average score for all the measures in the pillar' do
+ pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
+ academic_year: academic_year_1)
+ expect(pillar.score).to eq 4
+ end
+ end
+
+ context '.zone' do
+ before do
+ create(:survey_item_response, survey_item: survey_item_1, school:, academic_year: academic_year_1,
+ likert_score: 4)
+ create(:survey_item_response, survey_item: survey_item_1, school:, academic_year: academic_year_1,
+ likert_score: 5)
+ create(:survey_item_response, survey_item: survey_item_2, school:, academic_year: academic_year_1,
+ likert_score: 4)
+ create(:survey_item_response, survey_item: survey_item_2, school:, academic_year: academic_year_1,
+ likert_score: 5)
+ end
+
+ it 'returns the zone for the average score for all the measures in the pillar' do
+ pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
+ academic_year: academic_year_1)
+ expect(pillar.score).to eq 4.5
+ expect(pillar.zone).to eq 'approval'
+ end
+ end
+end
diff --git a/spec/models/report b/spec/models/report
new file mode 100644
index 00000000..e69de29b
diff --git a/spec/requests/report_spec.rb b/spec/requests/report_spec.rb
new file mode 100644
index 00000000..26409b49
--- /dev/null
+++ b/spec/requests/report_spec.rb
@@ -0,0 +1,7 @@
+require 'rails_helper'
+
+RSpec.describe "Reports", type: :request do
+ describe "GET /index" do
+ pending "add some examples (or delete) #{__FILE__}"
+ end
+end