effective_events 0.1.5 → 0.1.9

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -2
  3. data/app/controllers/admin/{event_purchases_controller.rb → event_addons_controller.rb} +1 -2
  4. data/app/datatables/admin/{effective_event_purchases_datatable.rb → effective_event_addons_datatable.rb} +2 -2
  5. data/app/datatables/admin/effective_event_products_datatable.rb +13 -4
  6. data/app/datatables/admin/effective_event_registrations_datatable.rb +1 -1
  7. data/app/datatables/admin/effective_event_tickets_datatable.rb +10 -1
  8. data/app/datatables/admin/effective_events_datatable.rb +7 -6
  9. data/app/datatables/{effective_event_purchases_datatable.rb → effective_event_addons_datatable.rb} +5 -5
  10. data/app/datatables/effective_event_registrants_datatable.rb +1 -1
  11. data/app/datatables/effective_event_registrations_datatable.rb +2 -1
  12. data/app/datatables/effective_events_datatable.rb +2 -2
  13. data/app/helpers/effective_events_helper.rb +14 -6
  14. data/app/models/concerns/effective_events_event_registration.rb +29 -10
  15. data/app/models/effective/event.rb +4 -4
  16. data/app/models/effective/{event_purchase.rb → event_addon.rb} +2 -2
  17. data/app/models/effective/event_product.rb +21 -7
  18. data/app/models/effective/event_ticket.rb +17 -3
  19. data/app/views/admin/{event_purchases → event_addons}/_form.html.haml +2 -2
  20. data/app/views/admin/event_products/_form.html.haml +8 -2
  21. data/app/views/admin/event_tickets/_form.html.haml +9 -4
  22. data/app/views/admin/events/_form.html.haml +4 -5
  23. data/app/views/effective/event_addons/_fields.html.haml +8 -0
  24. data/app/views/effective/event_registrants/_fields.html.haml +3 -5
  25. data/app/views/effective/event_registrations/_addons.html.haml +9 -0
  26. data/app/views/effective/event_registrations/_content.html.haml +2 -2
  27. data/app/views/effective/event_registrations/_summary.html.haml +22 -25
  28. data/app/views/effective/event_registrations/_tickets.haml +9 -0
  29. data/app/views/effective/event_registrations/addons.html.haml +19 -0
  30. data/app/views/effective/event_registrations/billing.html.haml +8 -7
  31. data/app/views/effective/event_registrations/{registrants.html.haml → tickets.haml} +0 -2
  32. data/app/views/effective/events/_dashboard.html.haml +0 -6
  33. data/config/effective_events.rb +4 -0
  34. data/config/routes.rb +1 -1
  35. data/db/migrate/01_create_effective_events.rb.erb +14 -12
  36. data/lib/effective_events/version.rb +1 -1
  37. data/lib/effective_events.rb +2 -1
  38. data/lib/generators/effective_events/install_generator.rb +5 -0
  39. metadata +12 -12
  40. data/app/views/effective/event_purchases/_fields.html.haml +0 -10
  41. data/app/views/effective/event_registrations/_purchases.html.haml +0 -10
  42. data/app/views/effective/event_registrations/_registrants.html.haml +0 -10
  43. data/app/views/effective/event_registrations/purchases.html.haml +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46897bd3260153bd17103b73716d32aca3b46d77335c9c8ac80b033ac881041b
4
- data.tar.gz: 7da214c575b80246b79edc8c8c0467352e7629dea228a809db80a4c8fc53f14a
3
+ metadata.gz: 57f83ae2c7ff0c516e104fe18d4f517838bc07eec2a3d10b939946d0c9ed97d6
4
+ data.tar.gz: 0f5b5cca100cbfc4820940cca910c8cb07e14107227a753135ee5464eecd9611
5
5
  SHA512:
6
- metadata.gz: cd8c3c426638f64c649408ea2da9ce57a5965c33c33aafde8255327b8c2eecf01ff0e8077b73d772575045e38e86f4648cdf79661f0b44d2d083e3ebab92a3e8
7
- data.tar.gz: 4331ea43140b17dce1a0c0850688cf7b57627df10dbefde960d64fdf7cba63d63f3a285f79141a4c73a23f0941dc3f94632f5e1445201fbf0a97eac24c7c26f7
6
+ metadata.gz: 33e99c1640263a789ff5c26653eb237110163f45d79726bd39a49412ac3e3fa43cda22ca888d02e07ce306e49393c438721c8bc704937a724146d26370870d8f
7
+ data.tar.gz: 3b9dedff99f782f3e88fffe9080665607c47ee8933ca0c66a58c9ef45448e5a18db05c21abf3052148dc073bba61b82907845c03982fab48942c94b34d75761f
data/README.md CHANGED
@@ -68,10 +68,34 @@ All authorization checks are handled via the effective_resources gem found in th
68
68
  The permissions you actually want to define are as follows (using CanCan):
69
69
 
