effective_events 0.1.4 → 0.1.8

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -2
  3. data/app/controllers/admin/event_addons_controller.rb +10 -0
  4. data/app/controllers/admin/event_products_controller.rb +8 -0
  5. data/app/controllers/effective/event_registrations_controller.rb +1 -3
  6. data/app/datatables/admin/effective_event_addons_datatable.rb +41 -0
  7. data/app/datatables/admin/effective_event_products_datatable.rb +50 -0
  8. data/app/datatables/admin/effective_event_registrations_datatable.rb +2 -1
  9. data/app/datatables/admin/effective_event_tickets_datatable.rb +10 -1
  10. data/app/datatables/admin/effective_events_datatable.rb +7 -6
  11. data/app/datatables/effective_event_addons_datatable.rb +38 -0
  12. data/app/datatables/effective_event_registrants_datatable.rb +1 -1
  13. data/app/datatables/effective_event_registrations_datatable.rb +2 -1
  14. data/app/datatables/effective_events_datatable.rb +2 -2
  15. data/app/helpers/effective_events_helper.rb +22 -3
  16. data/app/models/concerns/effective_events_event_registration.rb +36 -100
  17. data/app/models/effective/event.rb +8 -2
  18. data/app/models/effective/event_addon.rb +71 -0
  19. data/app/models/effective/event_product.rb +67 -0
  20. data/app/models/effective/event_registrant.rb +1 -0
  21. data/app/models/effective/event_ticket.rb +18 -4
  22. data/app/views/admin/event_addons/_form.html.haml +14 -0
  23. data/app/views/admin/event_products/_form.html.haml +15 -0
  24. data/app/views/admin/event_tickets/_form.html.haml +11 -2
  25. data/app/views/admin/events/_form.html.haml +22 -7
  26. data/app/views/effective/event_addons/_fields.html.haml +8 -0
  27. data/app/views/effective/event_registrants/_fields.html.haml +3 -5
  28. data/app/views/effective/event_registrations/_addons.html.haml +9 -0
  29. data/app/views/effective/event_registrations/_registrants.html.haml +8 -9
  30. data/app/views/effective/event_registrations/_summary.html.haml +22 -25
  31. data/app/views/effective/event_registrations/addons.html.haml +17 -0
  32. data/app/views/effective/event_registrations/billing.html.haml +8 -7
  33. data/app/views/effective/event_registrations/registrants.html.haml +0 -2
  34. data/app/views/effective/events/_dashboard.html.haml +0 -6
  35. data/config/effective_events.rb +4 -0
  36. data/config/routes.rb +2 -0
  37. data/db/migrate/01_create_effective_events.rb.erb +46 -9
  38. data/lib/effective_events/version.rb +1 -1
  39. data/lib/effective_events.rb +2 -1
  40. data/lib/generators/effective_events/install_generator.rb +5 -0
  41. metadata +14 -3
  42. data/app/views/effective/event_tickets/_fields.html.haml +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2a6d166ba053eb00016f2ea09e4f9fe64ebf8e2ddd3778261553891f664b81b
4
- data.tar.gz: ebb4c682a522a196dcc9714cacd50cfb9cac974e8f92b3412fca65ea7a470f7c
3
+ metadata.gz: 44c51f928a7db75214d362f3809a5249cdebb8a22e9239f5cc74e0ea19db958b
4
+ data.tar.gz: '099acc31c59746278f78b679b6605430f128f40fa22bfe441c92c84cff974e15'
5
5
  SHA512:
