Skip to content

Commit

Permalink
WIP: Early years provider import via Journey Configuration page
Browse files Browse the repository at this point in the history
  • Loading branch information
vacabor committed Jul 31, 2024
1 parent 4dc7151 commit 5d16055
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 1 deletion.
45 changes: 45 additions & 0 deletions app/controllers/admin/eligible_ey_providers_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module Admin
class EligibleEyProvidersController < BaseAdminController
before_action :ensure_service_operator

helper_method :journey_configuration

def create
@download_form = EligibleEyProvidersForm.new
@upload_form = EligibleEyProvidersForm.new(upload_params)

if @upload_form.invalid?
render "admin/journey_configurations/edit"
else
@upload_form.importer.run
flash[:notice] = @upload_form.importer.results_message

redirect_to edit_admin_journey_configuration_path(Journeys::EarlyYearsPayment::Provider::ROUTING_NAME, eligible_ey_providers_upload: {academic_year: @upload_form.academic_year})
end
end

def show
@download_form = EligibleEyProvidersForm.new(download_params)

send_data EligibleEyProvider.csv_for_academic_year(@download_form.academic_year),
type: "text/csv",
filename: "eligible_early_years_providers_#{@download_form.academic_year}.csv"
end

private

def journey_configuration
@journey_configuration ||= Journeys::Configuration.find_by(
routing_name: Journeys::EarlyYearsPayment::Provider::ROUTING_NAME
)
end

def upload_params
params.require(:eligible_ey_providers_upload).permit(:academic_year, :file)
end

def download_params
params.require(:eligible_ey_providers_download).permit(:academic_year)
end
end
end
35 changes: 35 additions & 0 deletions app/forms/admin/eligible_ey_providers_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Admin::EligibleEyProvidersForm
include ActiveModel::Model
include ActiveModel::Attributes

attribute :academic_year, AcademicYear::Type.new
attribute :file

validates :file,
presence: {message: "Choose a CSV file of eligible EY providers to upload"}

validate :validate_importer_errors

def select_options
(0..2).map do |relative_year|
academic_year = AcademicYear.current + relative_year
OpenStruct.new(id: academic_year.to_s, name: academic_year)
end
end

def importer
@importer ||= EligibleEyProvidersImporter.new(
file,
academic_year
)
end

private

# importer is not activemodel::errors compliant
def validate_importer_errors
importer.errors.each do |error|
errors.add(:file, error)
end
end
end
28 changes: 28 additions & 0 deletions app/models/eligible_ey_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class EligibleEyProvider < ApplicationRecord
attribute :academic_year, AcademicYear::Type.new

belongs_to :local_authority

def local_authority_code
local_authority.try :code
end

def self.csv_for_academic_year(academic_year)
csv_columns = {
"Nursery Name" => :nursery_name,
"EYURN / Ofsted URN" => :urn,
"LA Code" => :local_authority_code,
"Nursery Address" => :nursery_address,
"Primary Key Contact Email Address" => :primary_key_contact_email_address,
"Secondary Contact Email Address (Optional)" => :secondary_contact_email_address
}

CSV.generate(headers: true) do |csv|
csv << csv_columns.keys

where(academic_year:).each do |row|
csv << csv_columns.values.map { |attr| row.send(attr) }
end
end
end
end
44 changes: 44 additions & 0 deletions app/models/eligible_ey_providers_importer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class EligibleEyProvidersImporter < CsvImporter::Base
import_options(
target_data_model: EligibleEyProvider,
transform_rows_with: :row_to_hash,
mandatory_headers: [
"Nursery Name",
"EYURN / Ofsted URN",
"LA Code",
"Nursery Address",
"Primary Key Contact Email Address",
"Secondary Contact Email Address (Optional)"
]
)

attr_reader :academic_year

def initialize(file, academic_year)
super(file)

@academic_year = academic_year
end

def results_message
"Replaced #{deleted_row_count} existing providers with #{rows.count} new providers"
end

private

def delete_all_scope
target_data_model.where(academic_year:)
end

