Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate home page and CSV parsing logic #32

Merged
merged 7 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions app/controllers/csv_controller.rb

This file was deleted.

98 changes: 14 additions & 84 deletions app/controllers/schedules_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'csv'

# app/controllers/schedules_controller.rb
class SchedulesController < ApplicationController
before_action :set_schedule, only: %i[show destroy upload_rooms upload_instructors]
Expand Down Expand Up @@ -46,96 +44,28 @@ def destroy

def upload_rooms
if params[:room_file].present?
begin
ActiveRecord::Base.transaction do
room_data = CSV.read(params[:room_file].path, headers: true)

@schedule.rooms.destroy_all

room_data.each do |row|
Room.create!(
schedule_id: @schedule.id,
campus: row['campus'],
building_code: row['building_code'],
room_number: row['room_number'],
capacity: row['capacity'],
is_lecture_hall: row['is_lecture_hall'] == 'True',
is_learning_studio: row['is_learning_studio'] == 'True',
is_lab: row['is_lab'] == 'True',
is_active: row['is_active'] == 'True',
comments: row['comments']
)
end
end
flash[:notice] = 'Rooms successfully uploaded.'
rescue StandardError => e
flash[:alert] = "There was an error uploading the CSV file: #{e.message}"
raise e
end
# FIXME: What if the input file is malformed?
# We've erased our past data with no way to restore it
# We probably need to create a back up and restore if parsing gives an alert
@schedule.rooms.destroy_all
csv_handler = CsvHandler.new
csv_handler.upload(params[:room_file])
flash_result = csv_handler.parse_room_csv(@schedule.id)
flash[flash_result.keys.first] = flash_result.values.first
else
flash[:alert] = 'Please upload a CSV file.'
end

redirect_to schedule_path(@schedule)
end

def upload_instructors
if params[:instructor_file].present?
begin
ActiveRecord::Base.transaction do
instructor_data = CSV.read(params[:instructor_file].path)

@schedule.instructors.destroy_all
actual_headers = instructor_data[1]

required_headers = [
'anonimized ID',
'First Name',
'Last Name',
'Email',
'Teaching before 9:00 am.',
'Teaching after 3:00 pm.',
'Middle Name',
'Is there anything else we should be aware of regarding your teaching load (special course reduction, ...)' # Optional: Include if needed
]

missing_headers = required_headers - actual_headers
unless missing_headers.empty?
flash[:alert] = "Missing required headers: #{missing_headers.join(', ')}"
redirect_to schedule_path(@schedule) and return
end

instructor_data[2..].each do |row|
# Extracting values and checking for nulls
id_number = row[actual_headers.index('anonimized ID')]
first_name = row[actual_headers.index('First Name')]
last_name = row[actual_headers.index('Last Name')]
middle_name = row[actual_headers.index('Middle Name')]
email = row[actual_headers.index('Email')]
before_9 = row[actual_headers.index('Teaching before 9:00 am.')]
after_3 = row[actual_headers.index('Teaching after 3:00 pm.')]
beaware_of = row[actual_headers.index('Is there anything else we should be aware of regarding your teaching load (special course reduction, ...)')]

instructor_data = {
schedule_id: @schedule.id,
id_number: id_number,
first_name: first_name,
last_name: last_name,
middle_name: middle_name,
email: email,
before_9: before_9,
after_3: after_3,
beaware_of: beaware_of
}

Instructor.create(instructor_data)
end
end
flash[:notice] = 'Instructors successfully uploaded.'
rescue StandardError => e
flash[:alert] = "There was an error uploading the CSV file: #{e.message}"
raise e
end
# FIXME: See concern in upload_rooms
@schedule.instructors.destroy_all
csv_handler = CsvHandler.new
csv_handler.upload(params[:instructor_file])
flash_result = csv_handler.parse_instructor_csv(@schedule.id)
flash[flash_result.keys.first] = flash_result.values.first
else
flash[:alert] = 'Please upload a CSV file.'
end
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/welcome_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ class WelcomeController < ApplicationController

def index
return unless logged_in?

flash[:notice] = "Welcome back, #{@current_user.first_name}!" unless flash[:notice] || flash[:error]
redirect_to user_path(@current_user)
redirect_to schedules_path
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title

end
end
89 changes: 89 additions & 0 deletions app/services/csv_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

class CsvHandler
require 'csv'

def upload(file)
@file = file
end