70
70
  ```ruby
71
- can :index, Effective::Event
71
+ can([:index, :show], Effective::Event) { |event| !event.draft? }
72
+ can([:new, :create], EffectiveEvents.EventRegistration)
73
+ can([:show, :index], Effective::EventRegistrant) { |registrant| registrant.owner == user || registrant.owner.blank? }
74
+ can([:show, :index], Effective::EventAddon) { |addon| addon.owner == user || addon.owner.blank? }
75
+ can([:show, :index], EffectiveEvents.EventRegistration) { |registration| registration.owner == user }
76
+ can([:update, :destroy], EffectiveEvents.EventRegistration) { |registration| registration.owner == user && !registration.was_submitted? }
72
77
 
73
78
  if user.admin?
74
- can :manage, Effective::Event
79
+ can :admin, :effective_events
80
+
81
+ can(crud - [:destroy], Effective::Event)
82
+ can(:destroy, Effective::Event) { |et| et.event_registrants_count == 0 }
83
+
84
+ can(crud - [:destroy], Effective::EventRegistrant)
85
+ can(:mark_paid, Effective::EventRegistrant) { |er| !er.event_registration_id.present? }
86
+ can(:destroy, Effective::EventRegistrant) { |er| !er.purchased? }
87
+
88
+ can(crud - [:destroy], Effective::EventAddon)
89
+ can(:mark_paid, Effective::EventAddon) { |er| !er.event_registration_id.present? }
90
+ can(:destroy, Effective::EventAddon) { |er| !er.purchased? }
91
+
92
+ can(crud - [:destroy], Effective::EventTicket)
93
+ can(:destroy, Effective::EventTicket) { |et| et.purchased_event_registrants_count == 0 }
94
+
95
+ can(crud - [:destroy], Effective::EventProduct)
96
+ can(:destroy, Effective::EventProduct) { |et| et.purchased_event_addons_count == 0 }
97
+
98
+ can([:index, :show], EffectiveEvents.EventRegistration)
75
99
  end
76
100
  ```
77
101
 
@@ -1,11 +1,10 @@
1
1
  module Admin
2
- class EventPurchasesController < ApplicationController
2
+ class EventAddonsController < ApplicationController
3
3
  before_action(:authenticate_user!) if defined?(Devise)
4
4
  before_action { EffectiveResources.authorize!(self, :admin, :effective_events) }
5
5
 
6
6
  include Effective::CrudController
7
7
 
8
8
  submit :mark_paid, 'Save and Mark Paid'
9
-
10
9
  end
11
10
  end
@@ -1,5 +1,5 @@
1
1
  module Admin
2
- class EffectiveEventPurchasesDatatable < Effective::Datatable
2
+ class EffectiveEventAddonsDatatable < Effective::Datatable
3
3
  datatable do
4
4
  col :updated_at, visible: false
5
5
  col :created_at, visible: false
@@ -23,7 +23,7 @@ module Admin
23
23
  end
24
24
 
25
25
  collection do
26
- scope = Effective::EventPurchase.deep.purchased
26
+ scope = Effective::EventAddon.deep.purchased
27
27
 
28
28
  if attributes[:event_id].present?
29
29
  scope = scope.where(event: event)
@@ -12,11 +12,20 @@ module Admin
12
12
  col :title
13
13
  col :price, as: :price
14
14
 
15
- #col :capacity
16
- col :purchased_event_purchases_count, label: 'Purchased'
15
+ col :archived
17
16
 
18
- col :purchased_event_purchases, label: 'Purchased by' do |product|
19
- product.purchased_event_purchases.sort_by(&:to_s).map do |purchase|
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
+
23
+ col :purchased_event_addons_count, label: 'Purchased'
24
+ col :capacity, visible: false
25
+ col :capacity_available, visible: false
26
+
27
+ col :purchased_event_addons, label: 'Purchased by' do |product|
28
+ product.purchased_event_addons.sort_by(&:to_s).map do |purchase|
20
29
  content_tag(:div, purchase.owner.to_s, class: 'col-resource_item')
21
30
  end.join.html_safe
22
31
  end
@@ -13,7 +13,7 @@ class Admin::EffectiveEventRegistrationsDatatable < Effective::Datatable
13
13
  col :owner
14
14
 
15
15
  col :event_registrants, search: :string
16
- col :event_purchases, search: :string
16
+ col :event_addons, search: :string
17
17
  col :orders, label: 'Order'
18
18
 
19
19
  actions_col
@@ -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|
@@ -15,14 +15,13 @@ module Admin
15
15
 
16
16
  col :title
17
17
  col :draft
18
- col :start_at, label: 'Event Date'
19
-
20
- col :end_at, visible: false
18
+ col :start_at, label: 'Event Start Date'
19
+ col :end_at, label: 'Event End Date', visible: false
21
20
  col :excerpt, visible: false
22
21
 
23
- col :registration_start_at, label: 'Registration opens'
24
- col :registration_end_at, label: 'Registration closes'
25
- col :early_bird_end_at, label: 'Early bird ends'
22
+ col :registration_start_at, label: 'Registration opens', visible: false
23
+ col :registration_end_at, label: 'Registration closes', visible: false
24
+ col :early_bird_end_at, label: 'Early bird ends', visible: false
26
25
 
