Refactoring event states

This commit is contained in:
Chrisbr 2014-06-06 10:23:01 +02:00
parent a95a03c7e5
commit e5b588df81
12 changed files with 148 additions and 87 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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!

View file

@ -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.'

View file

@ -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}"

View file

@ -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"

View file

@ -0,0 +1,5 @@
class UpdateEventStates < ActiveRecord::Migration
def change
execute "UPDATE events SET state='new' WHERE state = 'review';"
end
end

View file

@ -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"

View file

@ -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.')