6
- metadata.gz: c44d5e9c255466984eda2b7470f7690810982d176ca4ef8c6c29225c3703ceb25d6c263e9ebc7792aa710450a54ad0370899a5295182665743e725ebe1d6b2c4
7
- data.tar.gz: 726518bd5c9fb10b52d4d1b92d03ff1ca7f08a8c474b0494fbc6c55cf4da9d573dbd43d13905076305415f0208a6ea17a9c0a42e4332fe1a4884e2103d5c9397
6
+ metadata.gz: 623603bcfb7c8ad11228d10a6526c1799c92482fb57e0b258ff43d75c39f40d014a3449946edd11d745026987d62f5da7739667bfc5b2f427acb348341edac17
7
+ data.tar.gz: 8eac487ea782b237e1efb89163c799a0f95224f5682d82e08ad4d16930b0e0f953ba7ab6f7f9b8f5e44ad9b82443adbdb29786145bd1ce16f0a1062b762bf1d0
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
 
@@ -0,0 +1,10 @@
1
+ module Admin
2
+ class EventAddonsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_events) }
5
+
6
+ include Effective::CrudController
7
+
8
+ submit :mark_paid, 'Save and Mark Paid'
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module Admin
2
+ class EventProductsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_events) }
5
+
6
+ include Effective::CrudController
7
+ end
8
+ end
@@ -40,9 +40,7 @@ module Effective
40
40
  def permitted_params
41
41
  model = (params.key?(:effective_event_registration) ? :effective_event_registration : :event_registration)
42
42
 
43
- params.require(model).permit!.except(
44
- :status, :status_steps, :wizard_steps, :submitted_at
45
- )
43
+ params.require(model).permit!.except(:status, :status_steps, :wizard_steps, :submitted_at)
46
44
  end
47
45
 
48
46
  end
@@ -0,0 +1,41 @@
1
+ module Admin
2
+ class EffectiveEventAddonsDatatable < Effective::Datatable
3
+ datatable do
4
+ col :updated_at, visible: false
5
+ col :created_at, visible: false
6
+ col :id, visible: false
7
+
8
+ col :event
9
+
10
+ col :event_registration, visible: false
11
+
12
+ if attributes[:event_id]
13
+ col :event_product, search: Effective::EventProduct.where(event: event).all
14
+ else
15
+ col :event_product, search: :string
16
+ end
17
+
18
+ col :purchased_order
19
+ col :owner
20
+ col :notes, label: 'Notes'
21
+
22
+ actions_col
23
+ end
24
+
25
+ collection do
26
+ scope = Effective::EventAddon.deep.purchased
27
+
28
+ if attributes[:event_id].present?
29
+ scope = scope.where(event: event)
30
+ end
31
+
32
+ scope
33
+ end
34
+
35
+ def event
36
+ @event ||= if attributes[:event_id]
37
+ Effective::Event.find(attributes[:event_id])
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,50 @@
1
+ module Admin
2
+ class EffectiveEventProductsDatatable < Effective::Datatable
3
+ datatable do
4
+ reorder :position
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ col :event
11
+
12
+ col :title
13
+ col :price, as: :price
14
+
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
+
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|
29
+ content_tag(:div, purchase.owner.to_s, class: 'col-resource_item')
30
+ end.join.html_safe
31
+ end
32
+
33
+ actions_col
34
+ end
35
+
36
+ collection do
37
+ scope = Effective::EventProduct.deep.all
38
+
39
+ if attributes[:event_id]
40
+ scope = scope.where(event: event)
41
+ end
42
+
43
+ scope
44
+ end
45
+
46
+ def event
47
+ Effective::Event.find(attributes[:event_id])
48
+ end
49
+ end
50
+ end
@@ -9,10 +9,11 @@ class Admin::EffectiveEventRegistrationsDatatable < Effective::Datatable
9
9
 
10
10
  col :submitted_at, label: 'Submitted', visible: false, as: :date
11
11
 
12
- col :event
12
+ col :event, search: :string
13
13
  col :owner
14
14
 
15
15
  col :event_registrants, search: :string
16
+ col :event_addons, search: :string
16
17
  col :orders, label: 'Order'
17
18
 
