diff --git a/app/controllers/score_items_controller.rb b/app/controllers/score_items_controller.rb index 0b67381489..7719a046f8 100644 --- a/app/controllers/score_items_controller.rb +++ b/app/controllers/score_items_controller.rb @@ -22,6 +22,54 @@ def copy end end + def upload + return render json: { message: I18n.t('course_members.upload_labels_csv.no_file') }, status: :unprocessable_entity if params[:upload].nil? || params[:upload][:file] == 'undefined' || params[:upload][:file].nil? + + file = params[:upload][:file] + + @evaluation_exercise = EvaluationExercise.find(params[:evaluation_exercise_id]) + authorize @evaluation_exercise, :update? + + begin + headers = CSV.foreach(file.path).first + %w[name maximum].each do |column| + return render json: { message: I18n.t('course_members.upload_labels_csv.missing_column', column: column) }, status: :unprocessable_entity unless headers&.include?(column) + end + + ScoreItem.transaction do + # Remove existing score items. + @evaluation_exercise.score_items.destroy_all + + CSV.foreach(file.path, headers: true) do |row| + row = row.to_hash + score_item = ScoreItem.new( + name: row['name'], + maximum: row['maximum'], + visible: row.key?('visible') ? row['visible'] : true, + description: row.key?('description') ? row['description'] : nil, + evaluation_exercise: @evaluation_exercise + ) + + score_item.save! + end + end + rescue CSV::MalformedCSVError, ActiveRecord::RecordInvalid + return render json: { message: I18n.t('course_members.upload_labels_csv.malformed') }, status: :unprocessable_entity + end + + respond_to do |format| + format.js { render 'score_items/index', locals: { new: nil, evaluation_exercise: @evaluation_exercise.reload } } + format.json { head :no_content } + end + end + + def index + @evaluation_exercise = EvaluationExercise.find(params[:evaluation_exercise_id]) + authorize @evaluation_exercise, :show? + + @score_items = policy_scope(@evaluation_exercise.score_items) + end + def create @score_item = ScoreItem.new(permitted_attributes(ScoreItem)) @score_item.last_updated_by = current_user diff --git a/app/models/score_item.rb b/app/models/score_item.rb index b7031b95da..ad4fa6c6e5 100644 --- a/app/models/score_item.rb +++ b/app/models/score_item.rb @@ -22,6 +22,7 @@ class ScoreItem < ApplicationRecord after_update :uncomplete_feedbacks_if_maximum_changed validates :maximum, numericality: { greater_than: 0, less_than: 1000 } + validates :name, presence: true default_scope { order(id: :asc) } diff --git a/app/policies/evaluation_exercise_policy.rb b/app/policies/evaluation_exercise_policy.rb index 43d72dcac2..1c1d58addb 100644 --- a/app/policies/evaluation_exercise_policy.rb +++ b/app/policies/evaluation_exercise_policy.rb @@ -6,6 +6,18 @@ def show_total? record.visible_score? && record.evaluation.released? end + def show? + return true if course_admin? + + return false unless evaluation_member? + + record&.visible_score? && record&.evaluation&.released? + end + + def update? + course_admin? + end + def permitted_attributes %i[visible_score] end @@ -16,4 +28,8 @@ def course_admin? course = record&.evaluation&.series&.course user&.course_admin?(course) end + + def evaluation_member? + record&.evaluation&.users&.include?(user) + end end diff --git a/app/views/score_items/_exercise.html.erb b/app/views/score_items/_exercise.html.erb index 4d88cf0b35..6e7000d8b4 100644 --- a/app/views/score_items/_exercise.html.erb +++ b/app/views/score_items/_exercise.html.erb @@ -2,8 +2,30 @@ <%= javascript_include_tag 'score_item' %> <% end %> <% maximum_score = evaluation_exercise.maximum_score %> -