effective_events 0.10.2 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|