effective_events 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/effective/event_registrations_controller.rb +11 -12
- data/app/datatables/admin/effective_event_addons_datatable.rb +2 -2
- data/app/datatables/admin/effective_event_products_datatable.rb +12 -4
- data/app/datatables/admin/effective_event_tickets_datatable.rb +5 -1
- data/app/helpers/effective_events_helper.rb +2 -2
- data/app/models/concerns/effective_events_event_registration.rb +41 -19
- data/app/models/effective/event.rb +36 -1
- data/app/models/effective/event_addon.rb +1 -0
- data/app/models/effective/event_product.rb +8 -13
- data/app/models/effective/event_registrant.rb +1 -0
- data/app/models/effective/event_ticket.rb +8 -13
- data/app/views/effective/event_registrations/_dashboard.html.haml +1 -1
- data/app/views/effective/event_registrations/checkout.html.haml +15 -3
- data/lib/effective_events/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c3cd1bb2313ea9a4be719350a54cb9f8bae0012040c26cd3661355a7590aba1
|
4
|
+
data.tar.gz: 82fa202806b65f47708ac748df70a44a3e2d5c253860049baad26925edf6e668
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af8087ebab4902bbce1ecb33310333f42943029f612477a2490d68d57c085ccaecded40fb10bcdbbd3cfbc28fb6506aeb1d146dafb22863560d35f2a46e6aa55
|
7
|
+
data.tar.gz: 90f1f61faed9c5991bdfc7289ca21071005f2b238cceea535e4648167102881f07b461021a9a6fc75bd117ab280bf3991d72b293485c5d090ad8503c1c38b389
|
@@ -1,29 +1,28 @@
|
|
1
1
|
module Effective
|
2
2
|
class EventRegistrationsController < ApplicationController
|
3
|
-
|
4
3
|
if defined?(Devise)
|
5
4
|
before_action :authenticate_user!, unless: -> { action_name == 'new' || (action_name == 'show' && params[:id] == 'start') }
|
6
5
|
end
|
7
6
|
|
8
7
|
include Effective::WizardController
|
9
8
|
|
9
|
+
before_action :redirect_unless_registerable, only: [:new, :show]
|
10
|
+
|
10
11
|
resource_scope -> {
|
11
12
|
event = Effective::Event.find(params[:event_id])
|
12
13
|
EffectiveEvents.EventRegistration.deep.where(owner: current_user, event: event)
|
13
14
|
}
|
14
15
|
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
return
|
19
|
-
return
|
20
|
-
|
21
|
-
if resource.
|
22
|
-
flash[:danger] = "Your selected event tickets are sold out. This event registration is no longer available."
|
23
|
-
return redirect_to('/dashboard')
|
24
|
-
end
|
16
|
+
# If the event is no longer registerable, do not let them continue
|
17
|
+
def redirect_unless_registerable
|
18
|
+
return if resource.blank?
|
19
|
+
return if resource.submitted?
|
20
|
+
return if resource.event.blank?
|
21
|
+
return if resource.event.registerable?
|
22
|
+
return if resource.submit_order&.deferred?
|
25
23
|
|
26
|
-
|
24
|
+
flash[:danger] = "Your selected event is no longer available for registration. This event registration is no longer available."
|
25
|
+
return redirect_to('/dashboard')
|
27
26
|
end
|
28
27
|
|
29
28
|
end
|
@@ -24,13 +24,21 @@ module Admin
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
col :
|
27
|
+
col :registered_event_addons_count, label: 'Registered'
|
28
|
+
col :purchased_event_addons_count, label: 'Purchased', visible: false
|
29
|
+
|
28
30
|
col :capacity, visible: false
|
29
31
|
col :capacity_available, visible: false
|
30
32
|
|
31
|
-
col :
|
32
|
-
product.
|
33
|
-
content_tag(:div,
|
33
|
+
col :registered_event_addons, label: 'Registered Names' do |product|
|
34
|
+
product.registered_event_addons.reject(&:archived?).sort_by(&:to_s).map do |addon|
|
35
|
+
content_tag(:div, addon.owner.to_s, class: 'col-resource_item')
|
36
|
+
end.join.html_safe
|
37
|
+
end
|
38
|
+
|
39
|
+
col :purchased_event_addons, label: 'Purchased Names', visible: false do |product|
|
40
|
+
product.purchased_event_addons.reject(&:archived?).sort_by(&:to_s).map do |addon|
|
41
|
+
content_tag(:div, addon.owner.to_s, class: 'col-resource_item')
|
34
42
|
end.join.html_safe
|
35
43
|
end
|
36
44
|
|
@@ -25,7 +25,11 @@ module Admin
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
col :
|
28
|
+
col :registered_event_registrants_count, label: 'Registered' do |event|
|
29
|
+
event.event_registrants.registered.unarchived.count
|
30
|
+
end
|
31
|
+
|
32
|
+
col :purchased_event_registrants_count, label: 'Purchased', visible: false do |event|
|
29
33
|
event.event_registrants.purchased.unarchived.count
|
30
34
|
end
|
31
35
|
|
@@ -20,7 +20,7 @@ module EffectiveEventsHelper
|
|
20
20
|
remaining = (ticket.capacity.present? ? "#{ticket.capacity_available} remaining" : nil)
|
21
21
|
|
22
22
|
label = [title, price, remaining].compact.join(' - ')
|
23
|
-
disabled = { disabled: :disabled } unless (authorized ||
|
23
|
+
disabled = { disabled: :disabled } unless (authorized || event.event_ticket_available?(ticket, quantity: 1))
|
24
24
|
|
25
25
|
[label, ticket.to_param, disabled].compact
|
26
26
|
end
|
@@ -39,7 +39,7 @@ module EffectiveEventsHelper
|
|
39
39
|
remaining = (product.capacity.present? ? "#{product.capacity_available} remaining" : nil)
|
40
40
|
|
41
41
|
label = [title, price, remaining].compact.join(' - ')
|
42
|
-
disabled = { disabled: :disabled } unless (authorized ||
|
42
|
+
disabled = { disabled: :disabled } unless (authorized || event.event_product_available?(product, quantity: 1))
|
43
43
|
|
44
44
|
[label, product.to_param, disabled].compact
|
45
45
|
end
|
@@ -77,7 +77,13 @@ module EffectiveEventsEventRegistration
|
|
77
77
|
timestamps
|
78
78
|
end
|
79
79
|
|
80
|
-
scope :deep, -> {
|
80
|
+
scope :deep, -> {
|
81
|
+
includes(:owner)
|
82
|
+
.includes(event: [:rich_texts, event_products: :purchased_event_addons, event_tickets: :purchased_event_registrants])
|
83
|
+
.includes(event_registrants: [event_ticket: :purchased_event_registrants])
|
84
|
+
.includes(event_addons: [event_product: :purchased_event_addons])
|
85
|
+
}
|
86
|
+
|
81
87
|
scope :sorted, -> { order(:id) }
|
82
88
|
|
83
89
|
scope :in_progress, -> { where.not(status: [:submitted]) }
|
@@ -99,16 +105,17 @@ module EffectiveEventsEventRegistration
|
|
99
105
|
self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
|
100
106
|
end
|
101
107
|
|
102
|
-
# Validate all
|
103
|
-
validate(
|
104
|
-
|
105
|
-
errors.add(:base, "The #{
|
106
|
-
item.errors.add(:event_ticket_id, "#{item.event_ticket} is unavailable for purchase")
|
108
|
+
# Validate all tickets are available for registration
|
109
|
+
validate(if: -> { current_step == :tickets }) do
|
110
|
+
unavailable_event_tickets.each do |event_ticket|
|
111
|
+
errors.add(:base, "The requested number of #{event_ticket} tickets are not available")
|
107
112
|
end
|
113
|
+
end
|
108
114
|
|
109
|
-
|
110
|
-
|
111
|
-
|
115
|
+
# Validate all products are available for registration
|
116
|
+
validate(if: -> { current_step == :addons }) do
|
117
|
+
unavailable_event_products.each do |event_product|
|
118
|
+
errors.add(:base, "The requested number of #{event_product} add-ons are not available")
|
112
119
|
end
|
113
120
|
end
|
114
121
|
|
@@ -132,15 +139,6 @@ module EffectiveEventsEventRegistration
|
|
132
139
|
notifications = event.event_notifications.select(&:registrant_purchased?)
|
133
140
|
notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
|
134
141
|
end
|
135
|
-
|
136
|
-
def sold_out_event_registrants
|
137
|
-
event_registrants.reject { |er| er.purchased? || er.event_ticket&.available? }
|
138
|
-
end
|
139
|
-
|
140
|
-
def sold_out_event_addons
|
141
|
-
event_addons.reject { |ep| ep.purchased? || ep.event_product&.available? }
|
142
|
-
end
|
143
|
-
|
144
142
|
end
|
145
143
|
|
146
144
|
# Instance Methods
|
@@ -200,10 +198,34 @@ module EffectiveEventsEventRegistration
|
|
200
198
|
event_addons
|
201
199
|
end
|
202
200
|
|
201
|
+
def unavailable_event_tickets
|
202
|
+
unavailable = []
|
203
|
+
|
204
|
+
present_event_registrants.map(&:event_ticket).group_by { |t| t }.each do |event_ticket, event_tickets|
|
205
|
+
unavailable << event_ticket unless event.event_ticket_available?(event_ticket, quantity: event_tickets.length)
|
206
|
+
end
|
207
|
+
|
208
|
+
unavailable
|
209
|
+
end
|
210
|
+
|
211
|
+
def unavailable_event_products
|
212
|
+
unavailable = []
|
213
|
+
|
214
|
+
present_event_addons.map(&:event_product).group_by { |p| p }.each do |event_product, event_products|
|
215
|
+
unavailable << event_product unless event.event_product_available?(event_product, quantity: event_products.length)
|
216
|
+
end
|
217
|
+
|
218
|
+
unavailable
|
219
|
+
end
|
220
|
+
|
203
221
|
private
|
204
222
|
|
205
223
|
def present_event_registrants
|
206
|
-
event_registrants.reject(&:marked_for_destruction?)
|
224
|
+
event_registrants.reject(&:marked_for_destruction?).reject(&:archived?)
|
225
|
+
end
|
226
|
+
|
227
|
+
def present_event_addons
|
228
|
+
event_addons.reject(&:marked_for_destruction?).reject(&:archived?)
|
207
229
|
end
|
208
230
|
|
209
231
|
end
|
@@ -24,6 +24,10 @@ module Effective
|
|
24
24
|
has_many :event_notifications, -> { order(:id) }, inverse_of: :event, dependent: :destroy
|
25
25
|
accepts_nested_attributes_for :event_notifications, allow_destroy: true
|
26
26
|
|
27
|
+
# Used by the registration_available checks
|
28
|
+
has_many :registered_event_registrants, -> { EventRegistrant.registered }, class_name: 'Effective::EventRegistrant', inverse_of: :event
|
29
|
+
has_many :registered_event_addons, -> { EventAddon.registered }, class_name: 'Effective::EventAddon', inverse_of: :event
|
30
|
+
|
27
31
|
# rich_text_body - Used by the select step
|
28
32
|
has_many_rich_texts
|
29
33
|
|
@@ -186,7 +190,8 @@ module Effective
|
|
186
190
|
end
|
187
191
|
|
188
192
|
def sold_out?
|
189
|
-
false
|
193
|
+
return false unless event_tickets.present?
|
194
|
+
event_tickets.none? { |event_ticket| event_ticket_available?(event_ticket, quantity: 1) }
|
190
195
|
end
|
191
196
|
|
192
197
|
def early_bird?
|
@@ -229,5 +234,35 @@ module Effective
|
|
229
234
|
start_at
|
230
235
|
end
|
231
236
|
|
237
|
+
# Can I register/purchase this many new event tickets?
|
238
|
+
def event_ticket_available?(event_ticket, quantity:)
|
239
|
+
raise('expected an EventTicket') unless event_ticket.kind_of?(Effective::EventTicket)
|
240
|
+
raise('expected quantity to be greater than 0') unless quantity.to_i > 0
|
241
|
+
|
242
|
+
return false if event_ticket.archived?
|
243
|
+
return true if event_ticket.capacity.blank? # No capacity enforced for this ticket
|
244
|
+
|
245
|
+
# Total number already sold
|
246
|
+
registered = registered_event_registrants.count { |r| r.event_ticket_id == event_ticket.id }
|
247
|
+
|
248
|
+
# If there's capacity for this many more
|
249
|
+
(registered + quantity) <= event_ticket.capacity
|
250
|
+
end
|
251
|
+
|
252
|
+
# Can I register/purchase this many new event products?
|
253
|
+
def event_product_available?(event_product, quantity:)
|
254
|
+
raise('expected an EventProduct') unless event_product.kind_of?(Effective::EventProduct)
|
255
|
+
raise('expected quantity to be greater than 0') unless quantity.to_i > 0
|
256
|
+
|
257
|
+
return false if event_product.archived?
|
258
|
+
return true if event_product.capacity.blank? # No capacity enforced for this product
|
259
|
+
|
260
|
+
# Total number already sold
|
261
|
+
registered = registered_event_addons.count { |r| r.event_product_id == event_product.id }
|
262
|
+
|
263
|
+
# If there's capacity for this many more
|
264
|
+
(registered + quantity) <= event_product.capacity
|
265
|
+
end
|
266
|
+
|
232
267
|
end
|
233
268
|
end
|
@@ -42,6 +42,7 @@ module Effective
|
|
42
42
|
|
43
43
|
scope :sorted, -> { order(:id) }
|
44
44
|
scope :deep, -> { includes(:event, :event_product) }
|
45
|
+
scope :registered, -> { purchased_or_deferred.unarchived }
|
45
46
|
|
46
47
|
before_validation(if: -> { event_registration.present? }) do
|
47
48
|
self.event ||= event_registration.event
|
@@ -9,7 +9,8 @@ module Effective
|
|
9
9
|
belongs_to :event
|
10
10
|
|
11
11
|
has_many :event_addons
|
12
|
-
has_many :purchased_event_addons, -> { EventAddon.purchased }, class_name: 'Effective::EventAddon'
|
12
|
+
has_many :purchased_event_addons, -> { EventAddon.purchased.unarchived }, class_name: 'Effective::EventAddon'
|
13
|
+
has_many :registered_event_addons, -> { EventAddon.registered.unarchived }, class_name: 'Effective::EventAddon'
|
13
14
|
|
14
15
|
log_changes(to: :event) if respond_to?(:log_changes)
|
15
16
|
|
@@ -45,23 +46,17 @@ module Effective
|
|
45
46
|
title.presence || 'New Event Product'
|
46
47
|
end
|
47
48
|
|
48
|
-
# Available for purchase
|
49
|
-
def available?
|
50
|
-
return false if archived?
|
51
|
-
capacity_available?
|
52
|
-
end
|
53
|
-
|
54
|
-
def capacity_available?
|
55
|
-
capacity.blank? || (capacity_available > 0)
|
56
|
-
end
|
57
|
-
|
58
49
|
def capacity_available
|
59
50
|
return nil if capacity.blank?
|
60
|
-
[(capacity -
|
51
|
+
[(capacity - registered_event_addons_count), 0].max
|
52
|
+
end
|
53
|
+
|
54
|
+
def registered_event_addons_count
|
55
|
+
registered_event_addons.length
|
61
56
|
end
|
62
57
|
|
63
58
|
def purchased_event_addons_count
|
64
|
-
purchased_event_addons.
|
59
|
+
purchased_event_addons.length
|
65
60
|
end
|
66
61
|
|
67
62
|
end
|
@@ -41,6 +41,7 @@ module Effective
|
|
41
41
|
|
42
42
|
scope :sorted, -> { order(:last_name) }
|
43
43
|
scope :deep, -> { includes(:event, :event_ticket) }
|
44
|
+
scope :registered, -> { purchased_or_deferred.unarchived }
|
44
45
|
|
45
46
|
validates :first_name, presence: true
|
46
47
|
validates :last_name, presence: true
|
@@ -9,7 +9,8 @@ module Effective
|
|
9
9
|
belongs_to :event
|
10
10
|
|
11
11
|
has_many :event_registrants
|
12
|
-
has_many :purchased_event_registrants, -> { EventRegistrant.purchased }, class_name: 'Effective::EventRegistrant'
|
12
|
+
has_many :purchased_event_registrants, -> { EventRegistrant.purchased.unarchived }, class_name: 'Effective::EventRegistrant'
|
13
|
+
has_many :registered_event_registrants, -> { EventRegistrant.registered.unarchived }, class_name: 'Effective::EventRegistrant'
|
13
14
|
|
14
15
|
log_changes(to: :event) if respond_to?(:log_changes)
|
15
16
|
|
@@ -51,23 +52,17 @@ module Effective
|
|
51
52
|
event.early_bird? ? early_bird_price : regular_price
|
52
53
|
end
|
53
54
|
|
54
|
-
# Available for purchase
|
55
|
-
def available?
|
56
|
-
return false if archived?
|
57
|
-
capacity_available?
|
58
|
-
end
|
59
|
-
|
60
|
-
def capacity_available?
|
61
|
-
capacity.blank? || (capacity_available > 0)
|
62
|
-
end
|
63
|
-
|
64
55
|
def capacity_available
|
65
56
|
return nil if capacity.blank?
|
66
|
-
[(capacity -
|
57
|
+
[(capacity - registered_event_registrants_count), 0].max
|
58
|
+
end
|
59
|
+
|
60
|
+
def registered_event_registrants_count
|
61
|
+
registered_event_registrants.length
|
67
62
|
end
|
68
63
|
|
69
64
|
def purchased_event_registrants_count
|
70
|
-
purchased_event_registrants.
|
65
|
+
purchased_event_registrants.length
|
71
66
|
end
|
72
67
|
|
73
68
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
-# In progress registration
|
2
|
-
- registration = EffectiveEvents.EventRegistration.in_progress.for(current_user).first
|
2
|
+
- registration = EffectiveEvents.EventRegistration.in_progress.includes(event: :event_products).for(current_user).first
|
3
3
|
|
4
4
|
- datatable = EffectiveResources.best('EffectiveEventRegistrationsDatatable').new(self, namespace: :effective)
|
5
5
|
|
@@ -1,6 +1,18 @@
|
|
1
1
|
= render 'layout' do
|
2
2
|
= render 'effective/event_registrations/content', resource: resource
|
3
3
|
|
4
|
-
.
|
5
|
-
.card
|
6
|
-
|
4
|
+
- if resource.submit_order.deferred?
|
5
|
+
.card
|
6
|
+
.card-body
|
7
|
+
= render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:submitted), deferred_url: wizard_path(:checkout), declined_url: wizard_path(:checkout))
|
8
|
+
- elsif resource.event.registerable? == false
|
9
|
+
.alert.alert-danger Your selected event is no longer available for registration.
|
10
|
+
- elsif resource.unavailable_event_tickets.present?
|
11
|
+
.alert.alert-danger Your selected number of event tickets are no longer available.
|
12
|
+
- elsif resource.unavailable_event_products.present?
|
13
|
+
.alert.alert-danger Your selected number of event add-ons are no longer available.
|
14
|
+
- else
|
15
|
+
.card
|
16
|
+
.card-body
|
17
|
+
= render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:submitted), deferred_url: wizard_path(:checkout), declined_url: wizard_path(:checkout))
|
18
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_events
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|