class ChallengeAssignmentsController < ApplicationController before_action :users_only before_action :load_collection, except: [:index] before_action :load_challenge, except: [:index] before_action :collection_owners_only, except: [:index, :show, :default] before_action :load_assignment_from_id, only: [:show, :default] before_action :owner_only, only: [:default] before_action :check_signup_closed, except: [:index] before_action :check_assignments_not_sent, only: [:generate, :set, :send_out] before_action :check_assignments_sent, only: [:default, :purge, :confirm_purge] # PERMISSIONS AND STATUS CHECKING def load_challenge @challenge = @collection.challenge if @collection no_challenge unless @challenge end def no_challenge flash[:error] = t('challenge_assignments.no_challenge', default: "What challenge did you want to work with?") redirect_to collection_path(@collection) rescue redirect_to '/' false end def load_assignment_from_id @challenge_assignment = @collection.assignments.find(params[:id]) end def owner_only return if current_user == @challenge_assignment.offering_pseud.user flash[:error] = t("challenge_assignments.validation.not_owner") redirect_to root_path end def check_signup_closed signup_open and return unless !@challenge.signup_open end def signup_open flash[:error] = t('challenge_assignments.signup_open', default: "Signup is currently open, you cannot make assignments now.") redirect_to @collection rescue redirect_to '/' false end def check_assignments_not_sent assignments_sent and return unless @challenge.assignments_sent_at.nil? end def assignments_sent flash[:error] = t('challenge_assignments.assignments_sent', default: "Assignments have already been sent! If necessary, you can purge them.") redirect_to collection_assignments_path(@collection) rescue redirect_to '/' false end def check_assignments_sent assignments_not_sent and return unless @challenge.assignments_sent_at end def assignments_not_sent flash[:error] = t('challenge_assignments.assignments_not_sent', default: "Assignments have not been sent! You might want matching instead.") redirect_to collection_path(@collection) rescue redirect_to '/' false end # ACTIONS def index if params[:user_id] && (@user = User.find_by(login: params[:user_id])) if current_user == @user if params[:collection_id] && (@collection = Collection.find_by(name: params[:collection_id])) @challenge_assignments = @user.offer_assignments.in_collection(@collection).undefaulted + @user.pinch_hit_assignments.in_collection(@collection).undefaulted else @challenge_assignments = @user.offer_assignments.undefaulted + @user.pinch_hit_assignments.undefaulted end else flash[:error] = ts("You aren't allowed to see that user's assignments.") redirect_to '/' and return end else # do error-checking for the collection case return unless load_collection @challenge = @collection.challenge if @collection signup_open and return unless !@challenge.signup_open access_denied and return unless @challenge.user_allowed_to_see_assignments?(current_user) # we temporarily are ordering by requesting pseud to avoid left join @assignments = case when params[:pinch_hit] # order by pinch hitter name ChallengeAssignment.unfulfilled_in_collection(@collection).undefaulted.with_pinch_hitter.joins("INNER JOIN pseuds ON (challenge_assignments.pinch_hitter_id = pseuds.id)").order("pseuds.name") when params[:fulfilled] @collection.assignments.fulfilled.order_by_requesting_pseud when params[:unfulfilled] ChallengeAssignment.unfulfilled_in_collection(@collection).undefaulted.order_by_requesting_pseud else @collection.assignments.defaulted.uncovered.order_by_requesting_pseud end @assignments = @assignments.page(params[:page]) end end def show unless @challenge.user_allowed_to_see_assignments?(current_user) || @challenge_assignment.offering_pseud.user == current_user flash[:error] = ts("You aren't allowed to see that assignment!") redirect_to "/" and return end if @challenge_assignment.defaulted? flash[:notice] = ts("This assignment has been defaulted-on.") end end def generate # regenerate assignments using the current potential matches ChallengeAssignment.generate(@collection) flash[:notice] = ts("Beginning regeneration of assignments. This may take some time, especially if your challenge is large.") redirect_to collection_potential_matches_path(@collection) end def send_out no_giver_count = @collection.assignments.with_request.with_no_offer.count no_recip_count = @collection.assignments.with_offer.with_no_request.count if (no_giver_count + no_recip_count) > 0 flash[:error] = ts("Some participants still aren't assigned. Please either delete them or match them to a placeholder before sending out assignments.") redirect_to collection_potential_matches_path(@collection) else ChallengeAssignment.send_out(@collection) flash[:notice] = "Assignments are now being sent out." redirect_to collection_assignments_path(@collection) end end def set # update all the assignments all_assignment_params = challenge_assignment_params @assignments = [] @collection.assignments.where(id: all_assignment_params.keys).each do |assignment| assignment_params = all_assignment_params[assignment.id.to_s] @assignments << assignment unless assignment.update(assignment_params) end ChallengeAssignment.update_placeholder_assignments!(@collection) if @assignments.empty? flash[:notice] = "Assignments updated" redirect_to collection_potential_matches_path(@collection) else flash[:error] = ts("These assignments could not be saved because the two participants do not match. Did you mean to write in a giver?") render template: "potential_matches/index" end end def confirm_purge end def purge ChallengeAssignment.clear!(@collection) @challenge.assignments_sent_at = nil @challenge.save flash[:notice] = ts("Assignments purged!") redirect_to collection_path(@collection) end def update_multiple @errors = [] params.each_pair do |key, val| action, id = key.split(/_/) next unless %w(approve default undefault cover).include?(action) assignment = @collection.assignments.find_by(id: id) unless assignment @errors << ts("Couldn't find assignment with id #{id}!") next end case action when "default" # default_assignment_id = y/n assignment.default || (@errors << ts("We couldn't default the assignment for %{offer}", offer: assignment.offer_byline)) when "undefault" # undefault_[assignment_id] = y/n - if set, undefault assignment.defaulted_at = nil assignment.save || (@errors << ts("We couldn't undefault the assignment covering %{request}.", request: assignment.request_byline)) when "approve" assignment.get_collection_item.approve_by_collection if assignment.get_collection_item when "cover" # cover_[assignment_id] = pinch hitter pseud next if val.blank? || assignment.pinch_hitter.try(:byline) == val pseud = Pseud.parse_byline(val) if pseud.nil? @errors << ts("We couldn't find the user %{val} to assign that to.", val: val) else assignment.cover(pseud) || (@errors << ts("We couldn't assign %{val} to cover %{request}.", val: val, request: assignment.request_byline)) end end end if @errors.empty? flash[:notice] = "Assignment updates complete!" redirect_to collection_assignments_path(@collection) else flash[:error] = @errors redirect_to collection_assignments_path(@collection) end end def default_all # mark all unfulfilled assignments as defaulted unfulfilled_assignments = ChallengeAssignment.unfulfilled_in_collection(@collection).readonly(false) unfulfilled_assignments.update_all defaulted_at: Time.now flash[:notice] = "All unfulfilled assignments marked as defaulting." redirect_to collection_assignments_path(@collection) end def default @challenge_assignment.defaulted_at = Time.now @challenge_assignment.save assignments_page_url = collection_assignments_url(@challenge_assignment.collection) @challenge_assignment.collection.notify_maintainers_challenge_default(@challenge_assignment, assignments_page_url) flash[:notice] = "We have notified the collection maintainers that you had to default on your assignment." redirect_to user_assignments_path(current_user) end private def challenge_assignment_params params.slice(:challenge_assignments).permit( challenge_assignments: [ :request_signup_pseud, :offer_signup_pseud, :pinch_hitter_byline ] ).require(:challenge_assignments) end end