18
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
@@ -0,0 +1,38 @@
1
+ # Used on the Event Registrations Addons step
2
+
3
+ class EffectiveEventAddonsDatatable < Effective::Datatable
4
+ datatable do
5
+
6
+ col :event_product, search: :string, label: 'Product'
7
+ col :price, as: :price
8
+ # col :notes
9
+ # no actions_col
10
+ end
11
+
12
+ collection do
13
+ scope = Effective::EventAddon.deep.all
14
+
15
+ if event.present?
16
+ scope = scope.where(event: event)
17
+ end
18
+
19
+ if event_registration.present?
20
+ scope = scope.where(event_registration_id: event_registration)
21
+ end
22
+
23
+ scope
24
+ end
25
+
26
+ def event
27
+ @event ||= if attributes[:event_id]
28
+ Effective::Event.find(attributes[:event_id])
29
+ end
30
+ end
31
+
32
+ def event_registration
33
+ @event_registration ||= if attributes[:event_registration_id]
34
+ EffectiveEvents.EventRegistration.find_by_id(attributes[:event_registration_id])
35
+ end
36
+ end
37
+
38
+ end
@@ -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,11 +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
15
+ end
16
+ end
17
+
18
+ def effective_events_event_products_collection(event)
19
+ raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
20
+
21
+ event.event_products.reject(&:archived?).map do |product|
22
+ title = product.to_s
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?
28
+
29
+ [label, product.to_param, disabled].compact
11
30
  end
12
31
  end
13
32
 
@@ -37,12 +37,15 @@ module EffectiveEventsEventRegistration
37
37
  acts_as_wizard(
38
38
  start: 'Start',
39
39
  registrants: 'Registrants',
40
+ addons: 'Add-ons',
40
41
  summary: 'Review',
41
42
  billing: 'Billing Address',
42
43
  checkout: 'Checkout',
43
44
  submitted: 'Submitted'
44
45
  )
45
46
 
47
+ acts_as_purchasable_wizard
48
+
46
49
  log_changes(except: :wizard_steps) if respond_to?(:log_changes)
47
50
 
48
51
  # Application Namespace
@@ -50,11 +53,14 @@ module EffectiveEventsEventRegistration
50
53
  accepts_nested_attributes_for :owner
51
54
 
52
55
  # Effective Namespace
53
- belongs_to :event
56
+ belongs_to :event, class_name: 'Effective::Event'
54
57
 
55
- has_many :event_registrants, -> { order(:id) }, inverse_of: :event_registration, dependent: :destroy
58
+ has_many :event_registrants, -> { order(:id) }, class_name: 'Effective::EventRegistrant', inverse_of: :event_registration, dependent: :destroy
56
59
  accepts_nested_attributes_for :event_registrants, reject_if: :all_blank, allow_destroy: true
57
60
 
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
+
58
64
  has_many :orders, -> { order(:id) }, as: :parent, class_name: 'Effective::Order', dependent: :nullify
59
65
  accepts_nested_attributes_for :orders
60
66
 
@@ -89,17 +95,29 @@ module EffectiveEventsEventRegistration
89
95
  self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
90
96
  end
91
97
 
92
- # Billing Step
93
- validate(if: -> { current_step == :billing && owner.present? }) do
94
- self.errors.add(:base, "must have a billing address") unless owner.billing_address.present?
95
- self.errors.add(:base, "must have an email") unless owner.email.present?
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
96
109
  end
97
110
 
98
- after_purchase do |_|
99
- raise('expected submit_order to be purchased') unless submit_order&.purchased?
100
- submit_purchased!
101
- after_submit_purchased!
111
+ def required_steps
112
+ return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
113
+ event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:addons])
102
114
  end
115
+
116
+ # All Fees and Orders
117
+ def submit_fees
118
+ (event_registrants + event_addons)
119
+ end
120
+
103
121
  end
104
122
 
105
123
  # Instance Methods
@@ -115,14 +133,16 @@ module EffectiveEventsEventRegistration
115
133
  submitted?
116
134
  end