27
26
  col :early_bird do |event|
28
27
  if event.early_bird?
@@ -33,7 +32,9 @@ module Admin
33
32
  end
34
33
 
35
34
  col :event_tickets, search: :string
35
+ col :event_products, search: :string
36
36
  col :event_registrants, search: :string
37
+ col :event_addons, search: :string
37
38
 
38
39
  col :roles, visible: false
39
40
  col :authenticate_user, visible: false
@@ -1,16 +1,16 @@
1
- # Used on the Event Registrations purchases step
1
+ # Used on the Event Registrations Addons step
2
2
 
3
- class EffectiveEventPurchasesDatatable < Effective::Datatable
3
+ class EffectiveEventAddonsDatatable < Effective::Datatable
4
4
  datatable do
5
5
 
6
- col :event_product, search: :string
6
+ col :event_product, search: :string, label: 'Product'
7
7
  col :price, as: :price
8
- col :notes
8
+ # col :notes
9
9
  # no actions_col
10
10
  end
11
11
 
12
12
  collection do
13
- scope = Effective::EventPurchase.deep.all
13
+ scope = Effective::EventAddon.deep.all
14
14
 
15
15
  if event.present?
16
16
  scope = scope.where(event: event)
@@ -3,7 +3,7 @@
3
3
  class EffectiveEventRegistrantsDatatable < Effective::Datatable
4
4
  datatable do
5
5
 
6
- col :event_ticket, search: :string
6
+ col :event_ticket, search: :string, label: 'Ticket'
7
7
 
8
8
  col :name do |er|
9
9
  "#{er.first_name} #{er.last_name}<br><small>#{mail_to(er.email)}</small>"
@@ -16,7 +16,8 @@ class EffectiveEventRegistrationsDatatable < Effective::Datatable
16
16
 
17
17
  col :owner, visible: false, search: :string
18
18
  col :status, visible: false
19
- col :event_registrants, search: :string
19
+ col :event_registrants, label: 'Registrants', search: :string
20
+ col :event_addons, label: 'Add-ons', search: :string
20
21
  col :orders, action: :show, visible: false, search: :string
21
22
 
22
23
  actions_col(actions: []) do |er|
@@ -10,9 +10,9 @@ class EffectiveEventsDatatable < Effective::Datatable
10
10
  order :title
11
11
  col :id, visible: false
12
12
 
13
- col :start_at, label: 'Event Date', as: :date
13
+ col :start_at, label: 'Date', as: :date
14
14
 
15
- col :title, label: 'Event' do |event|
15
+ col :title, label: 'Title' do |event|
16
16
  if event.registerable?
17
17
  link_to(event.to_s, effective_events.new_event_event_registration_path(event))
18
18
  else
@@ -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
 
@@ -36,8 +36,8 @@ module EffectiveEventsEventRegistration
36
36
 
37
37
  acts_as_wizard(
38
38
  start: 'Start',
39
- registrants: 'Registrants',
40
- purchases: 'Purchases',
39
+ tickets: 'Tickets',
40
+ addons: 'Add-ons',
41
41
  summary: 'Review',
42
42
  billing: 'Billing Address',
43
43
  checkout: 'Checkout',
@@ -58,8 +58,8 @@ module EffectiveEventsEventRegistration
58
58
  has_many :event_registrants, -> { order(:id) }, class_name: 'Effective::EventRegistrant', inverse_of: :event_registration, dependent: :destroy
59
59
  accepts_nested_attributes_for :event_registrants, reject_if: :all_blank, allow_destroy: true
60
60
 
61
- has_many :event_purchases, -> { order(:id) }, class_name: 'Effective::EventPurchase', inverse_of: :event_registration, dependent: :destroy
62
- accepts_nested_attributes_for :event_purchases, reject_if: :all_blank, allow_destroy: true
61
+ has_many :event_addons, -> { order(:id) }, class_name: 'Effective::EventAddon', inverse_of: :event_registration, dependent: :destroy
62
+ accepts_nested_attributes_for :event_addons, reject_if: :all_blank, allow_destroy: true
63
63
 
64
64
  has_many :orders, -> { order(:id) }, as: :parent, class_name: 'Effective::Order', dependent: :nullify
65
65
  accepts_nested_attributes_for :orders
@@ -91,18 +91,31 @@ module EffectiveEventsEventRegistration
91
91
  validates :event, presence: true
92
92
 
93
93
  # Registrants Step
94
- validate(if: -> { current_step == :registrants }) do
94
+ validate(if: -> { current_step == :tickets }) do
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_addons.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
- event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:purchases])
113
+ event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:addons])
101
114
  end
102
115
 
103
116
  # All Fees and Orders
104
117
  def submit_fees
105
- (event_registrants + event_purchases)
118
+ (event_registrants + event_addons)
106
119
  end
107
120
 
108
121
  end
