effective_events 0.10.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e0eded3c712c018bb91f9c90eebe522030fa7d02d5d73b9de4001bda7c5dbcf
4
- data.tar.gz: 3dc20c280ef92ebc93dad4cfe57df506e6a283bd4433a4792f07a236b3fb5ebc
3
+ metadata.gz: 2c3cd1bb2313ea9a4be719350a54cb9f8bae0012040c26cd3661355a7590aba1
4
+ data.tar.gz: 82fa202806b65f47708ac748df70a44a3e2d5c253860049baad26925edf6e668
5
5
  SHA512:
6
- metadata.gz: 43fcaa469c42cf91dcb5ac3f6c52509372a4d8983c91cac727d350f4c9a3a797f04d4cd1f4ee6793502a5eb868dbc1c660e51862b3a0ad299f1ad416a69c7220
7
- data.tar.gz: e7fe84b88841792c065bd307a80656ab4248b60306c2cfecaeb007ba09aa3b2bc782ee13512a91640e02c5b39156bb923bcd6683e889d51b36f99b2bd349bc67
6
+ metadata.gz: af8087ebab4902bbce1ecb33310333f42943029f612477a2490d68d57c085ccaecded40fb10bcdbbd3cfbc28fb6506aeb1d146dafb22863560d35f2a46e6aa55
7
+ data.tar.gz: 90f1f61faed9c5991bdfc7289ca21071005f2b238cceea535e4648167102881f07b461021a9a6fc75bd117ab280bf3991d72b293485c5d090ad8503c1c38b389
@@ -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.submitted?
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')
@@ -23,8 +23,8 @@ module Admin
23
23
  col :event_product, search: :string
24
24
  end
25
25
 
26
- col :purchased_order
27
- col :owner
26
+ col :purchased_order, visible: false
27
+ col :owner, visible: false
28
28
 
29
29
  col :first_name
30
30
  col :last_name
@@ -24,13 +24,21 @@ module Admin
24
24
  end
25
25
  end
26
26
 
27
- col :purchased_event_addons_count, label: 'Purchased'
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 :purchased_event_addons, label: 'Name' do |product|
32
- product.purchased_event_addons.reject(&:archived?).sort_by(&:to_s).map do |purchase|
33
- content_tag(:div, purchase.owner.to_s, class: 'col-resource_item')
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 :purchased_event_registrants_count, label: 'Registered' do |event|
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 || ticket.available?)
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 || product.available?)
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 items are available
109
- validate(unless: -> { current_step == :checkout || done? }) do
110
- sold_out_event_registrants.each do |item|
111
- errors.add(:base, "The #{item.event_ticket} ticket is sold out and no longer available for purchase")
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
- sold_out_event_addons.each do |item|
116
- errors.add(:base, "The #{item.event_product} product is sold out and no longer available for purchase")
117
- item.errors.add(:event_product_id, "#{item.event_product} is unavailable for purchase")
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
 
@@ -138,15 +139,6 @@ module EffectiveEventsEventRegistration
138
139
  notifications = event.event_notifications.select(&:registrant_purchased?)
139
140
  notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
140
141
  end
141
-
142
- def sold_out_event_registrants
143
- event_registrants.reject { |er| er.purchased? || er.event_ticket&.available? }
144
- end
145
-
146
- def sold_out_event_addons
147
- event_addons.reject { |ep| ep.purchased? || ep.event_product&.available? }
148
- end
149
-
150
142
  end
151
143
 
152
144
  # Instance Methods
@@ -206,10 +198,34 @@ module EffectiveEventsEventRegistration
206
198
  event_addons
207
199
  end
208
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
+
209
221
  private
210
222
 
211
223
  def present_event_registrants
212
- 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?)
213
229
  end
214
230
 
215
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 - purchased_event_addons_count), 0].max
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.reject(&:archived?).length
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 - purchased_event_registrants_count), 0].max
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.reject(&:archived?).length
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
- .card
5
- .card-body
6
- = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:submitted), deferred_url: wizard_path(:checkout), declined_url: wizard_path(:checkout))
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
+
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.10.2'.freeze
2
+ VERSION = '0.11.0'.freeze
3
3
  end
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.10.2
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: 2023-12-11 00:00:00.000000000 Z
11
+ date: 2024-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails