class ActivitiesController < ApplicationController include GroupsHelper include ActivitiesHelper has_activity_id = [ :show, :edit, :edit_subgroups, :update, :update_subgroups, :destroy, :presence, :change_organizer, :create_subgroup, :update_subgroup, :destroy_subgroup, :immediate_subgroups, :clear_subgroups ] before_action :set_activity_and_group, only: has_activity_id before_action :set_group, except: has_activity_id before_action :set_subgroup, only: [:update_subgroup, :destroy_subgroup] before_action :require_membership! before_action :require_leader!, only: [ :mass_new, :mass_create, :new, :create, :destroy ] before_action :require_organizer!, only: [ :edit, :update, :change_organizer, :create_subgroup, :update_subgroup, :destroy_subgroup, :edit_subgroups, :update_subgroups, :immediate_subgroups, :clear_subgroups ] # GET /groups/:id/activities # GET /activities.json def index @activities = if params[:past] @group.activities .where('start < ?', Time.zone.now) .order(start: :desc) .paginate(page: params[:page], per_page: 25) else @group.activities .where('start > ?', Time.zone.now) .order(start: :asc) .paginate(page: params[:page], per_page: 25) end end # GET /activities/1 # GET /activities/1.json def show @participants = @activity.participants .joins(:person) .order(attending: :desc) .order('people.first_name ASC') @organizers = @activity.participants .joins(:person) .where(is_organizer: true) .order('people.first_name ASC') .map { |p| p.person.full_name } .join(', ') @ownparticipant = @activity.participants .find_by(person: current_person) @counts = @activity.state_counts @num_participants = @counts.values.sum @assignable_subgroups = @activity.subgroups .where(is_assignable: true) .order(name: :asc) .pluck(:name) @subgroup_ids = @activity.subgroups .order(name: :asc) .pluck(:name, :id) @subgroup_ids.prepend([I18n.t('activities.subgroups.filter_nofilter'), 'all']) @subgroup_ids.append([I18n.t('activities.subgroups.filter_nogroup'), 'withoutgroup']) end # GET /activities/new def new @activity = Activity.new end # GET /activities/1/edit def edit set_edit_parameters! end # GET /activities/1/edit_subgroups def edit_subgroups @subgroups = @activity.subgroups.order(is_assignable: :desc, name: :asc) if @subgroups.none? flash_message(:error, I18n.t('activities.errors.cannot_subgroup_without_subgroups')) redirect_to group_activity_edit(@group, @activity) end @subgroup_options = @subgroups.map { |sg| [sg.name, sg.id] } @subgroup_options.prepend(['--', 'nil']) @participants = @activity.participants .joins(:person) .where.not(attending: false) .order(:subgroup_id) .order('people.first_name', 'people.last_name') end # POST /activities/1/update_subgroups def update_subgroups Participant.transaction do # For each key in participant_subgroups: params[:participant_subgroups].each do |k, v| # Get Participant, Subgroup p = Participant.find_by id: k sg = Subgroup.find_by id: v unless v == 'nil' # Verify that the Participant and Subgroup belong to this activity # Edit-capability is enforced by before_filter. if !p || p.activity != @activity || (!sg && v != 'nil') || (sg && sg.activity != @activity) flash_message(:danger, I18n.t(:somethingbroke)) redirect_to group_activity_edit_subgroups_path(@group, @activity) raise ActiveRecord::Rollback end p.subgroup = (sg if v != 'nil') p.save end end flash_message(:success, I18n.t('activities.subgroups.edited')) redirect_to edit_group_activity_path(@group, @activity, anchor: 'subgroups') end # POST /activities/1/immediate_subgroups def immediate_subgroups @activity.clear_subgroups! if params[:overwrite] @activity.assign_subgroups! if params[:overwrite] flash_message(:success, I18n.t('activities.subgroups.redistributed')) else flash_message(:success, I18n.t('activities.subgroups.remaining_distributed')) end redirect_to edit_group_activity_path(@group, @activity) end # POST /activities/1/clear_subgroups def clear_subgroups @activity.clear_subgroups! flash_message(:success, I18n.t('activities.subgroups.cleared')) redirect_to edit_group_activity_path(@group, @activity) end # Shared lookups for rendering the edit-view def set_edit_parameters! @non_organizers = @activity.participants.where(is_organizer: [false, nil]) @organizers = @activity.organizers @non_organizers_options = @non_organizers.map { |p| [p.person.full_name, p.id] } @organizers_options = @organizers.map { |p| [p.person.full_name, p.id] } @non_organizers_options.sort! @organizers_options.sort! @subgroup ||= Subgroup.new @subgroups = @activity.subgroups.order(is_assignable: :desc, name: :asc) end # POST /activities # POST /activities.json def create @activity = Activity.new(activity_params) @activity.group = @group respond_to do |format| if @activity.save format.html do redirect_to group_activity_url(@group, @activity) flash_message(:info, I18n.t('activities.created')) end format.json { render :show, status: :created, location: @activity } else format.html { render :new } format.json { render json: @activity.errors, status: :unprocessable_entity } end end end # Change organizer state for a Participant def change_organizer @activity = Activity.find(params[:activity_id]) @participant = @activity.participants.find(params[:participant_id]) @participant.is_organizer = params[:new_state] @participant.save message = if params[:new_state] == "true" I18n.t('activities.organizers.added', name: @participant.person.full_name) else I18n.t('activities.organizers.removed', name: @participant.person.full_name) end flash_message(:success, message) redirect_to edit_group_activity_path(@group, @activity, anchor: 'organizers-add') end # PATCH/PUT /activities/1 # PATCH/PUT /activities/1.json def update respond_to do |format| if @activity.update(activity_params) redirect = group_activity_path(@group, @activity) if params.has_key?('commit-continue') redirect = edit_group_activity_path(@group, @activity) end format.html do redirect_to redirect flash_message(:info, I18n.t('activities.updated')) end format.json { render :show, status: :ok, location: @activity } else set_edit_parameters! format.html { render :edit } format.json { render json: @activity.errors, status: :unprocessable_entity } end end end # DELETE /activities/1 # DELETE /activities/1.json def destroy @activity.destroy respond_to do |format| format.html do redirect_to group_activities_url(@group) flash_message(:info, 'Activity was successfully destroyed.') end format.json { head :no_content } end end # POST /activities/1/subgroups def create_subgroup @subgroup = Subgroup.new(subgroup_params) @subgroup.activity = @activity if @subgroup.save flash_message :success, I18n.t('activities.subgroups.created') redirect_to edit_group_activity_path(@group, @activity, anchor: 'subgroups-add') else flash_message :danger, I18n.t('activities.subgroups.create_failed') set_edit_parameters! render :edit end end # PATCH /activities/1/subgroups/:subgroup_id def update_subgroup if @subgroup.update(subgroup_params) flash_message :success, I18n.t('activities.subgroups.updated') redirect_to edit_group_activity_path(@group, @activity, anchor: 'subgroups') else flash_message :danger, I18n.t('activities.subgroups.update_failed') set_edit_parameters! render :edit end end # DELETE /activities/1/subgroups/:subgroup_id def destroy_subgroup @subgroup.destroy flash_message :success, I18n.t('activities.subgroups.destroyed') redirect_to edit_group_activity_path(@group, @activity, anchor: 'subgroups') end # PATCH/PUT /groups/:group_id/activities/:id/presence # PATCH/PUT /groups/:group_id/activities/:id/presence.json def presence participant = Participant.find_by( person_id: params[:person_id], activity: @activity ) if params[:person_id].to_i != current_person.id && !@activity.may_change?(current_person) head :forbidden return end if @activity.deadline&.past? && !@activity.may_change?(current_person) head :locked return end params[:notes] = params[:participant][:notes] if params[:participant] participant.update!(params.permit(:notes, :attending)) head :no_content end def mass_new; end def mass_create require 'csv' uploaded_io = params[:spreadsheet] result = Activity.from_csv(uploaded_io.read, @group) result.each(&:save!) flash_message(:success, I18n.t('activities.mass_imported', count: result.count)) redirect_to group_activities_path(@group) end private # The Activity's group takes precedence over whatever's in the URL, set_group not required (and can be mislead) def set_activity_and_group @activity = Activity.find(params[:id] || params[:activity_id]) @group = @activity.group end def set_group @group = Group.find(params[:group_id]) end def set_subgroup @subgroup = Subgroup.find(params[:subgroup_id]) end # Never trust parameters from the scary internet, only allow the white list through. def activity_params params.require(:activity).permit(:name, :description, :location, :start, :end, :deadline, :reminder_at, :subgroup_division_enabled, :no_response_action) end def subgroup_params params.require(:subgroup).permit(:name, :is_assignable) end end