@@ -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_addon(event_product:)
144
+ addon = event_addons.find { |ep| ep.event_product == event_product }
145
+ addon || event_addons.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
@@ -11,8 +11,8 @@ module Effective
11
11
  has_many :event_registrants, -> { order(:event_ticket_id, :created_at) }, inverse_of: :event
12
12
  accepts_nested_attributes_for :event_registrants, allow_destroy: true
13
13
 
14
- has_many :event_purchases, -> { order(:event_product_id, :created_at) }, inverse_of: :event
15
- accepts_nested_attributes_for :event_purchases, allow_destroy: true
14
+ has_many :event_addons, -> { order(:event_product_id, :created_at) }, inverse_of: :event
15
+ accepts_nested_attributes_for :event_addons, allow_destroy: true
16
16
 
17
17
  # rich_text_body - Used by the select step
18
18
  has_many_rich_texts
@@ -149,12 +149,12 @@ module Effective
149
149
 
150
150
  def early_bird?
151
151
  return false if early_bird_end_at.blank?
152
- early_bird_end_at < Time.zone.now
152
+ early_bird_end_at > Time.zone.now
153
153
  end
154
154
 
155
155
  def early_bird_past?
156
156
  return false if early_bird_end_at.blank?
157
- early_bird_end_at >= Time.zone.now
157
+ early_bird_end_at <= Time.zone.now
158
158
  end
159
159
 
160
160
  def early_bird_status
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Just like each EventRegistration has EventTickets and EventRegistrants
4
- # An Event Registration has EventProducts and EventPurchases
4
+ # An Event Registration has EventProducts and EventAddons
5
5
 
6
6
  module Effective
7
- class EventPurchase < ActiveRecord::Base
7
+ class EventAddon < ActiveRecord::Base
8
8
  acts_as_purchasable
9
9
 
10
10
  log_changes(to: :event) if respond_to?(:log_changes)
@@ -4,8 +4,8 @@ module Effective
4
4
  class EventProduct < ActiveRecord::Base
5
5
  belongs_to :event
6
6
 
7
- has_many :event_purchases
8
- has_many :purchased_event_purchases, -> { EventPurchase.purchased }, class_name: 'Effective::EventPurchase'
7
+ has_many :event_addons
8
+ has_many :purchased_event_addons, -> { EventAddon.purchased }, class_name: 'Effective::EventAddon'
9
9
 
10
10
  log_changes(to: :event) if respond_to?(:log_changes)
11
11
 
@@ -22,12 +22,16 @@ module Effective
22
22
  tax_exempt :boolean
23
23
 
24
24
  position :integer
25
+ archived :boolean
25
26
 
26
27
  timestamps
27
28
  end
28
29
 
29
30
  scope :sorted, -> { order(:position) }
30
- scope :deep, -> { with_rich_text_body.includes(:purchased_event_purchases) }
31
+ scope :deep, -> { with_rich_text_body.includes(:purchased_event_addons) }
32
+
33
+ scope :archived, -> { where(archived: true) }
34
+ scope :unarchived, -> { where(archived: false) }
31
35
 
32
36
  before_validation(if: -> { event.present? }) do
33
37
  self.position ||= (event.event_products.map(&:position).compact.max || -1) + 1
@@ -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_addons_count), 0].max
46
60
  end
47
61
 
48
- def purchased_event_purchases_count
49
- purchased_event_purchases.count
62
+ def purchased_event_addons_count
63
+ purchased_event_addons.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
@@ -1,4 +1,4 @@
1
- = effective_form_with(model: [:admin, event_purchase], engine: true) do |f|
1
+ = effective_form_with(model: [:admin, event_addon], engine: true) do |f|
2
2
  = f.hidden_field :event_id
3
3
 
4
4
  - if f.object.new_record?
@@ -6,7 +6,7 @@
6
6
  - else
7
7
  = f.static_field :owner
8
8
 
9
- = render 'effective/event_purchases/fields', f: f, event: event_purchase.event
9
+ = render 'effective/event_addons/fields', f: f, event: event_addon.event
10
10
 
11
11
  - if f.object.new_record?
12
12
  = f.submit 'Save and Mark Paid'
@@ -2,8 +2,14 @@
2
2
  = f.hidden_field :event_id
3
3
 
4
4
  = f.text_field :title
5
- = f.price_field :price
6
- = f.text_field :qb_item_name
5
+ = f.number_field :capacity, hint: 'The number of addons will be limited to this capacity. Leave blank for unlimited capacity.'
6
+
7
+ = f.price_field :price, hint: 'A price of $0 will allow a checkout for free.'
7
8
  = f.check_box :tax_exempt
8
9
 
10
+ - if defined?(EffectiveQbSync)
11
+ = f.text_field :qb_item_name, label: 'QuickBooks item name'
12
+
13
+ = f.check_box :archived, label: 'Archive this product. It will be unavailable for purchase.'
14
+
9
15
  = effective_submit(f)
@@ -2,10 +2,15 @@
2
2
  = f.hidden_field :event_id
3
3
 
4
4
  = f.text_field :title
