@@ -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
260269end
0 commit comments