effective_events 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46897bd3260153bd17103b73716d32aca3b46d77335c9c8ac80b033ac881041b
4
- data.tar.gz: 7da214c575b80246b79edc8c8c0467352e7629dea228a809db80a4c8fc53f14a
3
+ metadata.gz: 25070167849b6086995bc9e6e31bcdf0f8d9a36353ce8bb98c32a46d07c50318
4
+ data.tar.gz: 91f62a8a03323a83c7aaa2f54c39e2aeb3b2e1c89824de9be544d1e5cf955081
5
5
  SHA512:
6
- metadata.gz: cd8c3c426638f64c649408ea2da9ce57a5965c33c33aafde8255327b8c2eecf01ff0e8077b73d772575045e38e86f4648cdf79661f0b44d2d083e3ebab92a3e8
7
- data.tar.gz: 4331ea43140b17dce1a0c0850688cf7b57627df10dbefde960d64fdf7cba63d63f3a285f79141a4c73a23f0941dc3f94632f5e1445201fbf0a97eac24c7c26f7
6
+ metadata.gz: 3c3d87e21be01edf5b1395ad4a94a828cac98141b000d5ac43e7fc4af61e638399e620c17c9e0e137901aaed5c672fcc75deec074ef83b6cb3db2c7fc498ffde
7
+ data.tar.gz: 57626a1e76dc8ffdc26c687746de28f217b98fc6ce4fceefd8e13f4c59afc98519290184b49750cfeb4a04d86f494d6b4c8914a53cd2e437f28d7770f1e73baf
@@ -12,8 +12,17 @@ module Admin
12
12
  col :title
13
13
  col :price, as: :price
14
14
 
15
- #col :capacity
15
+ col :archived
16
+
17
+ col :capacity_to_s, label: 'Capacity' do |ticket|
18
+ if ticket.capacity.present?
19
+ "#{ticket.capacity_available} remaining / #{ticket.capacity} total"
20
+ end
21
+ end
22
+
16
23
  col :purchased_event_purchases_count, label: 'Purchased'
24
+ col :capacity, visible: false
25
+ col :capacity_available, visible: false
17
26
 
18
27
  col :purchased_event_purchases, label: 'Purchased by' do |product|
19
28
  product.purchased_event_purchases.sort_by(&:to_s).map do |purchase|
@@ -13,8 +13,17 @@ module Admin
13
13
  col :regular_price, as: :price
14
14
  col :early_bird_price, as: :price
15
15
 
16
- #col :capacity
16
+ col :archived
17
+
18
+ col :capacity_to_s, label: 'Capacity' do |ticket|
19
+ if ticket.capacity.present?
20
+ "#{ticket.capacity_available} remaining / #{ticket.capacity} total"
21
+ end
22
+ end
23
+
17
24
  col :purchased_event_registrants_count, label: 'Registered'
25
+ col :capacity, visible: false
26
+ col :capacity_available, visible: false
18
27
 
19
28
  col :purchased_event_registrants, label: 'Registrants' do |ticket|
20
29
  ticket.purchased_event_registrants.sort_by(&:last_name).map do |registrant|
@@ -3,22 +3,30 @@ module EffectiveEventsHelper
3
3
  def effective_events_event_tickets_collection(event)
4
4
  raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
5
5
 
6
- event.event_tickets.map do |ticket|
7
- label = ticket.to_s
6
+ event.event_tickets.reject(&:archived?).map do |ticket|
7
+ title = ticket.to_s
8
8
  price = (ticket.price == 0 ? '$0' : price_to_currency(ticket.price))
9
+ remaining = (ticket.capacity.present? ? "#{ticket.capacity_available} remaining" : nil)
9
10
 
10
- ["#{label} - #{price}", ticket.to_param]
11
+ label = [title, price, remaining].compact.join(' - ')
12
+ disabled = { disabled: :disabled } unless ticket.available?
13
+
14
+ [label, ticket.to_param, disabled].compact
11
15
  end
12
16
  end
13
17
 
14
18
  def effective_events_event_products_collection(event)