5
- = f.price_field :regular_price
6
- = f.price_field :early_bird_price
7
- = f.text_field :qb_item_name
5
+ = f.number_field :capacity, hint: 'The number of registrations will be limited to capacity. Leave blank for unlimited capacity.'
6
+
7
+ = f.price_field :regular_price, hint: 'A price of $0 will allow a checkout for free.'
8
+ = f.price_field :early_bird_price, hint: 'A price of $0 will allow a checkout for free.'
8
9
  = f.check_box :tax_exempt
9
- /= f.number_field :capacity, hint: 'The number of online purchases will be loosely limited to capacity.'
10
+
11
+ - if defined?(EffectiveQbSync)
12
+ = f.text_field :qb_item_name, label: 'QuickBooks item name'
13
+
14
+ = f.check_box :archived, label: 'Archive this ticket. It will be unavailable for purchase.'
10
15
 
11
16
  = effective_submit(f)
@@ -7,8 +7,6 @@
7
7
  = render '/admin/events/form_content', event: event
8
8
 
9
9
  = tab 'Tickets' do
10
- %p An event must have tickets before registration can begin
11
-
12
10
  %h2 Tickets
13
11
  - datatable = Admin::EffectiveEventTicketsDatatable.new(event_id: event.id)
14
12
  = render_inline_datatable(datatable)
@@ -28,9 +26,10 @@
28
26
  - datatable = Admin::EffectiveEventRegistrantsDatatable.new(event_id: event.id)
29
27
  .mb-4= render_inline_datatable(datatable)
30
28
 
31
- %h2 Purchases
32
- - datatable = Admin::EffectiveEventPurchasesDatatable.new(event_id: event.id)
33
- = render_inline_datatable(datatable)
29
+ = tab 'Add-ons' do
30
+ %h2 Add-ons
31
+ - datatable = Admin::EffectiveEventAddonsDatatable.new(event_id: event.id)
32
+ .mb-4= render_inline_datatable(datatable)
34
33
 
35
34
  = tab 'Wizard' do
36
35
  = render '/admin/events/form_event_registration_content', event: event
@@ -0,0 +1,8 @@
1
+ .card.mb-4
2
+ .card-body
3
+ - if f.object.purchased?
4
+ = f.static_field :event_product, label: 'Purchased event add-ons'
5
+ - else
6
+ = f.select :event_product_id, effective_events_event_products_collection(event), label: false
7
+
8
+ -# = f.text_area :notes, label: 'Notes'
@@ -1,11 +1,9 @@
1
- .card
1
+ .card.mb-4
2
2
  .card-body
3
- %h5.card-title Event Registrant
4
-
5
3
  - if f.object.purchased?
6
- = f.static_field :event_ticket, label: 'Purchased event ticket'
4
+ = f.static_field :event_ticket, label: 'Purchased ticket'
7
5
  - else
8
- = f.select :event_ticket_id, effective_events_event_tickets_collection(event)
6
+ = f.select :event_ticket_id, effective_events_event_tickets_collection(event), label: 'Ticket'
9
7
 
10
8
  .row
11
9
  .col-lg= f.text_field :first_name
@@ -0,0 +1,9 @@
1
+ = card do
2
+ .row
3
+ .col-sm
4
+ %h5.card-title= event_registration.wizard_step_title(:addons)
5
+ .col-sm-auto.text-right
6
+ = link_to('Edit', wizard_path(:addons)) if edit_effective_event_registrations_wizard?
7
+
8
+ - datatable = EffectiveEventAddonsDatatable.new(event_registration: event_registration)
9
+ .mb-4= render_simple_datatable(datatable)
@@ -2,9 +2,9 @@
2
2
  - step_content = resource.event&.send("rich_text_#{step}_content")
3
3
 
4
4
  - if all_steps_content.present?
5
- .card
5
+ .card.mb-4
6
6
  .card-body= all_steps_content
7
7
 
8
8
  - if step_content.present?
9
- .card
9
+ .card.mb-4
10
10
  .card-body= step_content
@@ -1,29 +1,26 @@
1
- .card
2
- .card-body
3
- %h5 Event Registration
1
+ = card('Event Registration') do
2
+ %table.table.table-sm
3
+ %tbody
4
+ %tr
5
+ %th.border-0 Event
6
+ %td.border-0
7
+ = link_to(event_registration.event, effective_events.event_path(event_registration.event))
4
8
 
5
- %table.table.table-sm
6
- %tbody
9
+ - if request.path.start_with?('/admin')
7
10
  %tr
8
- %th.border-0 Event
9
- %td.border-0
10
- = link_to(event_registration.event, effective_events.event_path(event_registration.event))
11
-
12
- - if request.path.start_with?('/admin')
13
- %tr
14
- %th Registered by
15
- %td
16
- - url = (polymorphic_admin_path(event_registration.owner) rescue "/admin/users/#{event_registration.owner.to_param}/edit")
17
- = link_to(event_registration.owner, url)
18
- - else
19
- %tr
20
- %th Registered by
21
- %td= event_registration.owner
11
+ %th Registered by
12
+ %td
13
+ - url = (polymorphic_admin_path(event_registration.owner) rescue "/admin/users/#{event_registration.owner.to_param}/edit")
14
+ = link_to(event_registration.owner, url)
15
+ - else
16
+ %tr
17
+ %th Registered by
18
+ %td= event_registration.owner
22
19
 