117
135
 
118
- def can_visit_step?(step)
119
- can_revisit_completed_steps(step)
136
+ # Find or build
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)
120
140
  end
121
141
 
122
- # Find or build
123
- def event_registrant(first_name:, last_name:, email:)
124
- registrant = event_registrants.find { |er| er.first_name == first_name && er.last_name == last_name && er.email == email }
125
- registrant || event_registrants.build(event: event, owner: owner, first_name: first_name, last_name: last_name, email: email)
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)
126
146
  end
127
147
 
128
148
  # This builds the default event registrants used by the wizard form
@@ -139,90 +159,6 @@ module EffectiveEventsEventRegistration
139
159
  event_registrants
140
160
  end
141
161
 
142
- # All Fees and Orders
143
- def submit_fees
144
- event_registrants
145
- end
146
-
147
- def submit_order
148
- orders.first
149
- end
150
-
151
- def find_or_build_submit_order
152
- order = submit_order || orders.build(user: owner)
153
- fees = submit_fees()
154
-
155
- # Adds fees, but does not overwrite any existing price.
156
- fees.each do |fee|
157
- order.add(fee) unless order.purchasables.include?(fee)
158
- end
159
-
160
- order.purchasables.each do |purchasable|
161
- order.remove(purchasable) unless fees.include?(purchasable)
162
- end
163
-
164
- # From Billing Step
165
- order.billing_address = owner.billing_address if owner.billing_address.present?
166
-
167
- # Important to add/remove anything
168
- order.save
169
-
170
- order
171
- end
172
-
173
- # Should be indempotent.
174
- def build_submit_fees_and_order
175
- return false if was_submitted?
176
-
177
- fees = submit_fees()
178
- raise('already has purchased submit fees') if fees.any?(&:purchased?)
179
-
180
- order = find_or_build_submit_order()
181
- raise('already has purchased submit order') if order.purchased?
182
-
183
- true
184
- end
185
-
186
- # If they go back and change registrants. Update the order right away.
187
- def registrants!
188
- save!
189
- build_submit_fees_and_order if submit_order.present?
190
- true
191
- end
192
-
193
- # Owner clicks on the Billing step. Next step is Checkout
194
- def billing!
195
- ready!
196
- end
197
-
198
- # Ready to check out
199
- def ready!
200
- build_submit_fees_and_order
201
- save!
202
- end
203
-
204
- # Called automatically via after_purchase hook above
205
- def submit_purchased!
206
- return false if was_submitted?
207
-
208
- wizard_steps[:checkout] = Time.zone.now
209
- submit!
210
- end
211
-
212
- # A hook to extend
213
- def after_submit_purchased!
214
- end
215
-
216
- # Draft -> Submitted requirements
217
- def submit!
218
- raise('already submitted') if was_submitted?
219
- raise('expected a purchased order') unless submit_order&.purchased?
220
-
221
- wizard_steps[:checkout] ||= Time.zone.now
222
- wizard_steps[:submitted] = Time.zone.now
223
- submitted!
224
- end
225
-
226
162
  private
227
163
 
228
164
  def present_event_registrants
@@ -2,11 +2,17 @@
2
2
 
3
3
  module Effective
4
4
  class Event < ActiveRecord::Base
5
+ has_many :event_tickets, -> { EventTicket.sorted }, inverse_of: :event
6
+ accepts_nested_attributes_for :event_tickets, allow_destroy: true
7
+
8
+ has_many :event_products, -> { EventProduct.sorted }, inverse_of: :event
9
+ accepts_nested_attributes_for :event_products, allow_destroy: true
10
+
5
11
  has_many :event_registrants, -> { order(:event_ticket_id, :created_at) }, inverse_of: :event
6
12
  accepts_nested_attributes_for :event_registrants, allow_destroy: true
7
13
 
8
- has_many :event_tickets, -> { order(:id) }, inverse_of: :event
9
- accepts_nested_attributes_for :event_tickets, 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
10
16
 