def parse_room_csv(schedule_id)
begin
ActiveRecord::Base.transaction do
room_data = CSV.parse(@file.read, headers: true)
room_data.each do |row|
Room.create!(
schedule_id: schedule_id,
campus: row['campus'],
building_code: row['building_code'],
room_number: row['room_number'],
capacity: row['capacity'].to_i,
is_lecture_hall: row['is_lecture_hall'] == 'True',
is_learning_studio: row['is_learning_studio'] == 'True',
is_lab: row['is_lab'] == 'True',
is_active: row['is_active'] == 'True',
comments: row['comments']
)
end
end
# Flash data to be received by controller
return { notice: 'Rooms successfully uploaded.' }
rescue StandardError => e
return { alert: "There was an error uploading the CSV file: #{e.message}" }
end
end

def parse_instructor_csv(schedule_id)
begin
ActiveRecord::Base.transaction do
instructor_data = CSV.parse(@file.read)
actual_headers = instructor_data[1]
required_headers = [
'anonimized ID',
'First Name',
'Last Name',
'Email',
'Teaching before 9:00 am.',
'Teaching after 3:00 pm.',
'Middle Name',
'Is there anything else we should be aware of regarding your teaching load (special course reduction, ...)' # Optional: Include if needed
]

missing_headers = required_headers - actual_headers
unless missing_headers.empty?
return {alert: "Missing required headers: #{missing_headers.join(', ')}"}
end

instructor_data[2..].each do |row|
# Extracting values and checking for nulls
id_number = row[actual_headers.index('anonimized ID')]
first_name = row[actual_headers.index('First Name')]
last_name = row[actual_headers.index('Last Name')]
middle_name = row[actual_headers.index('Middle Name')]
email = row[actual_headers.index('Email')]
before_9 = row[actual_headers.index('Teaching before 9:00 am.')]
after_3 = row[actual_headers.index('Teaching after 3:00 pm.')]
beaware_of = row[actual_headers.index('Is there anything else we should be aware of regarding your teaching load (special course reduction, ...)')]

instructor_data = {
schedule_id: schedule_id,
id_number: id_number,
first_name: first_name,
last_name: last_name,
middle_name: middle_name,
email: email,
before_9: before_9,
after_3: after_3,
beaware_of: beaware_of
}

Instructor.create(instructor_data)
end
end
return {notice: 'Instructors successfully uploaded.'}
rescue StandardError => e
return {alert: "There was an error uploading the CSV file: #{e.message}"}
end
end

end
2 changes: 1 addition & 1 deletion app/views/schedules/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Semester:<%= @schedule.semester_name %></h5>

<%= form_with url: upload_instructors_schedule_path(@schedule), multipart: true, method: :post, local: true do |f| %>
<div class='col-4'>
<%= f.label :instructor_file, "Select Instructors Data (CSV)", class: "form-label fw-bold" %>
<%= f.label :instructor_file, "Select Instructor Data (CSV)", class: "form-label fw-bold" %>
<%= f.file_field :instructor_file, class: "form-control" %>
</div>
<div>
Expand Down
23 changes: 0 additions & 23 deletions app/views/users/show.html.erb

This file was deleted.

5 changes: 1 addition & 4 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@
get 'manifest' => 'rails/pwa#manifest', as: :pwa_manifest

# Defines the root path route ("/")
root 'welcome#index'
get 'welcome/index', to: 'welcome#index', as: 'welcome'

# Show user
get '/users/:id', to: 'users#show', as: 'user'
root 'welcome#index'

# Login/logout
get '/logout', to: 'sessions#logout', as: 'logout'
Expand Down
26 changes: 0 additions & 26 deletions features/csv_upload.feature

This file was deleted.

20 changes: 19 additions & 1 deletion features/schedules.feature
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,22 @@ Feature: Schedules page
When I visit the schedules index page
When I search for "ABCD"
Then I should not see "Test Schedule 1"
And I should not see "Another Schedule"
And I should not see "Another Schedule"

Scenario: User can upload room CSV
Given I am logged in as a user with first name "Test"
When I visit the schedules index page
And I click on the card for "Test Schedule 1"
Then I should see "Select Room Data (CSV)"
When I upload a valid room file
And I click the "Upload Room Data" button
Then I should see "Rooms successfully uploaded"

Scenario: User can upload instructor CSV
Given I am logged in as a user with first name "Test"
When I visit the schedules index page
And I click on the card for "Test Schedule 1"
Then I should see "Select Instructor Data (CSV)"
When I upload a valid instructor file
And I click the "Upload Instructor Data" button
Then I should see "Instructors successfully uploaded"
19 changes: 0 additions & 19 deletions features/step_definitions/csv_upload_steps.rb

This file was deleted.

Loading