23
20
 
24
- - if event_registration.orders.present?
25
- %tr
26
- %th Order
27
- %td
28
- - event_registration.orders.each do |order|
29
- = link_to(order, effective_orders.order_path(order))
21
+ - if event_registration.orders.present?
22
+ %tr
23
+ %th Order
24
+ %td
25
+ - event_registration.orders.each do |order|
26
+ = link_to(order, effective_orders.order_path(order))
@@ -0,0 +1,9 @@
1
+ = card do
2
+ .row
3
+ .col-sm
4
+ %h5.card-title= event_registration.wizard_step_title(:tickets)
5
+ .col-sm-auto.text-right
6
+ = link_to('Edit', wizard_path(:tickets)) if edit_effective_event_registrations_wizard?
7
+
8
+ - datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
9
+ .mb-4= render_simple_datatable(datatable)
@@ -0,0 +1,19 @@
1
+ = render 'layout' do
2
+ .card.mb-4
3
+ .card-body
4
+ %p
5
+ Add-ons are free or paid additional items that can be included in your registration.
6
+ %br
7
+ If you are registering for multiple people, you need to include an add-on for each person.
8
+
9
+ = render 'effective/event_registrations/content', resource: resource
10
+
11
+ .card
12
+ .card-body
13
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
14
+ = f.hidden_field :id
15
+
16
+ = f.has_many :event_addons do |fp|
17
+ = render('effective/event_addons/fields', f: fp, event: f.object.event)
18
+
19
+ = f.save 'Save and Continue'
@@ -3,12 +3,13 @@
3
3
 
4
4
  - raise('expected owner to respond to billing_address') unless resource.owner.respond_to?(:billing_address)
5
5
 
6
- .card
7
- .card-body
8
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
9
- = f.hidden_field :id
6
+ = card('Billing Address') do
7
+ %p Please enter your billing address
10
8
 
11
- = f.fields_for(:owner, f.object.owner) do |fu|
12
- = effective_address_fields(fu, :billing)
9
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
10
+ = f.hidden_field :id
13
11
 
14
- = f.save 'Save and Continue'
12
+ = f.fields_for(:owner, f.object.owner) do |fu|
13
+ = effective_address_fields(fu, :billing)
14
+
15
+ = f.save 'Save and Continue'
@@ -3,8 +3,6 @@
3
3
 
4
4
  .card
5
5
  .card-body
6
- %p Please add one or more registrant.
7
-
8
6
  = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
9
7
  = f.hidden_field :id
10
8
 
@@ -2,12 +2,6 @@
2
2
 
3
3
  - upcoming = Effective::Event.events(user: current_user).upcoming.count
4
4
 
5
- %p
6
- - if upcoming == 1
7
- There is 1 upcoming event.
8
- - else
9
- There are #{upcoming} upcoming events.
10
-
11
5
  - datatable = EffectiveEventsDatatable.new(self, namespace: :effective)
12
6
  = render_datatable(datatable, simple: true)
13
7
 
@@ -1,7 +1,9 @@
1
1
  EffectiveEvents.setup do |config|
2
2
  config.events_table_name = :events
3
3
  config.event_tickets_table_name = :event_tickets
4
+ config.event_products_table_name = :event_products
4
5
  config.event_registrants_table_name = :event_registrants
6
+ config.event_addons_table_name = :event_addons
5
7
  config.event_registrations_table_name = :event_registrations
6
8
 
7
9
  # Layout Settings
@@ -11,7 +13,9 @@ EffectiveEvents.setup do |config|
11
13
  # Event Settings
12
14
  # config.event_registrations_class_name = 'Effective::EventRegistration'
13
15
 
16
+ # Pagination length on the Events#index page
14
17
  config.per_page = 10
15
18
 
19
+ # Events can be restricted by role
16
20
  config.use_effective_roles = true
17
21
  end
data/config/routes.rb CHANGED
@@ -19,7 +19,7 @@ EffectiveEvents::Engine.routes.draw do
19
19
  resources :event_tickets, except: [:show]
20
20
  resources :event_products, except: [:show]
21
21
  resources :event_registrants, except: [:show]
22
- resources :event_purchases, except: [:show]
22
+ resources :event_addons, except: [:show]
23
23
  resources :event_registrations, only: [:index, :show]
24
24
  end
25
25
 
@@ -1,6 +1,6 @@
1
1
  class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
2
2
  def change
3
- create_table :events do |t|
3
+ create_table <%= @events_table_name %> do |t|
4
4
  t.string :title
5
5
 
6
6
  t.string :slug
@@ -14,7 +14,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
14
14
  t.datetime :early_bird_end_at
15
15
 
16
16
  t.integer :event_registrants_count, default: 0
17
- t.integer :event_purchases_count, default: 0
17
+ t.integer :event_addons_count, default: 0
18
18
 
19
19
  t.integer :roles_mask
20
20
  t.boolean :authenticate_user, default: false
@@ -22,10 +22,10 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
22
22
  t.timestamps
23
23
  end
24
24
 
25
- add_index :events, :title
26
- add_index :events, :end_at
25
+ add_index <%= @events_table_name %>, :title
26
+ add_index <%= @events_table_name %>, :end_at
27
27
 
28
- create_table :event_tickets do |t|
28
+ create_table <%= @event_tickets_table_name %> do |t|
29
29
  t.integer :event_id
30
30
 
31
31
  t.string :title
@@ -38,11 +38,12 @@ 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
44
45
 
45
- create_table :event_registrants do |t|
46
+ create_table <%= @event_registrants_table_name %> do |t|
46
47
  t.integer :event_id
47
48
  t.integer :event_ticket_id
48
49
 
@@ -66,7 +67,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
66
67
  t.timestamps
67
68
  end
68
69
 
69
- create_table :event_products do |t|
70
+ create_table <%= @event_products_table_name %> do |t|
70
71
  t.integer :event_id
71
72
 
72
73
  t.string :title
@@ -78,11 +79,12 @@ 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
84
86
 
85
- create_table :event_purchases do |t|
87
+ create_table <%= @event_addons_table_name %> do |t|
86
88
  t.integer :event_id
87
89
  t.integer :event_product_id
88
90
 
@@ -100,7 +102,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
100
102
  t.timestamps
101
103
  end
102
104
 
103
- create_table :event_registrations do |t|
105
+ create_table <%= @event_registrations_table_name %> do |t|
104
106
  t.string :token
105
107
 
106
108
  t.integer :event_id
@@ -125,9 +127,9 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
125
127
  t.datetime :created_at
126
128
  end
127
129
 
128
- add_index :event_registrations, [:owner_id, :owner_type]
129
- add_index :event_registrations, :status
130
- add_index :event_registrations, :token
130
+ add_index <%= @event_registrations_table_name %>, [:owner_id, :owner_type]
131
+ add_index <%= @event_registrations_table_name %>, :status
132
+ add_index <%= @event_registrations_table_name %>, :token
131
133
 
132
134
  end
133
135
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.1.5'.freeze
2
+ VERSION = '0.1.9'.freeze
3
3
  end
@@ -6,7 +6,8 @@ module EffectiveEvents
6
6
 
7
7
  def self.config_keys
8
8
  [
9
- :events_table_name, :event_registrants_table_name, :event_tickets_table_name, :event_registrations_table_name,
9
+ :events_table_name, :event_registrants_table_name, :event_tickets_table_name,
10
+ :event_registrations_table_name, :event_products_table_name, :event_addons_table_name,
10
11
  :layout, :per_page, :use_effective_roles,
11
12
  :event_registration_class_name
12
13
  ]
@@ -21,6 +21,11 @@ module EffectiveEvents
21
21
 
22
22
  def create_migration_file
23
23
  @events_table_name = ':' + EffectiveEvents.events_table_name.to_s
24
+ @event_products_table_name = ':' + EffectiveEvents.event_products_table_name.to_s
25
+ @event_addons_table_name = ':' + EffectiveEvents.event_addons_table_name.to_s
26
+ @event_registrants_table_name = ':' + EffectiveEvents.event_registrants_table_name.to_s
27
+ @event_registrations_table_name = ':' + EffectiveEvents.event_registrations_table_name.to_s
28
+ @event_tickets_table_name = ':' + EffectiveEvents.event_tickets_table_name.to_s
24
29
 
25
30
  migration_template ('../' * 3) + 'db/migrate/01_create_effective_events.rb.erb', 'db/migrate/create_effective_events.rb'
26
31
  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.9
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-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -179,34 +179,34 @@ files:
179
179
  - app/assets/javascripts/effective_events/base.js
180
180
  - app/assets/stylesheets/effective_events.scss
181
181
  - app/assets/stylesheets/effective_events/base.scss
182
+ - app/controllers/admin/event_addons_controller.rb
182
183
  - app/controllers/admin/event_products_controller.rb
183
- - app/controllers/admin/event_purchases_controller.rb
184
184
  - app/controllers/admin/event_registrants_controller.rb
185
185
  - app/controllers/admin/event_registrations_controller.rb
186
186
  - app/controllers/admin/event_tickets_controller.rb
187
187
  - app/controllers/admin/events_controller.rb
188
188
  - app/controllers/effective/event_registrations_controller.rb
189
189
  - app/controllers/effective/events_controller.rb
190
+ - app/datatables/admin/effective_event_addons_datatable.rb
190
191
  - app/datatables/admin/effective_event_products_datatable.rb
191
- - app/datatables/admin/effective_event_purchases_datatable.rb
192
192
  - app/datatables/admin/effective_event_registrants_datatable.rb
193
193
  - app/datatables/admin/effective_event_registrations_datatable.rb