11
17
  # rich_text_body - Used by the select step
12
18
  has_many_rich_texts
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Just like each EventRegistration has EventTickets and EventRegistrants
4
+ # An Event Registration has EventProducts and EventAddons
5
+
6
+ module Effective
7
+ class EventAddon < ActiveRecord::Base
8
+ acts_as_purchasable
9
+
10
+ log_changes(to: :event) if respond_to?(:log_changes)
11
+
12
+ belongs_to :event, counter_cache: true
13
+
14
+ # Basically a category containing all the pricing and unique info about this product purchase
15
+ belongs_to :event_product
16
+
17
+ # Every event registrant is charged to a owner
18
+ belongs_to :owner, polymorphic: true
19
+
20
+ # This fee when checked out through the event registration
21
+ belongs_to :event_registration, polymorphic: true, optional: true
22
+
23
+ effective_resource do
24
+ notes :text
25
+
26
+ # Acts as Purchasable
27
+ price :integer
28
+ qb_item_name :string
29
+ tax_exempt :boolean
30
+
31
+ timestamps
32
+ end
33
+
34
+ scope :sorted, -> { order(:id) }
35
+ scope :deep, -> { all }
36
+
37
+ before_validation(if: -> { event_registration.present? }) do
38
+ self.event ||= event_registration.event
39
+ self.owner ||= event_registration.owner
40
+ end
41
+
42
+ before_validation(if: -> { event_product.present? }) do
43
+ self.price ||= event_product.price
44
+ end
45
+
46
+ def to_s
47
+ persisted? ? event_product.to_s : 'product'
48
+ end
49
+
50
+ def tax_exempt
51
+ event_product.tax_exempt
52
+ end
53
+
54
+ def qb_item_name
55
+ event_product.qb_item_name
56
+ end
57
+
58
+ # This is the Admin Save and Mark Paid action
59
+ def mark_paid!
60
+ raise('expected a blank event registration') if event_registration.present?
61
+
62
+ save!
63
+
64
+ order = Effective::Order.new(items: self, user: owner)
65
+ order.purchase!(skip_buyer_validations: true, email: false)
66
+
67
+ true
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Effective
4
+ class EventProduct < ActiveRecord::Base
5
+ belongs_to :event
6
+
7
+ has_many :event_addons
8
+ has_many :purchased_event_addons, -> { EventAddon.purchased }, class_name: 'Effective::EventAddon'
9
+
10
+ log_changes(to: :event) if respond_to?(:log_changes)
11
+
12
+ has_rich_text :body
13
+
14
+ effective_resource do
15
+ title :string
16
+ capacity :integer
17
+
18
+ # Pricing
19
+ price :integer
20
+
21
+ qb_item_name :string
22
+ tax_exempt :boolean
23
+
24
+ position :integer
25
+ archived :boolean
26
+
27
+ timestamps
28
+ end
29
+
30
+ scope :sorted, -> { order(:position) }
31
+ scope :deep, -> { with_rich_text_body.includes(:purchased_event_addons) }
32
+
33
+ scope :archived, -> { where(archived: true) }
34
+ scope :unarchived, -> { where(archived: false) }
35
+
36
+ before_validation(if: -> { event.present? }) do
37
+ self.position ||= (event.event_products.map(&:position).compact.max || -1) + 1
38
+ end
39
+
40
+ validates :title, presence: true, uniqueness: { scope: [:event_id] }
41
+ validates :price, presence: true
42
+
43
+ def to_s
44
+ title.presence || 'New Event Product'
45
+ end
46
+
47
+ # Available for purchase
48
+ def available?
49
+ return false if archived?
50
+ capacity_available?
51
+ end
52
+
53
+ def capacity_available?
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
60
+ end
61
+
62
+ def purchased_event_addons_count
63
+ purchased_event_addons.length
64
+ end
65
+
66
+ end
67
+ end
@@ -3,6 +3,7 @@
3
3
  module Effective
