Skip to content

Commit 63f29cf

Browse files
authored
Merge pull request #74 from cs169/tentative_accept
Tentative accept
2 parents f00b39f + cc42290 commit 63f29cf

23 files changed

Lines changed: 434 additions & 65 deletions

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ GEM
672672
turbolinks-source (5.2.0)
673673
tzinfo (2.0.6)
674674
concurrent-ruby (~> 1.0)
675-
tzinfo-data (1.2025.3)
675+
tzinfo-data (1.2026.1)
676676
tzinfo (>= 1.0.0)
677677
uglifier (4.2.0)
678678
execjs (>= 0.3.0, < 3)
@@ -832,7 +832,7 @@ DEPENDENCIES
832832
whenever
833833

834834
RUBY VERSION
835-
ruby 3.3.8p144
835+
ruby 3.3.10p183
836836

837837
BUNDLED WITH
838838
2.5.6

app/controllers/admin/conferences_controller.rb

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ def new
7171
source = Conference.find_by(short_title: params[:duplicate_from])
7272
if source && can?(:read, source)
7373
@conference = Conference.new(
74-
description: source.description,
75-
timezone: source.timezone,
76-
start_hour: source.start_hour,
77-
end_hour: source.end_hour,
78-
color: source.color,
79-
custom_css: source.custom_css,
80-
ticket_layout: source.ticket_layout,
74+
description: source.description,
75+
timezone: source.timezone,
76+
start_hour: source.start_hour,
77+
end_hour: source.end_hour,
78+
color: source.color,
79+
custom_css: source.custom_css,
80+
ticket_layout: source.ticket_layout,
8181
registration_limit: source.registration_limit,
82-
booth_limit: source.booth_limit,
83-
organization_id: source.organization_id
82+
booth_limit: source.booth_limit,
83+
organization_id: source.organization_id
8484
)
8585
@duplicate_from_source = source.short_title
8686
else
@@ -98,14 +98,14 @@ def create
9898
source = Conference.find_by(short_title: params[:duplicate_from])
9999
if source && can?(:read, source)
100100
@conference.assign_attributes(
101-
description: source.description,
102-
custom_css: source.custom_css,
103-
ticket_layout: source.ticket_layout,
101+
description: source.description,
102+
custom_css: source.custom_css,
103+
ticket_layout: source.ticket_layout,
104104
registration_limit: source.registration_limit,
105-
booth_limit: source.booth_limit,
106-
color: source.color,
107-
start_hour: source.start_hour,
108-
end_hour: source.end_hour
105+
booth_limit: source.booth_limit,
106+
color: source.color,
107+
start_hour: source.start_hour,
108+
end_hour: source.end_hour
109109
)
110110
end
111111
end

app/controllers/admin/emails_controller.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ def index
2828

