Skip to content

Commit e6d1f2c

Browse files
author
Mateo
committed
TICKET-604: Default back to csv and clean up code
1 parent 7a88251 commit e6d1f2c

2 files changed

Lines changed: 65 additions & 66 deletions

File tree

app/controllers/api/grade_entry_forms_controller.rb

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ module Api
22
class GradeEntryFormsController < MainApiController
33
DEFAULT_FIELDS = [:id, :short_identifier, :description, :due_date, :is_hidden, :visible_on, :visible_until,
44
:show_total].freeze
5+
STUDENT_FIELDS = [:user_name, :last_name, :first_name, :id_number, :email].freeze
56

6-
# Returns the specified grade entry form with all grade data
7+
# Returns the specified grade entry form
78
# Requires: id
8-
# Optional: user_name (filter to a single student), download=csv (export as CSV)
9+
# Default: returns CSV export (backward compatible)
10+
# Optional: .json extension or Accept: application/json header for structured JSON with student grades
11+
# user_name (filter to a single student, JSON only)
912
def show
1013
grade_entry_form = record
1114
if grade_entry_form.nil?
@@ -14,61 +17,15 @@ def show
1417
return
1518
end
1619

17-
if params[:download] == 'csv'
18-
send_data grade_entry_form.export_as_csv(current_role),
19-
type: 'text/csv',
20-
filename: "#{grade_entry_form.short_identifier}_grades_report.csv",
21-
disposition: 'inline'
20+
if request.format.json?
21+
render_json_show(grade_entry_form)
2222
return
2323
end
2424

25-
grade_entry_items = grade_entry_form.grade_entry_items.order(:position)
26-
27-
students_query = Student.left_outer_joins(:grade_entry_students, :user, :section)
28-
.where(hidden: false, 'grade_entry_students.assessment_id': grade_entry_form.id)
29-
students_query = students_query.where('users.user_name': params[:user_name]) if params[:user_name].present?
30-
students = students_query.order(:user_name)
31-
.pluck_to_hash(:user_name, :last_name, :first_name, 'sections.name as section_name',
32-
:id_number, :email, 'grade_entry_students.id as ges_id')
33-
34-
if params[:user_name].present? && students.empty?
35-
render 'shared/http_status', locals: { code: '422', message:
36-
'No student with that user_name' }, status: :unprocessable_content
37-
return
38-
end
39-
40-
grades_query = grade_entry_form.grades
41-
.joins(:grade_entry_item, grade_entry_student: :user)
42-
grades_query = grades_query.where('users.user_name': params[:user_name]) if params[:user_name].present?
43-
grade_data = grades_query.pluck('users.user_name', 'grade_entry_items.name', :grade)
44-
.group_by { |g| g[0] }
45-
46-
total_grades = GradeEntryStudent.get_total_grades(students.pluck(:ges_id))
47-
48-
student_data = students.map do |student|
49-
grades_hash = {}
50-
grade_data[student[:user_name]]&.each { |g| grades_hash[g[1]] = g[2] }
51-
entry = {
52-
user_name: student[:user_name],
53-
first_name: student[:first_name],
54-
last_name: student[:last_name],
55-
id_number: student[:id_number],
56-
email: student[:email],
57-
section_name: student[:section_name],
58-
grades: grades_hash
59-
}
60-
entry[:total_grade] = total_grades[student[:ges_id]] if grade_entry_form.show_total
61-
entry
62-
end
63-
64-
form_data = grade_entry_form.as_json(only: DEFAULT_FIELDS)
65-
form_data['grade_entry_items'] = grade_entry_items.as_json(only: [:id, :name, :out_of, :bonus])
66-
form_data['students'] = student_data
67-
68-
respond_to do |format|
69-
format.xml { render xml: form_data.to_xml(root: 'grade_entry_form', skip_types: 'true') }
70-
format.json { render json: form_data }
71-
end
25+
send_data grade_entry_form.export_as_csv(current_role),
26+
type: 'text/csv',
27+
filename: "#{grade_entry_form.short_identifier}_grades_report.csv",
28+
disposition: 'inline'
7229
end
7330