4
4
  class EventRegistrant < ActiveRecord::Base
5
5
  acts_as_purchasable
6
+
6
7
  log_changes(to: :event) if respond_to?(:log_changes)
7
8
 
8
9
  belongs_to :event, counter_cache: true
@@ -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,11 +31,14 @@ 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
36
40
 
37
- validates :title, presence: true
41
+ validates :title, presence: true, uniqueness: { scope: [:event_id] }
38
42
  validates :regular_price, presence: true
39
43
  validates :early_bird_price, presence: true, if: -> { event&.early_bird_end_at.present? }
40
44
 
@@ -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
@@ -0,0 +1,14 @@
1
+ = effective_form_with(model: [:admin, event_addon], engine: true) do |f|
2
+ = f.hidden_field :event_id
3
+
4
+ - if f.object.new_record?
5
+ = f.select :owner, { 'Users' => current_user.class.all }, polymorphic: true
6
+ - else
7
+ = f.static_field :owner
8
+
9
+ = render 'effective/event_addons/fields', f: f, event: event_addon.event
10
+
11
+ - if f.object.new_record?
12
+ = f.submit 'Save and Mark Paid'
13
+ - else
14
+ = f.submit 'Save'
@@ -0,0 +1,15 @@
1
+ = effective_form_with(model: [:admin, event_product], engine: true) do |f|
2
+ = f.hidden_field :event_id
3
+
4
+ = f.text_field :title
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.'
8
+ = f.check_box :tax_exempt
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
+
15
+ = effective_submit(f)
@@ -1,7 +1,16 @@
1
1
  = effective_form_with(model: [:admin, event_ticket], engine: true) do |f|
2
2
  = f.hidden_field :event_id
3
3
 
4
- /= f.number_field :capacity, hint: 'The number of online purchases will be loosely limited to capacity.'
5
- = render 'effective/event_tickets/fields', f: f
4
+ = f.text_field :title
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.'
9
+ = f.check_box :tax_exempt
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.'
6
15
 
7
16
  = effective_submit(f)
@@ -3,20 +3,35 @@
3
3
  = render 'admin/events/form_event', event: event
4
4
 
5
5
  - if event.persisted?
6
- = tab 'Registrants' do
7
- - datatable = Admin::EffectiveEventRegistrantsDatatable.new(event_id: event.id)
8
- = render_inline_datatable(datatable)
9
-
10
6
  = tab 'Content' do
11
7
  = render '/admin/events/form_content', event: event
12
8
 
13
9
  = tab 'Tickets' do
14
- %p An event must have tickets before registration can begin
15
-
10
+ %h2 Tickets
16
11
  - datatable = Admin::EffectiveEventTicketsDatatable.new(event_id: event.id)
17
12
  = render_inline_datatable(datatable)
18
13
 
19
- = tab 'Registration' do
14
+ = tab 'Products' do
15
+ %h2 Products
16
+ - datatable = Admin::EffectiveEventProductsDatatable.new(event_id: event.id)
17
+ = render_inline_datatable(datatable)
18
+
19
+ = tab 'Registrations' do
20
+ %h2 Registrations
21
+ - datatable = Admin::EffectiveEventRegistrationsDatatable.new(event_id: event.id)
22
+ .mb-4= render_inline_datatable(datatable)
23
+
24
+ = tab 'Registrants' do
25
+ %h2 Registrants
26
+ - datatable = Admin::EffectiveEventRegistrantsDatatable.new(event_id: event.id)
27
+ .mb-4= render_inline_datatable(datatable)
28
+
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)
33
+
34
+ = tab 'Wizard' do
20
35
  = render '/admin/events/form_event_registration_content', event: event
21
36
 
22
37
  = tab 'Access' do