2929
def email_params
3030
params.require(:email_settings).permit(:send_on_registration,
31-
:send_on_accepted, :send_on_rejected, :send_on_confirmed_without_registration,
31+
:send_on_accepted, :send_on_tentative_accepted, :send_on_rejected, :send_on_confirmed_without_registration,
3232
:send_on_submitted_proposal,
3333
:submitted_proposal_subject, :submitted_proposal_body,
34-
:registration_subject, :accepted_subject, :rejected_subject, :confirmed_without_registration_subject,
35-
:registration_body, :accepted_body, :rejected_body, :confirmed_without_registration_body,
34+
:registration_subject, :accepted_subject, :tentative_accepted_subject, :rejected_subject, :confirmed_without_registration_subject,
35+
:registration_body, :accepted_body, :tentative_accepted_body, :rejected_body, :confirmed_without_registration_body,
3636
:send_on_conference_dates_updated, :conference_dates_updated_subject, :conference_dates_updated_body,
3737
:send_on_conference_registration_dates_updated, :conference_registration_dates_updated_subject, :conference_registration_dates_updated_body,
3838
:send_on_venue_updated, :venue_updated_subject, :venue_updated_body,

app/controllers/admin/events_controller.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,46 @@ def new
115115
@superevents = @program.events.where(superevent: true)
116116
end
117117

118+
def preview_tentative_accept
119+
email_settings = @conference.email_settings
120+
@tentative_subject = email_settings.tentative_accepted_subject.presence
121+
default_body = email_settings.tentative_accepted_body.presence
122+
@missing_committee_review = @event.committee_review.blank?
123+
@tentative_body = EmailTemplateParser.parse_template(default_body, email_settings.get_values(@conference, @event.submitter, @event)) unless @missing_committee_review
124+
render :tentative_accept
125+
end
126+
127+
def tentative_accept
128+
email_settings = @conference.email_settings
129+
130+
if @event.committee_review.blank?
131+
flash.now[:alert] = 'Committee feedback is required before sending a tentative acceptance email.'
132+
@tentative_subject = email_settings.tentative_accepted_subject.presence
133+
email_settings.tentative_accepted_body.presence
134+
@missing_committee_review = true
135+
render :tentative_accept and return
136+
end
137+
138+
@tentative_subject = email_settings.tentative_accepted_subject.presence
139+
default_body = email_settings.tentative_accepted_body.presence
140+
@missing_committee_review = false
141+
@tentative_body = EmailTemplateParser.parse_template(default_body, email_settings.get_values(@conference, @event.submitter, @event))
142+
send_mail = email_settings.send_on_tentative_accepted
143+
144+
begin
145+
@event.tentatively_accept(send_mail: send_mail, subject: @tentative_subject, body: @tentative_body)
146+
@event.save!
147+
flash[:notice] = 'Event tentatively accepted!'
148+
redirect_to admin_conference_program_events_path(conference_id: @conference.short_title) and return
149+
rescue ActiveRecord::RecordInvalid => e
150+
flash.now[:error] = "Could not save tentative acceptance: #{e.record.errors.full_messages.join(', ')}"
151+
render :tentative_accept
152+
rescue Transitions::InvalidTransition => e
153+
flash.now[:error] = "Update state failed. #{e.message}"
154+
render :tentative_accept
155+
end
156+
end
157+
118158
def accept
119159
send_mail = @event.program.conference.email_settings.send_on_accepted
120160
subject = @event.program.conference.email_settings.accepted_subject.blank?

app/helpers/events_helper.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def difficulty_dropdown(event, difficulties, conference_id)
104104
end
105105

106106
# TODO-SNAPCON: Move to admin helper
107+
# rubocop:disable Metrics/MethodLength
107108
def state_dropdown(event, conference_id, email_settings)
108109
selection = event.state.humanize
109110
options = []
@@ -123,6 +124,12 @@ def state_dropdown(event, conference_id, email_settings)
123124
]
124125
end
125126
end
127+
if event.transition_possible? :tentatively_accept
128+
options << [
129+
'Tentatively Accept',
130+
preview_tentative_accept_admin_conference_program_event_path(conference_id, event), :get
131+
]
132+
end
126133
if event.transition_possible? :reject
127134
options << [
128135
'Reject',
@@ -159,6 +166,7 @@ def state_dropdown(event, conference_id, email_settings)
159166
end
160167
active_dropdown(selection, options)
161168
end
169+
# rubocop:enable Metrics/MethodLength
162170

163171
# TODO-SNAPCON: Move to admin helper
164172
def event_switch_checkbox(event, attribute, conference_id)
@@ -318,9 +326,10 @@ def active_dropdown(selection, options)
318326
#
319327
# Selection is the string to show by default, which is clicked to expose the
320328
# dropdown options.
321-
# Options is a list of 2-item lists; for each entry:
329+
# Options is a list of lists; for each entry:
322330
# * [0] is the text of the option,
323-
# * [1] is the link url for the options
331+
# * [1] is the link url for the option,
332+
# * [2] is the optional HTTP method symbol (defaults to :patch)
324333
content_tag('div', class: 'dropdown') do
325334
content_tag(
326335
'a',
@@ -333,7 +342,8 @@ def active_dropdown(selection, options)
333342
end +
334343
content_tag('ul', class: 'dropdown-menu') do
335344
options.collect do |option|
336-
content_tag('li', link_to(option[0], option[1], method: :patch))
345+
method = option[2] || :patch
346+
content_tag('li', link_to(option[0], option[1], method: method))
337347
end.join.html_safe
338348
end
339349
end

app/mailers/mailbot.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ def acceptance_mail(event)
5454
mail(subject: @conference.email_settings.accepted_subject, cc: @speakers)
5555
end
5656

57+
def tentative_acceptance_mail(event, subject: nil, body: nil)
58+
@user = event.submitter
59+
@conference = event.program.conference
60+
@speakers = event.speakers.map(&:email)
61+
@email_body = body.presence || @conference.email_settings.generate_event_mail(event, @conference.email_settings.tentative_accepted_body)
62+
email_subject = subject.presence || @conference.email_settings.tentative_accepted_subject
63+
64+
mail(subject: email_subject, cc: @speakers)
65+
end
66+
5767
def submitted_proposal_mail(event)
5868
@user = event.submitter
5969
@speakers = event.speakers.map(&:email)

app/models/conference.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ def copy_associations_from(source)
906906
new_room_id = old_room_id ? room_id_map[old_room_id] : nil
907907
program.tracks.create!(
908908
t.attributes.slice('name', 'short_name', 'description', 'color', 'state', 'relevance', 'start_date', 'end_date', 'cfp_active').merge(
909-
guid: SecureRandom.urlsafe_base64,
909+
guid: SecureRandom.urlsafe_base64,
910910
room_id: new_room_id
911911
)
912912
)

app/models/email_settings.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@
3636
# send_on_registration :boolean default(FALSE)
3737
# send_on_rejected :boolean default(FALSE)
3838
# send_on_submitted_proposal :boolean default(FALSE)
39+
# send_on_tentative_accepted :boolean default(FALSE)
3940
# send_on_venue_updated :boolean default(FALSE)
4041
# submitted_proposal_body :text
4142
# submitted_proposal_subject :string
43+
# tentative_accepted_body :text
44+
# tentative_accepted_subject :string
4245
# venue_updated_body :text
4346
# venue_updated_subject :string
4447
# created_at :datetime

app/models/event.rb

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class Event < ApplicationRecord
110110

111111
scope :confirmed, -> { where(state: 'confirmed') }
112112
scope :unconfirmed, -> { where(state: 'unconfirmed') }
113+
scope :tentatively_accepted, -> { where(state: 'tentatively_accepted') }
113114
scope :canceled, -> { where(state: 'canceled') }
114115
scope :withdrawn, -> { where(state: 'withdrawn') }
115116
scope :highlighted, -> { where(is_highlight: true) }
@@ -120,6 +121,7 @@ class Event < ApplicationRecord
120121
state :new
121122
state :withdrawn
122123
state :unconfirmed
124+
state :tentatively_accepted
123125
state :confirmed
124126
state :canceled
125127
state :rejected
@@ -131,7 +133,10 @@ class Event < ApplicationRecord
131133
transitions to: :withdrawn, from: %i[new unconfirmed confirmed]
132134
end
133135
event :accept do
134-
transitions to: :unconfirmed, from: [:new], on_transition: :process_acceptance
136+
transitions to: :unconfirmed, from: %i[new tentatively_accepted], on_transition: :process_acceptance
137+
end
138+
event :tentatively_accept do
139+
transitions to: :tentatively_accepted, from: [:new], on_transition: :process_tentative_acceptance
135140
end
136141
event :confirm do
137142
transitions to: :confirmed, from: :unconfirmed, on_transition: :process_confirmation
@@ -140,17 +145,18 @@ class Event < ApplicationRecord
140145
transitions to: :canceled, from: %i[unconfirmed confirmed]
141146
end
142147
event :reject do
143-
transitions to: :rejected, from: [:new], on_transition: :process_rejection
148+
transitions to: :rejected, from: %i[new tentatively_accepted], on_transition: :process_rejection
144149
end
145150
end
146151

147152
COLORS = {
148-
new: '#0000FF', # blue
149-
withdrawn: '#FF8000', # orange
150-
unconfirmed: '#FFFF00', # yellow
151-
confirmed: '#00FF00', # green
152-
canceled: '#848484', # grey
153-
rejected: '#FF0000' # red
153+
new: '#0000FF', # blue
154+
withdrawn: '#FF8000', # orange
155+
unconfirmed: '#FFFF00', # yellow
156+
tentatively_accepted: '#FFA500', # amber
157+
confirmed: '#00FF00', # green
158+
canceled: '#848484', # grey
159+
rejected: '#FF0000' # red
154160
}.freeze
155161

156162
##
@@ -245,6 +251,15 @@ def process_acceptance(options)
245251
end
246252
end
247253

254+
def process_tentative_acceptance(options)
255+
if program.conference.email_settings.send_on_tentative_accepted &&
256+
program.conference.email_settings.tentative_accepted_body &&
257+
program.conference.email_settings.tentative_accepted_subject &&
258+
options[:send_mail].present?
259+
Mailbot.tentative_acceptance_mail(self, subject: options[:subject], body: options[:body]).deliver_later
260+
end
261+
end
262+
248263
def process_rejection(options)
249264
if program.conference.email_settings.send_on_rejected &&
250265
program.conference.email_settings.rejected_body &&

app/models/user.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ def for_registration(conference)
104104
scope :comment_notifiable, lambda { |conference|
105105
joins(users_roles: :role)
106106
.where(roles: { resource_type: 'Conference',
107-
resource_id: conference.id,
108-
name: %i[organizer cfp] })
107+
resource_id: conference.id,
108+
name: %i[organizer cfp] })
109109
.where(
110110
Role.arel_table[:name]
111111
.eq('cfp')

0 commit comments

Comments
 (0)