194
194
  - app/datatables/admin/effective_event_tickets_datatable.rb
195
195
  - app/datatables/admin/effective_events_datatable.rb
196
- - app/datatables/effective_event_purchases_datatable.rb
196
+ - app/datatables/effective_event_addons_datatable.rb
197
197
  - app/datatables/effective_event_registrants_datatable.rb
198
198
  - app/datatables/effective_event_registrations_datatable.rb
199
199
  - app/datatables/effective_events_datatable.rb
200
200
  - app/helpers/effective_events_helper.rb
201
201
  - app/models/concerns/effective_events_event_registration.rb
202
202
  - app/models/effective/event.rb
203
+ - app/models/effective/event_addon.rb
203
204
  - app/models/effective/event_product.rb
204
- - app/models/effective/event_purchase.rb
205
205
  - app/models/effective/event_registrant.rb
206
206
  - app/models/effective/event_registration.rb
207
207
  - app/models/effective/event_ticket.rb
208
+ - app/views/admin/event_addons/_form.html.haml
208
209
  - app/views/admin/event_products/_form.html.haml
209
- - app/views/admin/event_purchases/_form.html.haml
210
210
  - app/views/admin/event_registrants/_form.html.haml
211
211
  - app/views/admin/event_tickets/_form.html.haml
212
212
  - app/views/admin/events/_form.html.haml
@@ -214,23 +214,23 @@ files:
214
214
  - app/views/admin/events/_form_content.html.haml
215
215
  - app/views/admin/events/_form_event.html.haml
216
216
  - app/views/admin/events/_form_event_registration_content.html.haml
217
- - app/views/effective/event_purchases/_fields.html.haml
217
+ - app/views/effective/event_addons/_fields.html.haml
218
218
  - app/views/effective/event_registrants/_fields.html.haml
219
+ - app/views/effective/event_registrations/_addons.html.haml
219
220
  - app/views/effective/event_registrations/_content.html.haml
220
221
  - app/views/effective/event_registrations/_dashboard.html.haml
221
222
  - app/views/effective/event_registrations/_event_registration.html.haml
222
223
  - app/views/effective/event_registrations/_layout.html.haml
223
224
  - app/views/effective/event_registrations/_orders.html.haml
224
- - app/views/effective/event_registrations/_purchases.html.haml
225
- - app/views/effective/event_registrations/_registrants.html.haml
226
225
  - app/views/effective/event_registrations/_summary.html.haml
226
+ - app/views/effective/event_registrations/_tickets.haml
227
+ - app/views/effective/event_registrations/addons.html.haml
227
228
  - app/views/effective/event_registrations/billing.html.haml
228
229
  - app/views/effective/event_registrations/checkout.html.haml
229
- - app/views/effective/event_registrations/purchases.html.haml
230
- - app/views/effective/event_registrations/registrants.html.haml
231
230
  - app/views/effective/event_registrations/start.html.haml
232
231
  - app/views/effective/event_registrations/submitted.html.haml
233
232
  - app/views/effective/event_registrations/summary.html.haml
233
+ - app/views/effective/event_registrations/tickets.haml
234
234
  - app/views/effective/events/_dashboard.html.haml
235
235
  - app/views/effective/events/_event.html.haml
236
236
  - app/views/effective/events/_layout.html.haml
@@ -1,10 +0,0 @@
1
- .card
2
- .card-body
3
- %h5.card-title Event Purchase
4
-
5
- - if f.object.purchased?
6
- = f.static_field :event_product, label: 'Purchased event product'
7
- - else
8
- = f.select :event_product_id, effective_events_event_products_collection(event)
9
-
10
- = f.text_area :notes, label: 'Notes'
@@ -1,10 +0,0 @@
1
- .card
2
- .card-body
3
- .row
4
- .col-sm
5
- %h5.card-title= event_registration.wizard_step_title(:purchases)
6
- .col-sm-auto.text-right
7
- = link_to('Edit', wizard_path(:purchases)) if edit_effective_event_registrations_wizard?
8
-
9
- - datatable = EffectiveEventPurchasesDatatable.new(event_registration: event_registration)
10
- .mb-4= render_simple_datatable(datatable)
@@ -1,10 +0,0 @@
1
- .card
2
- .card-body
3
- .row
4
- .col-sm
5
- %h5.card-title= event_registration.wizard_step_title(:registrants)
6
- .col-sm-auto.text-right
7
- = link_to('Edit', wizard_path(:registrants)) if edit_effective_event_registrations_wizard?
8
-
9
- - datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
10
- .mb-4= render_simple_datatable(datatable)
@@ -1,14 +0,0 @@
1
- = render 'layout' do
2
- = render 'effective/event_registrations/content', resource: resource
3
-
4
- .card
5
- .card-body
6
- %p Please add one or more products.
7
-
8
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
9
- = f.hidden_field :id
10
-
11
- = f.has_many :event_purchases do |fp|
12
- = render('effective/event_purchases/fields', f: fp, event: f.object.event)
13
-
14
- = f.save 'Save and Continue'