effective_events 0.10.2 → 0.11.1
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 +2 -15
- 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 +42 -20
- 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/checkout.html.haml +15 -3
- data/lib/effective_events/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 908edb48306e3813893671ea9ba33cc3d1988258a47451edecfeee86197136a7
|
|
4
|
+
data.tar.gz: 7bb18df7c58fd2fa7e08b17710a1b5eefe22574690f1532243aab1e559cc44ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f9e45f483664485e43509d46bb0209a7567bd66b5bf27f425cfbe03ee6a3b0f171362db99d6faf7c2070074be3210239d59140f0989260c2b1fd18aa5b820ca
|
|
7
|
+
data.tar.gz: ac11a1ab1e15d1e58f5ab7e6db346906fcf6836caedbb6c45f94fbf57c177334b379da57ae8e91658b23d017fb8d62f790f740c82c0d2c2ab55662edcba6084d
|
|
@@ -13,26 +13,13 @@ module Effective
|
|
|
13
13
|
EffectiveEvents.EventRegistration.deep.where(owner: current_user, event: event)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
# Override ready_checkout to also check for any currently sold out tickets or addons
|
|
17
|
-
# Prevents people from coming back and purchasing them
|
|
18
|
-
def ready_checkout
|
|
19
|
-
return unless step == :checkout
|
|
20
|
-
return unless resource.class.try(:acts_as_purchasable_wizard?)
|
|
21
|
-
|
|
22
|
-
if resource.sold_out_event_registrants.present? || resource.sold_out_event_addons.present?
|
|
23
|
-
flash[:danger] = "Your selected event tickets are sold out. This event registration is no longer available."
|
|
24
|
-
return redirect_to('/dashboard')
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
resource.ready!
|
|
28
|
-
end
|
|
29
|
-
|
|
30
16
|
# If the event is no longer registerable, do not let them continue
|
|
31
17
|
def redirect_unless_registerable
|
|
32
18
|
return if resource.blank?
|
|
19
|
+
return if resource.submitted?
|
|
33
20
|
return if resource.event.blank?
|
|
34
21
|
return if resource.event.registerable?
|
|
35
|
-
return if resource.
|
|
22
|
+
return if resource.submit_order&.deferred?
|
|
36
23
|
|
|
37
24
|
flash[:danger] = "Your selected event is no longer available for registration. This event registration is no longer available."
|
|
38
25
|
return redirect_to('/dashboard')
|
|
@@ -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
|
|
@@ -105,16 +105,17 @@ module EffectiveEventsEventRegistration
|
|
|
105
105
|
self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
# Validate all
|
|
109
|
-
validate(
|
|
110
|
-
|
|
111
|
-
errors.add(:base, "The #{
|
|
112
|
-
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")
|
|
113
112
|
end
|
|
113
|
+
end
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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")
|
|
118
119
|
end
|
|
119
120
|
end
|
|
120
121
|
|
|
@@ -126,27 +127,24 @@ module EffectiveEventsEventRegistration
|
|
|
126
127
|
# All Fees and Orders
|
|
127
128
|
def submit_fees
|
|
128
129
|
if owner.respond_to?(:outstanding_coupon_fees) # effective_memberships_owner
|
|
129
|
-
# Order item price reduction handled by reduce_order_item_coupon_fee_price in acts_as_purchasable_wizard
|
|
130
|
-
Array(owner.outstanding_coupon_fees).each { |fee| fees << fee unless fees.include?(fee) }
|
|
131
130
|
(event_registrants + event_addons + fees)
|
|
132
131
|
else
|
|
133
132
|
(event_registrants + event_addons)
|
|
134
133
|
end
|
|
135
134
|
end
|
|
136
135
|
|
|
137
|
-
def
|
|
138
|
-
|
|
139
|
-
notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
|
|
140
|
-
end
|
|
136
|
+
def apply_outstanding_coupon_fees
|
|
137
|
+
return unless owner.respond_to?(:outstanding_coupon_fees)
|
|
141
138
|
|
|
142
|
-
|
|
143
|
-
event_registrants.reject { |er| er.purchased? || er.event_ticket&.available? }
|
|
144
|
-
end
|
|
139
|
+
Array(owner.outstanding_coupon_fees).each { |fee| fees << fee unless fees.include?(fee) }
|
|
145
140
|
|
|
146
|
-
|
|
147
|
-
event_addons.reject { |ep| ep.purchased? || ep.event_product&.available? }
|
|
141
|
+
fees.select { |fee| fee.try(:coupon_fee?) }
|
|
148
142
|
end
|
|
149
143
|
|
|
144
|
+
def after_submit_purchased!
|
|
145
|
+
notifications = event.event_notifications.select(&:registrant_purchased?)
|
|
146
|
+
notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
|
|
147
|
+
end
|
|
150
148
|
end
|
|
151
149
|
|
|
152
150
|
# Instance Methods
|
|
@@ -206,10 +204,34 @@ module EffectiveEventsEventRegistration
|
|
|
206
204
|
event_addons
|
|
207
205
|
end
|
|
208
206
|
|
|
207
|
+
def unavailable_event_tickets
|
|
208
|
+
unavailable = []
|
|
209
|
+
|
|
210
|
+
present_event_registrants.map(&:event_ticket).group_by { |t| t }.each do |event_ticket, event_tickets|
|
|
211
|
+
unavailable << event_ticket unless event.event_ticket_available?(event_ticket, quantity: event_tickets.length)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
unavailable
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def unavailable_event_products
|
|
218
|
+
unavailable = []
|
|
219
|
+
|
|
220
|
+
present_event_addons.map(&:event_product).group_by { |p| p }.each do |event_product, event_products|
|
|
221
|
+
unavailable << event_product unless event.event_product_available?(event_product, quantity: event_products.length)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
unavailable
|
|
225
|
+
end
|
|
226
|
+
|
|
209
227
|
private
|
|
210
228
|
|
|
211
229
|
def present_event_registrants
|
|
212
|
-
event_registrants.reject(&:marked_for_destruction?)
|
|
230
|
+
event_registrants.reject(&:marked_for_destruction?).reject(&:archived?)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def present_event_addons
|
|
234
|
+
event_addons.reject(&:marked_for_destruction?).reject(&:archived?)
|
|
213
235
|
end
|
|
214
236
|
|
|
215
237
|
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,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.1
|
|
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-02-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -178,6 +178,20 @@ dependencies:
|
|
|
178
178
|
- - ">="
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
180
|
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: effective_roles
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
181
195
|
- !ruby/object:Gem::Dependency
|
|
182
196
|
name: psych
|
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|