15
19
  raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
16
20
 
17
- event.event_products.map do |product|
18
- label = product.to_s
21
+ event.event_products.reject(&:archived?).map do |product|
22
+ title = product.to_s
19
23
  price = (product.price == 0 ? '$0' : price_to_currency(product.price))
24
+ remaining = (product.capacity.present? ? "#{product.capacity_available} remaining" : nil)
25
+
26
+ label = [title, price, remaining].compact.join(' - ')
27
+ disabled = { disabled: :disabled } unless product.available?
20
28
 
21
- ["#{label} - #{price}", product.to_param]
29
+ [label, product.to_param, disabled].compact
22
30
  end
23
31
  end
24
32
 
@@ -95,6 +95,19 @@ module EffectiveEventsEventRegistration
95
95
  self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
96
96
  end
97
97
 
98
+ # Validate all items are available
99
+ validate(unless: -> { current_step == :checkout || done? }) do
100
+ event_registrants.reject { |er| er.purchased? || er.event_ticket&.available? }.each do |item|
101
+ errors.add(:base, "The #{item.event_ticket} ticket is sold out and no longer available for purchase")
102
+ item.errors.add(:event_ticket_id, "#{item.event_ticket} is unavailable for purchase")
103
+ end
104
+
105
+ event_purchases.reject { |ep| ep.purchased? || ep.event_product&.available? }.each do |item|
106
+ errors.add(:base, "The #{item.event_product} product is sold out and no longer available for purchase")
107
+ item.errors.add(:event_product_id, "#{item.event_product} is unavailable for purchase")
108
+ end
109
+ end
110
+
98
111
  def required_steps
99
112
  return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
100
113
  event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:purchases])
@@ -121,9 +134,15 @@ module EffectiveEventsEventRegistration
121
134
  end
122
135
 
123
136
  # Find or build
124
- def event_registrant(first_name:, last_name:, email:)
125
- registrant = event_registrants.find { |er| er.first_name == first_name && er.last_name == last_name && er.email == email }
126
- registrant || event_registrants.build(event: event, owner: owner, first_name: first_name, last_name: last_name, email: email)
137
+ def event_registrant(event_ticket:, first_name:, last_name:, email:)
138
+ registrant = event_registrants.find { |er| er.event_ticket == event_ticket && er.first_name == first_name && er.last_name == last_name && er.email == email }
139
+ registrant || event_registrants.build(event: event, event_ticket: event_ticket, owner: owner, first_name: first_name, last_name: last_name, email: email)
140
+ end
141
+
142
+ # Find or build. But it's not gonna work with more than 1. This is for testing only really.
143
+ def event_purchase(event_product:)
144
+ purchase = event_purchases.find { |ep| ep.event_product == event_product }
145
+ purchase || event_purchases.build(event_product: event_product, owner: owner)
127
146
  end
128
147
 
129
148
  # This builds the default event registrants used by the wizard form
@@ -22,6 +22,7 @@ module Effective
22
22
  tax_exempt :boolean
23
23
 
24
24
  position :integer
25
+ archived :boolean
25
26
 
26
27
  timestamps
27
28
  end
@@ -29,6 +30,9 @@ module Effective
29
30
  scope :sorted, -> { order(:position) }
30
31
  scope :deep, -> { with_rich_text_body.includes(:purchased_event_purchases) }
31
32
 
33
+ scope :archived, -> { where(archived: true) }
34
+ scope :unarchived, -> { where(archived: false) }
35
+
32
36
  before_validation(if: -> { event.present? }) do
33
37
  self.position ||= (event.event_products.map(&:position).compact.max || -1) + 1
34
38
  end
@@ -40,13 +44,23 @@ module Effective
40
44
  title.presence || 'New Event Product'
41
45
  end
42
46
 
47
+ # Available for purchase
48
+ def available?
49
+ return false if archived?
50
+ capacity_available?
51
+ end
52
+
43
53
  def capacity_available?