7431
def index
@@ -256,5 +213,57 @@ def destroy
256213
message: 'Grade Entry Form contains non-nil grades' }, status: :conflict
257214
end
258215
end
216+
217+
private
218+
219+
def render_json_show(grade_entry_form)
220+
filter_user = params[:user_name].presence
221+
222+
students = fetch_students(grade_entry_form, filter_user)
223+
if filter_user && students.empty?
224+
render 'shared/http_status', locals: { code: '422', message:
225+
'No student with that user_name' }, status: :unprocessable_content
226+
return
227+
end
228+
229+
grades_by_user = fetch_grades_by_user(grade_entry_form, filter_user)
230+
total_grades = grade_entry_form.show_total ? GradeEntryStudent.get_total_grades(students.pluck(:ges_id)) : {}
231+
232+
form_data = grade_entry_form.as_json(only: DEFAULT_FIELDS)
233+
form_data['grade_entry_items'] = grade_entry_form.grade_entry_items.order(:position)
234+
.as_json(only: [:id, :name, :out_of, :bonus])
235+
form_data['students'] = build_student_data(students, grades_by_user, total_grades,
236+
include_total: grade_entry_form.show_total)
237+
238+
render json: form_data
239+
end
240+
241+
def fetch_students(grade_entry_form, filter_user)
242+
query = Student.left_outer_joins(:grade_entry_students, :user, :section)
243+
.where(hidden: false, 'grade_entry_students.assessment_id': grade_entry_form.id)
244+
query = query.where('users.user_name': filter_user) if filter_user
245+
query.order(:user_name)
246+
.pluck_to_hash(:user_name, :last_name, :first_name, 'sections.name as section_name',
247+
:id_number, :email, 'grade_entry_students.id as ges_id')
248+
end
249+
250+
def fetch_grades_by_user(grade_entry_form, filter_user)
251+
query = grade_entry_form.grades.joins(:grade_entry_item, grade_entry_student: :user)
252+
query = query.where('users.user_name': filter_user) if filter_user
253+
query.pluck('users.user_name', 'grade_entry_items.name', :grade)
254+
.group_by { |user_name, _item, _grade| user_name }
255+
.transform_values { |rows| rows.to_h { |_user, item, grade| [item, grade] } }
256+
end
257+
258+
def build_student_data(students, grades_by_user, total_grades, include_total:)
259+
students.map do |student|
260+
entry = student.slice(*STUDENT_FIELDS).merge(
261+
section_name: student[:section_name],
262+
grades: grades_by_user.fetch(student[:user_name], {})
263+
)
264+
entry[:total_grade] = total_grades[student[:ges_id]] if include_total
265+
entry
266+
end
267+
end
259268
end
260269
end

spec/controllers/api/grade_entry_forms_controller_spec.rb

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -279,18 +279,8 @@
279279
end
280280
end
281281

282-
context 'expecting an xml response' do
283-
before { request.env['HTTP_ACCEPT'] = 'application/xml' }
284-
285-
it 'returns xml with grade_entry_form root' do
286-
get :show, params: { id: grade_entry_form.id, course_id: course.id }
287-
expect(response).to have_http_status(:ok)
288-
expect(Hash.from_xml(response.body)).to have_key('grade_entry_form')
289-
end
290-
end
291-
292-
it 'returns CSV when download=csv' do
293-
get :show, params: { id: grade_entry_form.id, course_id: course.id, download: 'csv' }
282+
it 'returns CSV by default' do
283+
get :show, params: { id: grade_entry_form.id, course_id: course.id }
294284
expect(response).to have_http_status(:ok)
295285
expect(response.content_type).to include('text/csv')
296286
end

0 commit comments

Comments
 (0)