def row_to_hash(row)
{
nursery_name: row.fetch("Nursery Name"),
urn: row.fetch("EYURN / Ofsted URN"),
local_authority_id: LocalAuthority.find_by(code: row.fetch("LA Code")).try(:id),
nursery_address: row.fetch("Nursery Address"),
primary_key_contact_email_address: row.fetch("Primary Key Contact Email Address"),
secondary_contact_email_address: row.fetch("Secondary Contact Email Address (Optional)"),
academic_year:
}
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<hr class="govuk-section-break govuk-section-break--m govuk-section-break--visible">

<h2 class="govuk-heading-m">
Download eligible EY providers
</h2>

<%= form_with model: @download_form, scope: :eligible_ey_providers_download, url: admin_eligible_ey_providers_path, builder: GOVUKDesignSystemFormBuilder::FormBuilder, method: :get do |f| %>
<%= f.govuk_error_summary %>

<%= f.govuk_collection_select :academic_year, f.object.select_options, :id, :name,
label: { text: "Academic year" } %>

<%= f.govuk_submit "Download CSV" %>
<% end %>

<hr class="govuk-section-break govuk-section-break--m govuk-section-break--visible">

<h2 class="govuk-heading-m">
Upload eligible EY providers
</h2>

<%= form_with model: @upload_form, scope: :eligible_ey_providers_upload, url: admin_eligible_ey_providers_path, builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %>
<%= f.govuk_error_summary %>

<%= f.govuk_collection_select :academic_year, f.object.select_options, :id, :name,
label: { text: "Academic year" } %>

<%= f.govuk_file_field :file,
label: { text: "Eligible EY providers" },
hint: { text: "This file should be a CSV" } %>

<%= f.govuk_submit "Upload CSV" %>
<% end %>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def matches?(request)

resources :journey_configurations, only: [:index, :edit, :update]
resources :levelling_up_premium_payments_awards, only: [:index, :create]
resource :eligible_ey_providers, only: [:create, :show], path: "eligible-early-years-providers"
resource :eligible_fe_providers, only: [:create, :show], path: "eligible-further-education-providers"

get "refresh-session", to: "sessions#refresh", as: :refresh_session
Expand Down
16 changes: 16 additions & 0 deletions db/migrate/20240731152713_create_eligible_ey_providers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class CreateEligibleEyProviders < ActiveRecord::Migration[7.0]
def change
create_table :eligible_ey_providers, id: :uuid do |t|
t.string :nursery_name
t.string :urn
t.references :local_authority, null: false, foreign_key: true, type: :uuid
t.string :nursery_address
t.string :primary_key_contact_email_address
t.string :secondary_contact_email_address
t.text :academic_year, limit: 9, null: false

t.timestamps
end
add_index :eligible_ey_providers, [:academic_year, :urn]
end
end
17 changes: 16 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_07_24_092519) do
ActiveRecord::Schema[7.0].define(version: 2024_07_31_152713) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
enable_extension "pgcrypto"
Expand Down Expand Up @@ -180,6 +180,20 @@
t.datetime "updated_at", null: false
end

create_table "eligible_ey_providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "nursery_name"
t.string "urn"
t.uuid "local_authority_id", null: false
t.string "nursery_address"
t.string "primary_key_contact_email_address"
t.string "secondary_contact_email_address"
t.text "academic_year", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["academic_year", "urn"], name: "index_eligible_ey_providers_on_academic_year_and_urn"
t.index ["local_authority_id"], name: "index_eligible_ey_providers_on_local_authority_id"
end

create_table "eligible_fe_providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.integer "ukprn", null: false
t.text "academic_year", null: false
Expand Down Expand Up @@ -501,6 +515,7 @@
add_foreign_key "claims", "journeys_sessions"
add_foreign_key "decisions", "dfe_sign_in_users", column: "created_by_id"
add_foreign_key "early_career_payments_eligibilities", "schools", column: "current_school_id"
add_foreign_key "eligible_ey_providers", "local_authorities"
add_foreign_key "international_relocation_payments_eligibilities", "schools", column: "current_school_id"
add_foreign_key "levelling_up_premium_payments_eligibilities", "schools", column: "current_school_id"
add_foreign_key "notes", "claims"
Expand Down

0 comments on commit 5d16055

Please sign in to comment.