44
- return true if capacity.blank?
45
- capacity <= purchased_event_purchases.count
54
+ capacity.blank? || (capacity_available > 0)
55
+ end
56
+
57
+ def capacity_available
58
+ return nil if capacity.blank?
59
+ [(capacity - purchased_event_purchases_count), 0].max
46
60
  end
47
61
 
48
62
  def purchased_event_purchases_count
49
- purchased_event_purchases.count
63
+ purchased_event_purchases.length
50
64
  end
51
65
 
52
66
  end
@@ -23,6 +23,7 @@ module Effective
23
23
  tax_exempt :boolean
24
24
 
25
25
  position :integer
26
+ archived :boolean
26
27
 
27
28
  timestamps
28
29
  end
@@ -30,6 +31,9 @@ module Effective
30
31
  scope :sorted, -> { order(:position) }
31
32
  scope :deep, -> { with_rich_text_body.includes(:purchased_event_registrants) }
32
33
 
34
+ scope :archived, -> { where(archived: true) }
35
+ scope :unarchived, -> { where(archived: false) }
36
+
33
37
  before_validation(if: -> { event.present? }) do
34
38
  self.position ||= (event.event_tickets.map(&:position).compact.max || -1) + 1
35
39
  end
@@ -46,13 +50,23 @@ module Effective
46
50
  event.early_bird? ? early_bird_price : regular_price
47
51
  end
48
52
 
53
+ # Available for purchase
54
+ def available?
55
+ return false if archived?
56
+ capacity_available?
57
+ end
58
+
49
59
  def capacity_available?
50
- return true if capacity.blank?
51
- capacity <= purchased_event_registrants.count
60
+ capacity.blank? || (capacity_available > 0)
61
+ end
62
+
63
+ def capacity_available
64
+ return nil if capacity.blank?
65
+ [(capacity - purchased_event_registrants_count), 0].max
52
66
  end
53
67
 
54
68
  def purchased_event_registrants_count
55
- purchased_event_registrants.count
69
+ purchased_event_registrants.length
56
70
  end
57
71
 
58
72
  end
@@ -2,8 +2,11 @@
2
2
  = f.hidden_field :event_id
3
3
 
4
4
  = f.text_field :title
5
+ = f.number_field :capacity, hint: 'The number of online purchases will be limited to capacity.'
6
+ = f.check_box :archived, label: 'Yes, archive this product and make it unavailable for purchase'
7
+
5
8
  = f.price_field :price
6
- = f.text_field :qb_item_name
9
+ = f.text_field :qb_item_name, label: 'Quickbooks item name'
7
10
  = f.check_box :tax_exempt
8
11
 
9
12
  = effective_submit(f)
@@ -2,10 +2,13 @@
2
2
  = f.hidden_field :event_id
3
3
 
4
4
  = f.text_field :title
5
+ = f.number_field :capacity, hint: 'The number of online purchases will be limited to capacity.'
6
+ = f.check_box :archived, label: 'Yes, archive this ticket and make it unavailable for purchase'
7
+
5
8
  = f.price_field :regular_price
6
9
  = f.price_field :early_bird_price
7
- = f.text_field :qb_item_name
10
+ = f.text_field :qb_item_name, label: 'Quickbooks item name'
8
11
  = f.check_box :tax_exempt
9
- /= f.number_field :capacity, hint: 'The number of online purchases will be loosely limited to capacity.'
12
+
10
13
 
11
14
  = effective_submit(f)
@@ -38,6 +38,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
38
38
  t.boolean :tax_exempt, default: false
39
39
 
40
40
  t.integer :position
41
+ t.boolean :archived, default: false
41
42
 
42
43
  t.timestamps
43
44
  end
@@ -78,6 +79,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
78
79
  t.boolean :tax_exempt, default: false
79
80
 
80
81
  t.integer :position
82
+ t.boolean :archived, default: false
81
83
 
82
84
  t.timestamps
83
85
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.1.5'.freeze
2
+ VERSION = '0.1.6'.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.1.5
4
+ version: 0.1.6
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: 2022-01-12 00:00:00.000000000 Z
11
+ date: 2022-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails