From e5b588df81dcb56010d925eb18b388cfe8ab26f3 Mon Sep 17 00:00:00 2001 From: Chrisbr Date: Fri, 6 Jun 2014 10:23:01 +0200 Subject: [PATCH] Refactoring event states --- app/controllers/admin/events_controller.rb | 63 ++++++++++++++++--- app/controllers/proposal_controller.rb | 38 +++++++++-- app/helpers/application_helper.rb | 16 +++-- app/models/event.rb | 40 +++--------- app/models/person.rb | 10 +-- .../conference/_recent_submissions.html.haml | 2 +- app/views/admin/events/index.html.haml | 18 +++--- app/views/proposal/index.html.haml | 18 ++++-- config/routes.rb | 11 +++- .../20140605125153_update_event_states.rb | 5 ++ db/schema.rb | 2 +- spec/features/proposal_spec.rb | 12 ++-- 12 files changed, 148 insertions(+), 87 deletions(-) create mode 100644 db/migrate/20140605125153_update_event_states.rb diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 9e5b38bc..ee748da7 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -119,13 +119,24 @@ class Admin::EventsController < ApplicationController def create end - def update_state - event = Event.find(params[:id]) - if params[:send_mail] == "true" and (event.conference.email_settings.accepted_email_template.nil? or event.conference.email_settings.rejected_email_template.nil?) - redirect_to(admin_conference_events_path(:conference_id => @conference.short_title), :notice => "Update Email Template before Sending Mails") and return - end - event.send(:"#{params[:transition]}!", :send_mail => params[:send_mail]) - redirect_to(admin_conference_events_path(:conference_id => @conference.short_title), :notice => "Updated state") + def accept + update_state(params[:id], :accept, 'Event accepted!', true) + end + + def confirm + update_state(params[:id], :confirm, 'Event confirmed!') + end + + def cancel + update_state(params[:id], :cancel, 'Event canceled!') + end + + def reject + update_state(params[:id], :reject, 'Event rejected!', true) + end + + def restart + update_state(params[:id], :restart, 'Review started!') end def vote @@ -146,4 +157,42 @@ class Admin::EventsController < ApplicationController format.js end end + + private + + def update_state(id, transition, notice, mail = false) + event = Event.find(id) + if mail + check_mail_settings + end + if event + begin + if mail + event.send(transition, + send_mail: params[:send_mail]) + else + event.send(transition) + end + event.save + rescue Transitions::InvalidTransition => e + redirect_to( + admin_conference_events_path(conference_id: @conference.short_title), + notice: "Update state failed. #{e.message}") && return + end + redirect_to(admin_conference_events_path(conference_id: @conference.short_title), + notice: notice) + else + redirect_to(admin_conference_events_path(conference_id: @conference.short_title), + notice: 'Error! Could not find event!') + end + end + + def check_mail_settings + if !params[:send_mail].blank? && event && + event.conference.email_settings.rejected_email_template.nil? && + event.conference.email_settings.accepted_email_template.nil? + redirect_to(admin_conference_events_path(conference_id: @conference.short_title), + notice: 'Update Email Template before Sending Mails') && return + end + end end diff --git a/app/controllers/proposal_controller.rb b/app/controllers/proposal_controller.rb index 9234d885..6c98b95d 100644 --- a/app/controllers/proposal_controller.rb +++ b/app/controllers/proposal_controller.rb @@ -1,7 +1,7 @@ class ProposalController < ApplicationController before_filter :verify_user, :except => [:show] before_filter :setup - before_filter :verify_access, :only => [:edit, :update, :destroy, :confirm] + before_filter :verify_access, only: [:edit, :update, :destroy, :confirm, :restart] def setup @person = current_user.person if current_user @@ -34,8 +34,16 @@ class ProposalController < ApplicationController end def destroy - @person.withdraw_proposal(params[:id]) - redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :alert => 'Proposal withdrawn.') + proposal = @person.events.find_by_id(params[:id]) + if proposal + proposal.withdraw + proposal.save + redirect_to(conference_proposal_index_path(conference_id: @conference.short_title), + alert: 'Proposal withdrawn.') + else + redirect_to(conference_proposal_index_path(conference_id: @conference.short_title), + alert: 'Error! Could not find proposal!') + end end def new @@ -144,8 +152,8 @@ class ProposalController < ApplicationController def confirm if @event.transition_possible? :confirm begin - @event.confirm!(:send_mail => params[:send_mail]) - rescue Exception => e + @event.confirm! + rescue InvalidTransition => e redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :alert => "Event was NOT confirmed: #{e.message}") return end @@ -160,4 +168,24 @@ class ProposalController < ApplicationController end end + def restart + @event + if @event.transition_possible? :restart + begin + @event.restart + @event.save + rescue InvalidTransition => e + redirect_to(conference_proposal_index_path(conference_id: @conference.short_title), + alert: "Event was NOT restarted: #{e.message}") + return + end + # Success + redirect_to(conference_proposal_index_path(conference_id: @conference.short_title), + notice: 'Event was restarted. Review pending!') + else + # Error + redirect_to(conference_proposal_index_path(conference_id: @conference.short_title), + alert: 'Event was NOT restarted!') + end + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index baf1cd0d..cc90e9ee 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -18,20 +18,18 @@ module ApplicationHelper def label_for(event_state) result = '' case event_state - when 'Withdrawn' - result = 'label label-danger' - when 'Review Pending' + when 'new' result = 'label label-primary' - when 'Accepted (confirmation pending)' + when 'withdrawn' + result = 'label label-danger' + when 'unconfirmed' result = 'label label-success' - when 'Confirmed' + when 'confirmed' result = 'label label-success' - when 'Rejected' + when 'rejected' result = 'label label-warning' - when 'Cancelled' + when 'canceled' result = 'label label-danger' - when 'Submitted' - result = 'label label-primary' end result end diff --git a/app/models/event.rb b/app/models/event.rb index f4de3182..1b985c36 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -35,34 +35,29 @@ class Event < ActiveRecord::Base state_machine :initial => :new do state :new - state :review state :withdrawn - state :accepted state :unconfirmed state :confirmed state :canceled state :rejected - event :start_review do - transitions :to => :review, :from => [:new, :rejected, :canceled] + event :restart do + transitions to: :new, from: [:rejected, :withdrawn, :canceled] end event :withdraw do - transitions :to => :withdrawn, :from => [:new, :review, :unconfirmed, :confirmed] + transitions to: :withdrawn, from: [:new, :unconfirmed, :confirmed] end event :accept do - transitions :to => :unconfirmed, :from => [:new, :review], :on_transition => :process_acceptance - end - event :unconfirm do - transitions :to => :review, :from=>[:confirmed] + transitions to: :unconfirmed, from: [:new], on_transition: :process_acceptance end event :confirm do - transitions :to => :confirmed, :from => :unconfirmed, :on_transition => :process_confirmation + transitions to: :confirmed, from: :unconfirmed, on_transition: :process_confirmation end event :cancel do - transitions :to => :canceled, :from => [:unconfirmed, :confirmed] + transitions to: :canceled, from: [:unconfirmed, :confirmed] end event :reject do - transitions :to => :rejected, :from => [:new, :review], :on_transition => :process_rejection + transitions to: :rejected, from: [:new], on_transition: :process_rejection end end @@ -123,7 +118,7 @@ class Event < ActiveRecord::Base self.class.state_machine.events_for(self.current_state).include?(transition) end - def process_confirmation(options) + def process_confirmation if self.conference.email_settings.send_on_confirmed_without_registration? if self.conference.registrations.where(:person_id => self.submitter.id).first.nil? Mailbot.confirm_reminder_mail(self).deliver @@ -147,25 +142,6 @@ class Event < ActiveRecord::Base end end - def public_state - public_state = "Submitted" - case self.state - when "withdrawn" - public_state = "Withdrawn" - when "new", "review" - public_state = "Review Pending" - when "accepted", "unconfirmed" - public_state = "Accepted (confirmation pending)" - when "confirmed" - public_state = "Confirmed" - when "rejected" - public_state = "Rejected" - when "cancelled" - public_state = "Cancelled" - end - public_state - end - def abstract_word_count if self.abstract.nil? 0 diff --git a/app/models/person.rb b/app/models/person.rb index f7a1fd04..20eed8c6 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -34,14 +34,6 @@ class Person < ActiveRecord::Base end end - def withdraw_proposal id - proposal = self.events.find_by_id(id) - if !proposal.nil? - proposal.withdraw - proposal.save - end - end - def attending_conference? conference Registration.where(:conference_id => conference.id, :person_id => self.id).count @@ -49,7 +41,7 @@ class Person < ActiveRecord::Base def proposals conference - self.events.where("conference_id = ? AND state != ? AND state != ? AND event_people.event_role=?", conference.id, "withdrawn", "rejected", "submitter") + events.where('conference_id = ? AND event_people.event_role=?', conference.id, 'submitter') end def proposal_count conference diff --git a/app/views/admin/conference/_recent_submissions.html.haml b/app/views/admin/conference/_recent_submissions.html.haml index 7d298fdd..e13f559a 100644 --- a/app/views/admin/conference/_recent_submissions.html.haml +++ b/app/views/admin/conference/_recent_submissions.html.haml @@ -15,7 +15,7 @@ %td #{event.title} %td #{event.conference.title} %td - .span{'class'=>label_for(event.public_state)} #{event.public_state} + .span{'class'=>label_for(event.state)} #{event.state.humanize} - else %h5.text-warning.text-center No submissions! \ No newline at end of file diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 871bc031..2757652b 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -107,33 +107,33 @@ %ul.dropdown-menu{:role=>"menu"} - if event.transition_possible? :accept %li= link_to 'Accept event', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :accept), + accept_admin_conference_event_path(@conference.short_title, event), method: :patch, id: "accept_event_#{event.id}" - if @conference.email_settings.send_on_accepted? %li= link_to 'Accept event (without email)', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :accept, send_mail: false), + accept_admin_conference_event_path(@conference.short_title, event, send_mail: false), method: :patch, hint: 'Accept this event without sending an automated email.', id: "accept_event_without_mail_#{event.id}" - if event.transition_possible? :reject %li= link_to 'Reject event', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :reject), + reject_admin_conference_event_path(@conference.short_title, event), method: :patch, confirm: 'Are you sure?', id: "reject_event_#{event.id}" - if @conference.email_settings.send_on_rejected? %li= link_to 'Reject event (without email)', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :reject, send_mail: false), + reject_admin_conference_event_path(@conference.short_title, event, send_mail: false), method: :patch, confirm: 'Are you sure?', id: "reject_event_without_mail_#{event.id}" - - if event.transition_possible? :start_review + - if event.transition_possible? :restart %li= link_to 'Start review', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :start_review), - method: :patch, id: "review_event_#{event.id}" + restart_admin_conference_event_path(@conference.short_title, event), + method: :patch, id: "restart_event_#{event.id}" - if event.transition_possible? :confirm %li= link_to 'Confirm event', - update_state_admin_conference_event_path(@conference.short_title, event, transition: :confirm), + confirm_admin_conference_event_path(@conference.short_title, event), method: :patch, id: "confirm_event_#{event.id}", hint: 'Confirm that the speaker(s) will be present and that the event will actually take place.' - if event.transition_possible? :cancel %li= link_to 'Cancel event', - update_state_admin_conference_event_path(@conference.short_title, event, :transition => :cancel), + cancel_admin_conference_event_path(@conference.short_title, event), method: :patch, id: "cancel_event_#{event.id}", hint: 'Mark this event as cancelled. Usually this means that the speakers had to cancel their appearance.' diff --git a/app/views/proposal/index.html.haml b/app/views/proposal/index.html.haml index 629e2299..fff86416 100644 --- a/app/views/proposal/index.html.haml +++ b/app/views/proposal/index.html.haml @@ -19,7 +19,10 @@ %td = link_to event.title, conference_proposal_path(@conference.short_title, event.id) %td - = event.public_state + - if event.state == 'new' + Review pending + - else + = event.state.humanize - if event.state == 'confirmed' && event.require_registration == true (Pre-registered: #{pre_registered(event).count}) - if event.confirmed? && !@conference.user_registered?(current_user) @@ -29,10 +32,15 @@ .pull-right - if event.transition_possible? :confirm = link_to 'Confirm', - conference_proposal_confirm_path(@conference.short_title, event, send_mail: false), + conference_proposal_confirm_path(@conference.short_title, event), method: :patch, class: 'btn btn-mini btn-success', id: "confirm_proposal_#{event.id}" = link_to 'Edit', edit_conference_proposal_path(@conference.short_title, event.id), class: 'btn btn-mini btn-primary', id: "edit_proposal_#{event.id}" - = link_to 'Withdraw', conference_proposal_path(@conference.short_title, event.id), method: :delete, - confirm: 'Are you sure you want to withdraw this proposal?', class: 'btn btn-mini btn-danger', - id: "delete_proposal_#{event.id}" + - if event.transition_possible? :withdraw + = link_to 'Withdraw', conference_proposal_path(@conference.short_title, event.id), method: :delete, + confirm: 'Are you sure you want to withdraw this proposal?', class: 'btn btn-mini btn-danger', + id: "delete_proposal_#{event.id}" + - if event.state == 'withdrawn' || event.state == 'rejected' + = link_to 'Re-Submit', + conference_proposal_restart_path(@conference.short_title, event), + method: :patch, class: 'btn btn-mini btn-success', id: "review_event_#{event.id}" diff --git a/config/routes.rb b/config/routes.rb index 606b9569..e34d7e52 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,8 +53,12 @@ Osem::Application.routes.draw do resources :events do member do post :comment - patch :update_state - patch :update_track + patch :accept + patch :confirm + patch :cancel + patch :reject + patch :unconfirm + patch :restart get :vote end resource :speaker, :only => [:edit, :update] @@ -67,7 +71,8 @@ Osem::Application.routes.draw do resources :conference, only: [:show] do resources :proposal do resources :event_attachment, :controller => "event_attachments" - patch "/confirm" => "proposal#confirm" + patch '/confirm' => 'proposal#confirm' + patch '/restart' => 'proposal#restart' end resource :schedule, :only => [] do get "/" => "schedule#index" diff --git a/db/migrate/20140605125153_update_event_states.rb b/db/migrate/20140605125153_update_event_states.rb new file mode 100644 index 00000000..b4a888c6 --- /dev/null +++ b/db/migrate/20140605125153_update_event_states.rb @@ -0,0 +1,5 @@ +class UpdateEventStates < ActiveRecord::Migration + def change + execute "UPDATE events SET state='new' WHERE state = 'review';" + end +end diff --git a/db/schema.rb b/db/schema.rb index cdaa250a..2ef5c751 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140604142949) do +ActiveRecord::Schema.define(version: 20140605125153) do create_table "answers", force: true do |t| t.string "title" diff --git a/spec/features/proposal_spec.rb b/spec/features/proposal_spec.rb index ae438c5a..ebd30f86 100644 --- a/spec/features/proposal_spec.rb +++ b/spec/features/proposal_spec.rb @@ -67,15 +67,15 @@ feature Event do click_button 'New' click_link "reject_event_#{event.id}" - expect(flash).to eq('Updated state') + expect(flash).to eq('Event rejected!') click_button 'Rejected' - click_link "review_event_#{event.id}" - expect(flash).to eq('Updated state') + click_link "restart_event_#{event.id}" + expect(flash).to eq('Review started!') # Start review - click_button 'Review' + click_button 'New' click_link "accept_event_#{event.id}" - expect(flash).to eq('Updated state') + expect(flash).to eq('Event accepted!') expect(page.has_content?('Unconfirmed')).to be true sign_out @@ -83,7 +83,7 @@ feature Event do sign_in participant visit conference_proposal_index_path(conference.short_title) expect(page.has_content?('Example Proposal')).to be true - expect(page.has_content?('Accepted (confirmation pending)')).to be true + expect(page.has_content?('Unconfirmed')).to be true click_link "confirm_proposal_#{event.id}" expect(flash). to eq('Event was confirmed. Please register to attend the conference.')