@@ -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)
@@ -1,10 +1,9 @@
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?
1
+ = card do
2
+ .row
3
+ .col-sm
4
+ %h5.card-title= event_registration.wizard_step_title(:registrants)
5
+ .col-sm-auto.text-right
6
+ = link_to('Edit', wizard_path(:registrants)) if edit_effective_event_registrations_wizard?
8
7
 
9
- - datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
10
- .mb-4= render_simple_datatable(datatable)
8
+ - datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
9
+ .mb-4= render_simple_datatable(datatable)
@@ -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,17 @@
1
+ = render 'layout' do
2
+ = render 'effective/event_registrations/content', resource: resource
3
+
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
+ .card
10
+ .card-body
11
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
12
+ = f.hidden_field :id
13
+
14
+ = f.has_many :event_addons do |fp|
15
+ = render('effective/event_addons/fields', f: fp, event: f.object.event)
16
+
17
+ = 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
@@ -17,7 +17,9 @@ EffectiveEvents::Engine.routes.draw do
17
17
  namespace :admin do
18
18
  resources :events, except: [:show]
19
19
  resources :event_tickets, except: [:show]
20
+ resources :event_products, except: [:show]
20
21
  resources :event_registrants, except: [:show]
22
+ resources :event_addons, except: [:show]
21
23
  resources :event_registrations, only: [:index, :show]
22
24
  end
23
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,6 +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_addons_count, default: 0
17
18
 
18
19
  t.integer :roles_mask
19
20
  t.boolean :authenticate_user, default: false
@@ -21,10 +22,10 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
21
22
  t.timestamps
22
23
  end
23
24
 
24
- add_index :events, :title
25
- add_index :events, :end_at
25
+ add_index <%= @events_table_name %>, :title
26
+ add_index <%= @events_table_name %>, :end_at
26
27
 
27
- create_table :event_tickets do |t|
28
+ create_table <%= @event_tickets_table_name %> do |t|
28
29
  t.integer :event_id
29
30
 
30
31
  t.string :title
@@ -37,11 +38,12 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
37
38
  t.boolean :tax_exempt, default: false
38
39
 
39
40
  t.integer :position
41
+ t.boolean :archived, default: false
40
42
 
41
43
  t.timestamps
42
44
  end
43
45
 
44
- create_table :event_registrants do |t|
46
+ create_table <%= @event_registrants_table_name %> do |t|
45
47
  t.integer :event_id
46
48
  t.integer :event_ticket_id
47
49
 
@@ -65,7 +67,42 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
65
67
  t.timestamps
66
68
  end
67
69
 
68
- create_table :event_registrations do |t|
70
+ create_table <%= @event_products_table_name %> do |t|
71
+ t.integer :event_id
72
+
73
+ t.string :title
74
+ t.integer :capacity
75
+
76
+ t.integer :price
77
+
78
+ t.string :qb_item_name
79
+ t.boolean :tax_exempt, default: false
80
+
81
+ t.integer :position
82
+ t.boolean :archived, default: false
83
+
84
+ t.timestamps
85
+ end
86
+
87
+ create_table <%= @event_addons_table_name %> do |t|
88
+ t.integer :event_id
89
+ t.integer :event_product_id
90
+
91
+ t.integer :owner_id
92
+ t.string :owner_type
93
+
94
+ t.integer :event_registration_id
95
+ t.string :event_registration_type
96
+
97
+ t.text :notes
98
+
99
+ t.integer :purchased_order_id
100
+ t.integer :price
101
+
102
+ t.timestamps
103
+ end
104
+
105
+ create_table <%= @event_registrations_table_name %> do |t|
69
106
  t.string :token
70
107
 
71
108
  t.integer :event_id
@@ -90,9 +127,9 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
90
127
  t.datetime :created_at
91
128
  end
92
129
 
93
- add_index :event_registrations, [:owner_id, :owner_type]
94
- add_index :event_registrations, :status
95
- 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
96
133
 
97
134
  end
