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

redesigned versions_controller.rb file #110

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
124 changes: 124 additions & 0 deletions app/controllers/api/v1/late_policies_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
class Api::V1::LatePoliciesController < ApplicationController
include AuthorizationHelper

before_action :set_late_policy, only: %i[show edit update destroy]

def action_allowed?
case params[:action]
when 'new', 'create', 'index'
current_user_has_ta_privileges?
when 'edit', 'update', 'destroy'
current_user_has_ta_privileges? &&
current_user.instructor_id == check_if_instructor
else
false
end
end

def index
@penalty_policies = LatePolicy.where(['instructor_id = ? OR private = 0', check_if_instructor])
render json: @penalty_policies
end

def show
render json: @penalty_policy
end

def new
@penalty_policy = LatePolicy.new
render json: @penalty_policy
end

def edit
render json: @penalty_policy
end

def create
valid_penalty, error_message = validate_input
if error_message
render json: { error: error_message }, status: :unprocessable_entity and return
end

if valid_penalty
@late_policy = LatePolicy.new(late_policy_params)
@late_policy.instructor_id = check_if_instructor
if @late_policy.save
render json: @late_policy, status: :created
else
render json: { error: 'The following error occurred while saving the late policy.' }, status: :unprocessable_entity
end
else
render json: { error: 'Validation failed' }, status: :unprocessable_entity
end
end

def update
valid_penalty, error_message = @penalty_policy.duplicate_name_check(check_if_instructor, params[:id])

if error_message
render json: { error: error_message }, status: :unprocessable_entity and return
end

if valid_penalty
if @penalty_policy.update(late_policy_params)
LatePolicy.update_calculated_penalty_objects(@penalty_policy)
render json: @penalty_policy, status: :ok
else
render json: { error: 'The following error occurred while updating the late policy.' }, status: :unprocessable_entity
end
else
render json: { error: 'Validation failed' }, status: :unprocessable_entity
end
end

def destroy
if @penalty_policy.destroy
head :no_content
else
render json: { error: 'This policy is in use and hence cannot be deleted.' }, status: :unprocessable_entity
end
end

private

def set_late_policy
@penalty_policy = LatePolicy.find(params[:id])
end

def late_policy_params
params.require(:late_policy).permit(:policy_name, :penalty_per_unit, :penalty_unit, :max_penalty)
end

def check_if_instructor
late_policy.try(:instructor_id) || current_user.instructor_id
end

def late_policy
@penalty_policy ||= @late_policy || LatePolicy.find(params[:id]) if params[:id]
end

def validate_input(is_update = false)
max_penalty = params[:late_policy][:max_penalty].to_i
penalty_per_unit = params[:late_policy][:penalty_per_unit].to_i

valid_penalty, error_message = duplicate_name_check(is_update)
prefix = is_update ? "Cannot edit the policy. " : ""

if max_penalty < penalty_per_unit
error_message = prefix + 'The maximum penalty cannot be less than penalty per unit.'
valid_penalty = false
end

if penalty_per_unit < 0
error_message = 'Penalty per unit cannot be negative.'
valid_penalty = false
end

if max_penalty >= 100
error_message = prefix + 'Maximum penalty cannot be greater than or equal to 100'
valid_penalty = false
end

return valid_penalty, error_message
end
end
54 changes: 54 additions & 0 deletions app/controllers/api/v1/versions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class Api::V1::VersionsController < ApplicationController
include AuthorizationHelper

before_action :authorize_admin!

def index
redirect_to action: :search
end

def show
@version = Version.find_by(id: params[:id])
if @version
render json: @version
else
render json: { error: 'Version not found' }, status: :not_found
end
end

def search
@per_page = (params[:num_versions] || 25).to_i

@versions = if params[:post]
paginate_list
else
Version.page(params[:page]).order('id').per(@per_page)
end

render json: @versions
end

private

def authorize_admin!
render json: { error: 'Forbidden' }, status: :forbidden unless current_user_has_admin_privileges?
end

# For filtering the versions list with proper search and pagination.
def paginate_list
versions = Version.page(params[:page]).order('id').per(@per_page)
versions = versions.where(id: params[:id]) if params[:id].to_i > 0
if current_user_has_super_admin_privileges?
versions = versions.where(whodunnit: params[:post][:user_id]) if params[:post][:user_id].to_i > 0
end
versions = versions.where(whodunnit: current_user.try(:id)) if current_user.try(:id).to_i > 0
versions = versions.where(item_type: params[:post][:item_type]) if params[:post][:item_type] && params[:post][:item_type] != 'Any'
versions = versions.where(event: params[:post][:event]) if params[:post][:event] && params[:post][:event] != 'Any'
versions = versions.where('created_at >= ? and created_at <= ?', time_to_string(params[:start_time]), time_to_string(params[:end_time])) if params[:start_time] && params[:end_time]
versions
end

def time_to_string(time)
"#{time.tr('/', '-')}:00"
end
end
41 changes: 41 additions & 0 deletions app/models/late_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class LatePolicy < ApplicationRecord
belongs_to :user

has_many :assignments, dependent: :nullify

validates :policy_name, presence: true, format: { with: /\A[A-Za-z0-9][A-Za-z0-9\s'._-]+\z/i }
validates :instructor_id, presence: true
validates :max_penalty, presence: true, numericality: { greater_than: 0, less than: 100 }
validates :penalty_per_unit, presence: true, numericality: { greater_than: 0 }
validates :penalty_unit, presence: true

def duplicate_name_check(instructor_id, current_policy_id = nil)
existing_policy = LatePolicy.find_by(policy_name: self.policy_name, instructor_id: instructor_id)

if existing_policy && (current_policy_id.nil? || existing_policy.id != current_policy_id)
error_message = "A policy with the same name #{self.policy_name} already exists."
return false, error_message
end

return true, nil
end

def self.update_calculated_penalty_objects(late_policy)
CalculatedPenalty.find_each do |pen|
participant = AssignmentParticipant.find(pen.participant_id)
assignment = participant.assignment
next unless assignment.late_policy_id == late_policy.id

penalties = calculate_penalty(pen.participant_id)
total_penalty = penalties.values.sum
case pen.deadline_type_id.to_i
when 1
pen.update(penalty_points: penalties[:submission])
when 2
pen.update(penalty_points: penalties[:review])
when 5
pen.update(penalty_points: penalties[:meta_review])
end
end
end
end