effective_events 0.19.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/effective_events/base.js +32 -0
- data/app/controllers/effective/event_registrants_select2_ajax_controller.rb +61 -0
- data/app/controllers/effective/event_registrations_controller.rb +17 -1
- data/app/datatables/effective_event_registrants_datatable.rb +11 -11
- data/app/datatables/effective_event_registrations_datatable.rb +2 -1
- data/app/helpers/effective_events_helper.rb +2 -19
- data/app/mailers/effective/events_mailer.rb +1 -1
- data/app/models/concerns/effective_events_event_registration.rb +141 -51
- data/app/models/effective/event.rb +32 -12
- data/app/models/effective/event_notification.rb +1 -1
- data/app/models/effective/event_registrant.rb +171 -45
- data/app/models/effective/event_ticket.rb +20 -17
- data/app/models/effective/event_ticket_selection.rb +28 -0
- data/app/views/admin/event_registrants/_form.html.haml +16 -3
- data/app/views/admin/event_tickets/_form.html.haml +1 -1
- data/app/views/effective/event_registrants/_fields.html.haml +47 -28
- data/app/views/effective/event_registrations/_details.html.haml +1 -0
- data/app/views/effective/event_registrations/_fields_event_registrants.html.haml +26 -0
- data/app/views/effective/event_registrations/_fields_event_ticket_selections.html.haml +85 -0
- data/app/views/effective/event_registrations/_form_blank_registrants.html.haml +12 -14
- data/app/views/effective/event_registrations/_layout.html.haml +9 -1
- data/app/views/effective/event_registrations/billing.html.haml +1 -1
- data/app/views/effective/event_registrations/details.html.haml +10 -0
- data/app/views/effective/event_registrations/summary.html.haml +2 -2
- data/app/views/effective/event_registrations/tickets.html.haml +3 -13
- data/app/views/effective/events/show.html.haml +34 -34
- data/config/effective_events.rb +11 -4
- data/config/routes.rb +5 -0
- data/db/migrate/101_create_effective_events.rb +16 -1
- data/lib/effective_events/version.rb +1 -1
- data/lib/effective_events.rb +6 -4
- metadata +8 -7
- data/app/views/effective/event_registrants/_fields_member_only.html.haml +0 -10
- data/app/views/effective/event_registrants/_fields_member_or_non_member.html.haml +0 -34
- data/app/views/effective/event_registrants/_fields_questions.html.haml +0 -8
- data/app/views/effective/event_registrants/_fields_regular.html.haml +0 -8
- data/app/views/effective/event_registrations/_event_tickets.html.haml +0 -63
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
module Effective
|
4
4
|
class EventRegistrant < ActiveRecord::Base
|
5
|
+
include ActionView::Helpers::TagHelper
|
6
|
+
|
5
7
|
self.table_name = (EffectiveEvents.event_registrants_table_name || :event_registrants).to_s
|
6
8
|
|
7
|
-
PERMITTED_BLANK_REGISTRANT_CHANGES = ["first_name", "last_name", "email", "company", "user_id", "user_type", "
|
8
|
-
|
9
|
+
PERMITTED_BLANK_REGISTRANT_CHANGES = ["first_name", "last_name", "email", "company", "user_id", "user_type", "organization_id", "organization_type", "blank_registrant", "response1", "response2", "response3"]
|
10
|
+
|
11
|
+
attr_accessor :building_user_and_organization
|
9
12
|
|
10
13
|
acts_as_purchasable
|
11
14
|
acts_as_archived
|
@@ -14,7 +17,7 @@ module Effective
|
|
14
17
|
|
15
18
|
belongs_to :event, counter_cache: true
|
16
19
|
|
17
|
-
# Basically a category containing all the pricing and unique info about
|
20
|
+
# Basically a category containing all the pricing and unique info about this registrant
|
18
21
|
belongs_to :event_ticket
|
19
22
|
|
20
23
|
# Every event registrant is charged to a owner
|
@@ -23,20 +26,26 @@ module Effective
|
|
23
26
|
# This fee when checked out through the event registration
|
24
27
|
belongs_to :event_registration, polymorphic: true, optional: true
|
25
28
|
|
26
|
-
#
|
29
|
+
# The user for this registrant
|
27
30
|
belongs_to :user, polymorphic: true, optional: true
|
31
|
+
accepts_nested_attributes_for :user
|
32
|
+
|
33
|
+
# The organization for this registrant
|
34
|
+
belongs_to :organization, polymorphic: true, optional: true
|
35
|
+
accepts_nested_attributes_for :organization
|
28
36
|
|
29
37
|
effective_resource do
|
30
38
|
first_name :string
|
31
39
|
last_name :string
|
32
40
|
email :string
|
33
|
-
company :string
|
41
|
+
company :string # Organization name
|
34
42
|
|
35
|
-
blank_registrant
|
36
|
-
member_or_non_member_choice :string # Used by Member or Non-Member tickets to indicate a member or non-member
|
43
|
+
blank_registrant :boolean # Leave details and come back later
|
37
44
|
|
38
45
|
waitlisted :boolean
|
39
46
|
promoted :boolean # An admin marked this registrant as promoted from the waitlist
|
47
|
+
|
48
|
+
selected_at :datetime # When the event registration was selected by a user on the tickets! step
|
40
49
|
registered_at :datetime # When the order is deferred or purchased
|
41
50
|
|
42
51
|
# Question Responses
|
@@ -58,7 +67,7 @@ module Effective
|
|
58
67
|
timestamps
|
59
68
|
end
|
60
69
|
|
61
|
-
scope :sorted, -> { order(:
|
70
|
+
scope :sorted, -> { order(:event_ticket_id, :id) }
|
62
71
|
scope :deep, -> { includes(:event, :event_ticket, :owner) }
|
63
72
|
scope :registered, -> { where.not(registered_at: nil) }
|
64
73
|
|
@@ -67,12 +76,31 @@ module Effective
|
|
67
76
|
self.owner ||= event_registration.owner
|
68
77
|
end
|
69
78
|
|
70
|
-
|
71
|
-
|
72
|
-
|
79
|
+
with_options(unless: -> { purchased? && !blank_registrant_was }) do
|
80
|
+
before_validation(if: -> { blank_registrant? }) do
|
81
|
+
assign_attributes(user: nil, organization: nil, first_name: nil, last_name: nil, email: nil, company: nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
before_validation(if: -> { user.blank? }) do
|
85
|
+
assign_attributes(building_user_and_organization: true) # For member-only ticket validations
|
86
|
+
end
|
73
87
|
|
74
|
-
|
75
|
-
|
88
|
+
before_validation(if: -> { user.blank? && first_name.present? && last_name.present? && email.present? }) do
|
89
|
+
build_user() if EffectiveEvents.create_users
|
90
|
+
build_organization_and_representative() if EffectiveEvents.organization_enabled?
|
91
|
+
end
|
92
|
+
|
93
|
+
before_validation(if: -> { user.present? }) do
|
94
|
+
assign_attributes(first_name: user.first_name, last_name: user.last_name, email: (user.try(:public_email).presence || user.email))
|
95
|
+
end
|
96
|
+
|
97
|
+
before_validation(if: -> { organization.blank? && user.present? && user.class.try(:effective_memberships_organization_user?) }) do
|
98
|
+
assign_attributes(company: user.organizations.first.to_s.presence) if company.blank?
|
99
|
+
end
|
100
|
+
|
101
|
+
before_validation(if: -> { organization.present? }) do
|
102
|
+
assign_attributes(company: organization.to_s)
|
103
|
+
end
|
76
104
|
end
|
77
105
|
|
78
106
|
before_validation(if: -> { event_ticket.present? }, unless: -> { purchased? }) do
|
@@ -83,35 +111,44 @@ module Effective
|
|
83
111
|
errors.add(:waitlisted, 'is not permitted for a non-waitlist event ticket') if waitlisted? && !event_ticket.waitlist?
|
84
112
|
end
|
85
113
|
|
86
|
-
validates :user_id, uniqueness: { scope: [:event_id], allow_blank: true, message: 'is already registered for this event' }
|
87
114
|
validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
88
115
|
validates :email, email: true
|
89
116
|
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
117
|
+
# This works for persisted and adding a new one. But not adding two at same time in a registration
|
118
|
+
validates :user_id, uniqueness: { scope: [:event_id], allow_blank: true, message: 'is already registered for this event' }
|
119
|
+
|
120
|
+
# First name, last name and email are always required fields on details
|
121
|
+
validates :first_name, presence: true, if: -> { registrant_validations_enabled? }
|
122
|
+
validates :last_name, presence: true, if: -> { registrant_validations_enabled? }
|
123
|
+
validates :email, presence: true, if: -> { registrant_validations_enabled? }
|
124
|
+
|
125
|
+
# User, company and organization conditionall required
|
126
|
+
validates :user, presence: true, if: -> { registrant_validations_enabled? && EffectiveEvents.create_users }
|
127
|
+
validates :company, presence: true, if: -> { registrant_validations_enabled? && EffectiveEvents.company_or_organization_required }
|
128
|
+
validates :organization, presence: true, if: -> { registrant_validations_enabled? && EffectiveEvents.company_or_organization_required && EffectiveEvents.organization_enabled? }
|
94
129
|
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
130
|
+
# Member ticket: company name is locked in. you can only add to your own company
|
131
|
+
validate(if: -> { registrant_validations_enabled? && event_ticket&.member_only? }) do
|
132
|
+
if building_user_and_organization && owner.present? && Array(owner.try(:organizations)).exclude?(organization)
|
133
|
+
errors.add(:organization_id, "must be your own for member-only tickets")
|
134
|
+
end
|
135
|
+
|
136
|
+
errors.add(:user_id, 'must be a member to register for member-only tickets') unless member_present?
|
101
137
|
end
|
102
138
|
|
103
|
-
#
|
104
|
-
|
139
|
+
# Copy any user errors from build_user_and_organization() into the registrant
|
140
|
+
after_validation(if: -> { user && user.new_record? && user.errors.present? }) do
|
141
|
+
errors.add(:first_name, user.errors[:first_name].join(', ')) if user.errors[:first_name].present?
|
142
|
+
errors.add(:last_name, user.errors[:last_name].join(', ')) if user.errors[:last_name].present?
|
143
|
+
errors.add(:email, user.errors[:email].join(', ')) if user.errors[:email].present?
|
105
144
|
|
106
|
-
|
107
|
-
|
108
|
-
validates :last_name, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:last_name) }
|
109
|
-
validates :email, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:email) }
|
110
|
-
validates :company, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:company) }
|
145
|
+
others = user.errors.reject { |error| [:first_name, :last_name, :email].include?(error.attribute) }
|
146
|
+
errors.add(:base, others.map(&:full_message).join(', ')) if others.present?
|
111
147
|
end
|
112
148
|
|
113
|
-
|
114
|
-
|
149
|
+
# Copy any organization errors from build_user_and_organization() into the registrant
|
150
|
+
after_validation(if: -> { organization && organization.new_record? && organization.errors.present? }) do
|
151
|
+
errors.add(:company, organization.errors.full_messages.join(', '))
|
115
152
|
end
|
116
153
|
|
117
154
|
after_defer do
|
@@ -127,7 +164,7 @@ module Effective
|
|
127
164
|
end
|
128
165
|
|
129
166
|
def title
|
130
|
-
[event_ticket
|
167
|
+
["#{event_ticket} - #{name}", details.presence].compact.join(' ').html_safe
|
131
168
|
end
|
132
169
|
|
133
170
|
def name
|
@@ -140,20 +177,42 @@ module Effective
|
|
140
177
|
end
|
141
178
|
end
|
142
179
|
|
180
|
+
def details
|
181
|
+
[
|
182
|
+
(content_tag(:span, 'Member', class: 'badge badge-warning') if member_ticket?),
|
183
|
+
(content_tag(:span, 'Waitlist', class: 'badge badge-warning') if waitlisted_not_promoted?),
|
184
|
+
(content_tag(:span, 'Archived', class: 'badge badge-warning') if event_ticket&.archived?)
|
185
|
+
].compact.join(' ').html_safe
|
186
|
+
end
|
187
|
+
|
188
|
+
def purchasable_name
|
189
|
+
["#{event_ticket} - #{name}", details.presence].compact.join('<br>').html_safe
|
190
|
+
end
|
191
|
+
|
143
192
|
def last_first_name
|
144
|
-
first_name.present? ? "#{last_name}, #{first_name}" : "GUEST"
|
193
|
+
(first_name.present? && last_name.present?) ? "#{last_name}, #{first_name}" : "GUEST"
|
145
194
|
end
|
146
195
|
|
147
|
-
|
148
|
-
|
196
|
+
# We create registrants on the tickets step. But don't enforce validations until the details step.
|
197
|
+
def registrant_validations_enabled?
|
198
|
+
return false if blank_registrant? # They want to come back later
|
199
|
+
|
200
|
+
return true if event_registration.blank? # If we're creating in an Admin area
|
201
|
+
return false if event_ticket.blank? # Invalid anyway
|
202
|
+
|
203
|
+
event_registration.current_step == :details
|
149
204
|
end
|
150
205
|
|
151
|
-
def
|
152
|
-
|
206
|
+
def member_present?
|
207
|
+
user.try(:is?, :member) || organization.try(:is?, :member)
|
153
208
|
end
|
154
209
|
|
155
|
-
def
|
156
|
-
|
210
|
+
def member_ticket?
|
211
|
+
return false if event_ticket.blank?
|
212
|
+
return true if event_ticket.member_only?
|
213
|
+
return true if event_ticket.member_or_non_member? && member_present?
|
214
|
+
|
215
|
+
false
|
157
216
|
end
|
158
217
|
|
159
218
|
def present_registrant?
|
@@ -168,10 +227,19 @@ module Effective
|
|
168
227
|
event_ticket&.qb_item_name
|
169
228
|
end
|
170
229
|
|
230
|
+
def selected?
|
231
|
+
selected_at.present?
|
232
|
+
end
|
233
|
+
|
171
234
|
def registered?
|
172
235
|
registered_at.present?
|
173
236
|
end
|
174
237
|
|
238
|
+
def selected_not_expired?
|
239
|
+
return false unless EffectiveEvents.EventRegistration.selection_window.present?
|
240
|
+
selected_at.present? && (selected_at + EffectiveEvents.EventRegistration.selection_window > Time.zone.now)
|
241
|
+
end
|
242
|
+
|
175
243
|
# Called by an event_registration after_defer and after_purchase
|
176
244
|
def registered!
|
177
245
|
self.registered_at ||= Time.zone.now
|
@@ -219,10 +287,6 @@ module Effective
|
|
219
287
|
true
|
220
288
|
end
|
221
289
|
|
222
|
-
def registered?
|
223
|
-
registered_at.present?
|
224
|
-
end
|
225
|
-
|
226
290
|
def event_ticket_price
|
227
291
|
raise('expected an event') if event.blank?
|
228
292
|
raise('expected an event ticket') if event_ticket.blank?
|
@@ -246,6 +310,68 @@ module Effective
|
|
246
310
|
|
247
311
|
private
|
248
312
|
|
313
|
+
def build_user
|
314
|
+
raise('is already purchased') if purchased?
|
315
|
+
raise('expected no user') unless user.blank?
|
316
|
+
raise('expected a first_name') unless first_name.present?
|
317
|
+
raise('expected a last_name') unless last_name.present?
|
318
|
+
raise('expected a email') unless email.present?
|
319
|
+
|
320
|
+
return if user_type.blank?
|
321
|
+
|
322
|
+
# Add User
|
323
|
+
user_klass = user_type.constantize
|
324
|
+
|
325
|
+
# First we lookup the user by email. If they actually exist we ignore all other fields
|
326
|
+
existing_user = user_klass.find_by_any_email(email.strip.downcase)
|
327
|
+
|
328
|
+
if existing_user.present?
|
329
|
+
assign_attributes(user: existing_user)
|
330
|
+
|
331
|
+
if EffectiveEvents.organization_enabled? && user_klass.try(:effective_memberships_organization_user?)
|
332
|
+
assign_attributes(organization: existing_user.organizations.first) if existing_user.organizations.present?
|
333
|
+
end
|
334
|
+
else
|
335
|
+
# Otherwise create a new user
|
336
|
+
new_user = user_klass.create(
|
337
|
+
first_name: first_name.strip,
|
338
|
+
last_name: last_name.strip,
|
339
|
+
email: email.strip.downcase,
|
340
|
+
password: SecureRandom.base64(12) + '!@#123abcABC-'
|
341
|
+
)
|
342
|
+
|
343
|
+
assign_attributes(user: new_user)
|
344
|
+
end
|
345
|
+
|
346
|
+
user.valid?
|
347
|
+
end
|
348
|
+
|
349
|
+
# The organization might already be set here
|
350
|
+
def build_organization_and_representative
|
351
|
+
raise('is already purchased') if purchased?
|
352
|
+
|
353
|
+
return if organization_type.blank?
|
354
|
+
|
355
|
+
# We previously created an invalid user
|
356
|
+
return if user.present? && user.errors.present?
|
357
|
+
|
358
|
+
# Add Organization and representative
|
359
|
+
organization_klass = organization_type.constantize
|
360
|
+
|
361
|
+
# Find or create the organization
|
362
|
+
if organization.present?
|
363
|
+
user.build_representative(organization: organization) if user.present?
|
364
|
+
elsif company.present?
|
365
|
+
new_organization = organization_klass.where(title: company.strip).first
|
366
|
+
new_organization ||= organization_klass.create(title: company.strip, email: email.strip.downcase)
|
367
|
+
assign_attributes(organization: new_organization)
|
368
|
+
|
369
|
+
user.build_representative(organization: new_organization) if user.present?
|
370
|
+
end
|
371
|
+
|
372
|
+
true
|
373
|
+
end
|
374
|
+
|
249
375
|
def assign_price
|
250
376
|
raise('is already purchased') if purchased?
|
251
377
|
|
@@ -69,35 +69,38 @@ module Effective
|
|
69
69
|
validates :early_bird_price, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
|
70
70
|
|
71
71
|
validates :capacity, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
|
72
|
+
validates :capacity, presence: { message: 'must be present when using the waitlist'}, if: -> { waitlist? }
|
72
73
|
|
73
74
|
def to_s
|
74
75
|
title.presence || 'New Event Ticket'
|
75
76
|
end
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
return
|
78
|
+
def capacity_selectable(except: nil)
|
79
|
+
return nil if capacity.blank?
|
80
|
+
return nil if waitlist?
|
80
81
|
|
81
|
-
|
82
|
-
|
82
|
+
capacity_available(except: except)
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
def capacity_available(except: nil)
|
86
|
+
return nil if capacity.blank?
|
87
|
+
[(capacity - capacity_taken(except: except)), 0].max
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
90
|
+
def capacity_taken(except: nil)
|
91
|
+
registered_or_selected_event_registrants(except: except).reject(&:waitlisted?).length
|
92
|
+
end
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
+
def registered_or_selected_event_registrants(except: nil)
|
95
|
+
raise('expected except to be an EventRegistration') if except && !except.class.try(:effective_events_event_registration?)
|
94
96
|
|
95
|
-
|
97
|
+
event_registrants.select do |er|
|
98
|
+
(er.registered? || er.selected_not_expired?) && (except.blank? || er.event_registration_id != except.id)
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
|
-
def
|
99
|
-
|
100
|
-
[(capacity - registered_event_registrants_count), 0].max
|
102
|
+
def registered_or_selected_event_registrants_count
|
103
|
+
registered_or_selected_event_registrants.count
|
101
104
|
end
|
102
105
|
|
103
106
|
def registered_event_registrants_count
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Form object to select a # of tickets on the EventRegistration form
|
4
|
+
|
5
|
+
module Effective
|
6
|
+
class EventTicketSelection < ActiveRecord::Base
|
7
|
+
self.table_name = (EffectiveEvents.event_ticket_selections_table_name || :event_ticket_selections).to_s
|
8
|
+
|
9
|
+
belongs_to :event_registration, polymorphic: true
|
10
|
+
belongs_to :event_ticket
|
11
|
+
|
12
|
+
effective_resource do
|
13
|
+
quantity :integer
|
14
|
+
|
15
|
+
timestamps
|
16
|
+
end
|
17
|
+
|
18
|
+
scope :sorted, -> { order(:id) }
|
19
|
+
scope :deep, -> { includes(:event_registration, :event_ticket) }
|
20
|
+
|
21
|
+
validates :quantity, numericality: { greater_than_or_equal_to: 0 }
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
persisted? ? "#{quantity}x #{event_ticket}": model_name.human
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -9,10 +9,10 @@
|
|
9
9
|
- if f.object.new_record?
|
10
10
|
-# User
|
11
11
|
- klass = (f.object.owner || current_user).class
|
12
|
-
- ajax_url = (
|
12
|
+
- ajax_url = (effective_resources.users_admin_select2_ajax_index_path unless Rails.env.test?)
|
13
13
|
|
14
14
|
= f.hidden_field :owner_type, value: klass.name
|
15
|
-
= f.select :owner_id, klass.all, ajax_url: ajax_url, label: 'User'
|
15
|
+
= f.select :owner_id, klass.all, ajax_url: ajax_url, label: 'Registration User'
|
16
16
|
- else
|
17
17
|
= f.static_field :owner
|
18
18
|
|
@@ -20,7 +20,20 @@
|
|
20
20
|
|
21
21
|
#effective-events-event-registrant-ajax
|
22
22
|
- if f.object.event.present?
|
23
|
-
|
23
|
+
.card
|
24
|
+
.card-body
|
25
|
+
- if f.object.purchased?
|
26
|
+
= f.static_field :event_ticket, label: 'Purchased ticket'
|
27
|
+
|
28
|
+
= f.select :event_ticket_id, effective_events_event_tickets_collection(f.object.event, namespace), required: true
|
29
|
+
|
30
|
+
- if f.object.event.allow_blank_registrants? && (f.object.new_record? || f.object.blank_registrant?)
|
31
|
+
= f.check_box :blank_registrant, label: "I will return and add this ticket's information later"
|
32
|
+
- else
|
33
|
+
= f.hidden_field :blank_registrant, value: false
|
34
|
+
|
35
|
+
= f.show_if(:blank_registrant, false) do
|
36
|
+
= render('effective/event_registrants/fields', f: f)
|
24
37
|
|
25
38
|
= f.check_box :archived, label: "Archive this registrant. It will be displayed as archived on the owner's event registration"
|
26
39
|
|
@@ -11,7 +11,7 @@
|
|
11
11
|
= f.show_if(:category, 'Regular') do
|
12
12
|
.alert.alert-info.mb-4
|
13
13
|
%strong Regular Ticket:
|
14
|
-
Anyone will be able to purchase this ticket.
|
14
|
+
Anyone will be able to purchase this ticket. Only the regular price applies.
|
15
15
|
|
16
16
|
= f.show_if(:category, 'Member Only') do
|
17
17
|
.alert.alert-info.mb-4
|
@@ -1,33 +1,52 @@
|
|
1
|
-
.
|
2
|
-
.
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
.event-registrant-user-fields
|
2
|
+
- user_klass = (f.object.user || current_user).class
|
3
|
+
- ajax_url = (effective_events.users_event_registrants_select2_ajax_index_path unless Rails.env.test?)
|
4
|
+
- disabled = (f.object.user.present? && f.object.user.persisted? && f.object.user.errors.blank?)
|
5
|
+
- event_ticket = f.object.event_ticket
|
6
|
+
|
7
|
+
= f.hidden_field :user_type, value: user_klass.name
|
8
|
+
|
9
|
+
= f.select :user_id, user_klass.all, ajax_url: ajax_url, label: "Quick add", placeholder: "Search by name, email, or company",
|
10
|
+
hint: "Can't find someone? Add their details below.", input_js: { minimumInputLength: 1 }, 'data-event-registrant-user-search': true
|
11
|
+
|
12
|
+
.row
|
13
|
+
.col-md= f.text_field :first_name, input_html: { disabled: disabled }
|
14
|
+
.col-md= f.text_field :last_name, input_html: { disabled: disabled }
|
15
|
+
|
16
|
+
.row
|
17
|
+
.col-md= f.email_field :email, input_html: { disabled: disabled }
|
18
|
+
.col-md
|
19
|
+
= f.hidden_field :organization_type
|
20
|
+
= f.hidden_field :organization_id
|
21
|
+
|
22
|
+
- if EffectiveEvents.organization_enabled? == false
|
23
|
+
= f.text_field :company, input_html: { disabled: disabled }
|
24
|
+
|
25
|
+
- if EffectiveEvents.organization_enabled?
|
26
|
+
= f.hidden_field :organization_type, value: EffectiveMemberships.Organization.name
|
27
|
+
|
28
|
+
- organizations = EffectiveMemberships.Organization.sorted.all
|
29
|
+
|
30
|
+
- if event_ticket&.member_only?
|
31
|
+
- organization_id = (f.object.event_registration&.owner || current_user).try(:organizations).try(:first).try(:id)
|
32
|
+
|
33
|
+
= f.select :organization_id, organizations, label: organization_label, placeholder: 'Search by name', input_html: { disabled: disabled },
|
34
|
+
input_js: { minimumInputLength: 1 },
|
35
|
+
hint: "You can only add new members to your own #{organization_label.downcase}",
|
36
|
+
value: (organization_id if organization_id && f.object.organization_id.blank?)
|
17
37
|
- else
|
18
|
-
|
38
|
+
- # This creates a select field organization_id and a text field company
|
39
|
+
= f.select_or_text :organization_id, :company, organizations, name: organization_label.downcase, input_html: { disabled: disabled },
|
40
|
+
text: { label: "#{organization_label} name", placeholder: "New #{organization_label.downcase} name" },
|
41
|
+
select: { label: organization_label, placeholder: 'Search by name', input_js: { minimumInputLength: 1 } }
|
19
42
|
|
20
|
-
|
21
|
-
|
43
|
+
- if event_ticket.present?
|
44
|
+
- if event_ticket.question1.present?
|
45
|
+
= f.text_field :response1, label: event_ticket.question1
|
22
46
|
|
23
|
-
|
24
|
-
|
25
|
-
- elsif ticket.member_only?
|
26
|
-
= render('effective/event_registrants/fields_member_only', f: f)
|
27
|
-
- elsif ticket.member_or_non_member?
|
28
|
-
= render('effective/event_registrants/fields_member_or_non_member', f: f)
|
29
|
-
- else
|
30
|
-
- raise("Unexpected ticket category: #{ticket.category || 'nil'}")
|
47
|
+
- if event_ticket.question2.present?
|
48
|
+
= f.text_field :response2, label: event_ticket.question2
|
31
49
|
|
32
|
-
|
50
|
+
- if event_ticket.question3.present?
|
51
|
+
= f.text_field :response3, label: event_ticket.question3
|
33
52
|
|
@@ -0,0 +1 @@
|
|
1
|
+
-# Intentionally blank
|
@@ -0,0 +1,26 @@
|
|
1
|
+
- # Displayed on the details step
|
2
|
+
- event = form.object.event
|
3
|
+
|
4
|
+
- form.object.event_registrants.each_with_index do |event_registrant, index|
|
5
|
+
= card("Ticket ##{index+1}") do
|
6
|
+
- event_ticket = event_registrant.event_ticket
|
7
|
+
|
8
|
+
%p
|
9
|
+
= event_ticket
|
10
|
+
= ' - '
|
11
|
+
|
12
|
+
- if event_ticket.member_or_non_member? && event_registrant.first_name.blank? && !event.early_bird?
|
13
|
+
= effective_events_ticket_price(event, event_ticket)
|
14
|
+
- else
|
15
|
+
= price_to_currency(event_registrant.price)
|
16
|
+
|
17
|
+
= event_registrant.details
|
18
|
+
|
19
|
+
= form.fields_for :event_registrants, event_registrant do |fr|
|
20
|
+
- if event.allow_blank_registrants? && (fr.object.user.blank? || fr.object.blank_registrant?)
|
21
|
+
= fr.check_box :blank_registrant, label: "I will return and add this ticket's information later"
|
22
|
+
- else
|
23
|
+
= fr.hidden_field :blank_registrant, value: false
|
24
|
+
|
25
|
+
= fr.show_if(:blank_registrant, false) do
|
26
|
+
= render('effective/event_registrants/fields', f: fr)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
-# Displayed on the tickets step
|
2
|
+
- event = form.object.event
|
3
|
+
- tickets = event.event_tickets.reject(&:archived?)
|
4
|
+
- waitlist = tickets.any? { |ticket| ticket.waitlist? }
|
5
|
+
|
6
|
+
- all_member_only_tickets = tickets.all? { |ticket| ticket.member_only? }
|
7
|
+
- any_member_only_tickets = tickets.any? { |ticket| ticket.member_only? }
|
8
|
+
- is_member = current_user.try(:is?, :member)
|
9
|
+
|
10
|
+
- if event.early_bird?
|
11
|
+
.alert.alert-warning.mb-3
|
12
|
+
Early Bird rates end on
|
13
|
+
= event.early_bird_end_at.strftime("%A, %B %d, %Y at %l:%M%P.")
|
14
|
+
|
15
|
+
%table.table.table-sm.table-striped
|
16
|
+
%thead
|
17
|
+
%tr
|
18
|
+
%th Ticket
|
19
|
+
%th Price
|
20
|
+
%th Quantity
|
21
|
+
|
22
|
+
%tbody
|
23
|
+
- tickets.each do |ticket|
|
24
|
+
%tr
|
25
|
+
%td
|
26
|
+
= ticket.to_s
|
27
|
+
- if ticket.capacity.present? && ticket.display_capacity?
|
28
|
+
%br
|
29
|
+
%small
|
30
|
+
#{event.capacity_available(event_ticket: ticket, event_registration: form.object)} remaining
|
31
|
+
- if ticket.waitlist?
|
32
|
+
before waitlist
|
33
|
+
%td
|
34
|
+
%ul.list-unstyled.mb-0
|
35
|
+
- # Early Bird
|
36
|
+
- if event.early_bird? && ticket.early_bird_price.to_i > 0 && [ticket.member_price, ticket.regular_price].exclude?(ticket.early_bird_price)
|
37
|
+
%li
|
38
|
+
- if ticket.regular_price.to_i > 0
|
39
|
+
%div
|
40
|
+
%s.text-muted
|
41
|
+
= price_to_currency(ticket.regular_price)
|
42
|
+
|
43
|
+
- if ticket.member_price.to_i > 0
|
44
|
+
%div
|
45
|
+
%s.text-muted
|
46
|
+
= price_to_currency(ticket.member_price)
|
47
|
+
.badge.badge-secondary.mr-2 Members
|
48
|
+
|
49
|
+
%div
|
50
|
+
= price_to_currency(ticket.early_bird_price)
|
51
|
+
.badge.badge-warning Early Bird
|
52
|
+
- else
|
53
|
+
- if ticket.regular_price.present?
|
54
|
+
%li
|
55
|
+
= price_to_currency(ticket.regular_price)
|
56
|
+
|
57
|
+
- if ticket.member_price.present?
|
58
|
+
%li
|
59
|
+
= price_to_currency(ticket.member_price)
|
60
|
+
.badge.badge-secondary Members
|
61
|
+
|
62
|
+
%td
|
63
|
+
- event_ticket_selection = form.object.event_ticket_selection(event_ticket: ticket)
|
64
|
+
|
65
|
+
= form.fields_for :event_ticket_selections, event_ticket_selection do |f|
|
66
|
+
= f.hidden_field :event_ticket_id
|
67
|
+
= f.hidden_field :quantity, value: 0
|
68
|
+
|
69
|
+
- capacity = event.capacity_selectable(event_ticket: ticket, event_registration: form.object)
|
70
|
+
- disabled = (ticket.member_only? && !is_member)
|
71
|
+
|
72
|
+
- if form.object.selected_expired? && !f.object.errors.present?
|
73
|
+
- f.object.assign_attributes(quantity: 0)
|
74
|
+
|
75
|
+
= f.select :quantity, (0..capacity), label: false, disabled: disabled,
|
76
|
+
include_blank: false, input_js: { minimumResultsForSearch: 'Infinity' }
|
77
|
+
|
78
|
+
- if waitlist
|
79
|
+
%p If the ticket capacity has been reached you will be added to the waitlist.
|
80
|
+
|
81
|
+
- unless is_member
|
82
|
+
- if all_member_only_tickets
|
83
|
+
.alert.alert-info.mb-4 You must be a member to purchase tickets.
|
84
|
+
- elsif any_member_only_tickets
|
85
|
+
.alert.alert-info.mb-4 You must be a member to purchase some of these tickets.
|