98
135
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.1.4'.freeze
2
+ VERSION = '0.1.8'.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.4
4
+ version: 0.1.8
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-06 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,25 +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
183
+ - app/controllers/admin/event_products_controller.rb
182
184
  - app/controllers/admin/event_registrants_controller.rb
183
185
  - app/controllers/admin/event_registrations_controller.rb
184
186
  - app/controllers/admin/event_tickets_controller.rb
185
187
  - app/controllers/admin/events_controller.rb
186
188
  - app/controllers/effective/event_registrations_controller.rb
187
189
  - app/controllers/effective/events_controller.rb
190
+ - app/datatables/admin/effective_event_addons_datatable.rb
191
+ - app/datatables/admin/effective_event_products_datatable.rb
188
192
  - app/datatables/admin/effective_event_registrants_datatable.rb
189
193
  - app/datatables/admin/effective_event_registrations_datatable.rb
190
194
  - app/datatables/admin/effective_event_tickets_datatable.rb
191
195
  - app/datatables/admin/effective_events_datatable.rb
196
+ - app/datatables/effective_event_addons_datatable.rb
192
197
  - app/datatables/effective_event_registrants_datatable.rb
193
198
  - app/datatables/effective_event_registrations_datatable.rb
194
199
  - app/datatables/effective_events_datatable.rb
195
200
  - app/helpers/effective_events_helper.rb
196
201
  - app/models/concerns/effective_events_event_registration.rb
197
202
  - app/models/effective/event.rb
203
+ - app/models/effective/event_addon.rb
204
+ - app/models/effective/event_product.rb
198
205
  - app/models/effective/event_registrant.rb
199
206
  - app/models/effective/event_registration.rb
200
207
  - app/models/effective/event_ticket.rb
208
+ - app/views/admin/event_addons/_form.html.haml
209
+ - app/views/admin/event_products/_form.html.haml
201
210
  - app/views/admin/event_registrants/_form.html.haml
202
211
  - app/views/admin/event_tickets/_form.html.haml
203
212
  - app/views/admin/events/_form.html.haml
@@ -205,7 +214,9 @@ files:
205
214
  - app/views/admin/events/_form_content.html.haml
206
215
  - app/views/admin/events/_form_event.html.haml
207
216
  - app/views/admin/events/_form_event_registration_content.html.haml
217
+ - app/views/effective/event_addons/_fields.html.haml
208
218
  - app/views/effective/event_registrants/_fields.html.haml
219
+ - app/views/effective/event_registrations/_addons.html.haml
209
220
  - app/views/effective/event_registrations/_content.html.haml
210
221
  - app/views/effective/event_registrations/_dashboard.html.haml
211
222
  - app/views/effective/event_registrations/_event_registration.html.haml
@@ -213,13 +224,13 @@ files:
213
224
  - app/views/effective/event_registrations/_orders.html.haml
214
225
  - app/views/effective/event_registrations/_registrants.html.haml
215
226
  - app/views/effective/event_registrations/_summary.html.haml
227
+ - app/views/effective/event_registrations/addons.html.haml
216
228
  - app/views/effective/event_registrations/billing.html.haml
217
229
  - app/views/effective/event_registrations/checkout.html.haml
218
230
  - app/views/effective/event_registrations/registrants.html.haml
219
231
  - app/views/effective/event_registrations/start.html.haml
220
232
  - app/views/effective/event_registrations/submitted.html.haml
221
233
  - app/views/effective/event_registrations/summary.html.haml
222
- - app/views/effective/event_tickets/_fields.html.haml
223
234
  - app/views/effective/events/_dashboard.html.haml
224
235
  - app/views/effective/events/_event.html.haml
225
236
  - app/views/effective/events/_layout.html.haml
@@ -1,4 +0,0 @@
1
- = f.text_field :title
2
- = f.price_field :regular_price
3
- = f.price_field :early_bird_price
4
- = f.check_box :tax_exempt