effective_events 0.1.1 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/event_products_controller.rb +8 -0
  3. data/app/controllers/admin/event_purchases_controller.rb +11 -0
  4. data/app/controllers/effective/event_registrations_controller.rb +2 -8
  5. data/app/datatables/admin/effective_event_products_datatable.rb +41 -0
  6. data/app/datatables/admin/effective_event_purchases_datatable.rb +41 -0
  7. data/app/datatables/admin/effective_event_registrations_datatable.rb +2 -1
  8. data/app/datatables/admin/effective_event_tickets_datatable.rb +1 -1
  9. data/app/datatables/effective_event_purchases_datatable.rb +38 -0
  10. data/app/datatables/effective_event_registrations_datatable.rb +1 -3
  11. data/app/helpers/effective_events_helper.rb +12 -1
  12. data/app/models/concerns/effective_events_event_registration.rb +21 -103
  13. data/app/models/effective/event.rb +8 -2
  14. data/app/models/effective/event_product.rb +53 -0
  15. data/app/models/effective/event_purchase.rb +71 -0
  16. data/app/models/effective/event_registrant.rb +1 -0
  17. data/app/models/effective/event_ticket.rb +1 -1
  18. data/app/views/admin/event_products/_form.html.haml +9 -0
  19. data/app/views/admin/event_purchases/_form.html.haml +14 -0
  20. data/app/views/admin/event_tickets/_form.html.haml +5 -1
  21. data/app/views/admin/events/_form.html.haml +21 -5
  22. data/app/views/effective/event_purchases/_fields.html.haml +10 -0
  23. data/app/views/effective/event_registrations/_purchases.html.haml +10 -0
  24. data/app/views/effective/event_registrations/purchases.html.haml +14 -0
  25. data/config/routes.rb +2 -0
  26. data/db/migrate/01_create_effective_events.rb.erb +35 -0
  27. data/lib/effective_events/version.rb +1 -1
  28. data/lib/generators/effective_events/install_generator.rb +1 -1
  29. metadata +14 -3
  30. 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: 23e52aa324b4d84c7b5f77010de031f30210f244daf286bc036d23bac01c75a9
4
- data.tar.gz: f8f80c273f26ff8a1b0e2a4ebfc5ea10575f279b3894ebe544a571542069e378
3
+ metadata.gz: 46897bd3260153bd17103b73716d32aca3b46d77335c9c8ac80b033ac881041b
4
+ data.tar.gz: 7da214c575b80246b79edc8c8c0467352e7629dea228a809db80a4c8fc53f14a
5
5
  SHA512:
6
- metadata.gz: 8281c1104c199078ad1b2481b56a870213900e5626771058c17ee72e0bc6232a4e5900e813a3ac9c8ca3ff4937e91e4c0062919fb12ba5b9686ff04aefa09eeb
7
- data.tar.gz: 1ec398208f84946302d74165cbc6a114957465d015bf483e82a798bd9d45a32dd9b6544223c6467aaccb2870d27f98ef553fae5cc0732b23be12ecbd6e3280c9
6
+ metadata.gz: cd8c3c426638f64c649408ea2da9ce57a5965c33c33aafde8255327b8c2eecf01ff0e8077b73d772575045e38e86f4648cdf79661f0b44d2d083e3ebab92a3e8
7
+ data.tar.gz: 4331ea43140b17dce1a0c0850688cf7b57627df10dbefde960d64fdf7cba63d63f3a285f79141a4c73a23f0941dc3f94632f5e1445201fbf0a97eac24c7c26f7
@@ -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
@@ -0,0 +1,11 @@
1
+ module Admin
2
+ class EventPurchasesController < 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
+
10
+ end
11
+ end
@@ -6,7 +6,7 @@ module Effective
6
6
 
7
7
  resource_scope -> {
8
8
  event = Effective::Event.find(params[:event_id])
9
- EffectiveEvents.EventRegistration.deep.where(owner: current_owner, event: event)
9
+ EffectiveEvents.EventRegistration.deep.where(owner: current_user, event: event)
10
10
  }
11
11
 
12
12
  # Allow only 1 in-progress event registration at a time
@@ -37,16 +37,10 @@ module Effective
37
37
 
38
38
  private
39
39
 
40
- def current_owner
41
- (current_user.class.respond_to?(:effective_memberships_owner?) ? current_user.effective_memberships_owners : current_user)
42
- end
43
-
44
40
  def permitted_params
45
41
  model = (params.key?(:effective_event_registration) ? :effective_event_registration : :event_registration)
46
42
 
47
- params.require(model).permit!.except(
48
- :status, :status_steps, :wizard_steps, :submitted_at
49
- )
43
+ params.require(model).permit!.except(:status, :status_steps, :wizard_steps, :submitted_at)
50
44
  end
51
45
 
52
46
  end
@@ -0,0 +1,41 @@
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 :capacity
16
+ col :purchased_event_purchases_count, label: 'Purchased'
17
+
18
+ col :purchased_event_purchases, label: 'Purchased by' do |product|
19
+ product.purchased_event_purchases.sort_by(&:to_s).map do |purchase|
20
+ content_tag(:div, purchase.owner.to_s, class: 'col-resource_item')
21
+ end.join.html_safe
22
+ end
23
+
24
+ actions_col
25
+ end
26
+
27
+ collection do
28
+ scope = Effective::EventProduct.deep.all
29
+
30
+ if attributes[:event_id]
31
+ scope = scope.where(event: event)
32
+ end
33
+
34
+ scope
35
+ end
36
+
37
+ def event
38
+ Effective::Event.find(attributes[:event_id])
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ module Admin
2
+ class EffectiveEventPurchasesDatatable < 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::EventPurchase.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
@@ -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_purchases, search: :string
16
17
  col :orders, label: 'Order'
17
18
 
18
19
  actions_col
@@ -13,7 +13,7 @@ module Admin
13
13
  col :regular_price, as: :price
14
14
  col :early_bird_price, as: :price
15
15
 
16
- col :capacity
16
+ #col :capacity
17
17
  col :purchased_event_registrants_count, label: 'Registered'
18
18
 
19
19
  col :purchased_event_registrants, label: 'Registrants' do |ticket|
@@ -0,0 +1,38 @@
1
+ # Used on the Event Registrations purchases step
2
+
3
+ class EffectiveEventPurchasesDatatable < Effective::Datatable
4
+ datatable do
5
+
6
+ col :event_product, search: :string
7
+ col :price, as: :price
8
+ col :notes
9
+ # no actions_col
10
+ end
11
+
12
+ collection do
13
+ scope = Effective::EventPurchase.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
@@ -30,9 +30,7 @@ class EffectiveEventRegistrationsDatatable < Effective::Datatable
30
30
  end
31
31
 
32
32
  collection do
33
- owner = (current_user.respond_to?(:effective_memberships_owners) ? current_user.effective_memberships_owners : current_user)
34
-
35
- EffectiveEvents.EventRegistration.deep.where(owner: owner)
33
+ EffectiveEvents.EventRegistration.deep.where(owner: current_user)
36
34
  end
37
35
 
38
36
  end
@@ -5,12 +5,23 @@ module EffectiveEventsHelper
5
5
 
6
6
  event.event_tickets.map do |ticket|
7
7
  label = ticket.to_s
8
- price = (ticket.price == 0 ? '$0' : number_to_currency(ticket.price))
8
+ price = (ticket.price == 0 ? '$0' : price_to_currency(ticket.price))
9
9
 
10
10
  ["#{label} - #{price}", ticket.to_param]
11
11
  end
12
12
  end
13
13
 
14
+ def effective_events_event_products_collection(event)
15
+ raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
16
+
17
+ event.event_products.map do |product|
18
+ label = product.to_s
19
+ price = (product.price == 0 ? '$0' : price_to_currency(product.price))
20
+
21
+ ["#{label} - #{price}", product.to_param]
22
+ end
23
+ end
24
+
14
25
  def edit_effective_event_registrations_wizard?
15
26
  params[:controller] == 'effective/event_registrations' && defined?(resource) && resource.draft?
16
27
  end
@@ -37,12 +37,15 @@ module EffectiveEventsEventRegistration
37
37
  acts_as_wizard(
38
38
  start: 'Start',
39
39
  registrants: 'Registrants',
40
+ purchases: 'Purchases',
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_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
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
 
@@ -78,10 +84,7 @@ module EffectiveEventsEventRegistration
78
84
  scope :in_progress, -> { where.not(status: [:submitted]) }
79
85
  scope :done, -> { where(status: [:submitted]) }
80
86
 
81
- scope :for, -> (user) {
82
- owner = (user.respond_to?(:effective_memberships_owners) ? user.effective_memberships_owners : user)
83
- where(owner: owner)
84
- }
87
+ scope :for, -> (user) { where(owner: user) }
85
88
 
86
89
  # All Steps validations
87
90
  validates :owner, presence: true
@@ -92,17 +95,16 @@ module EffectiveEventsEventRegistration
92
95
  self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
93
96
  end
94
97
 
95
- # Billing Step
96
- validate(if: -> { current_step == :billing && owner.present? }) do
97
- self.errors.add(:base, "must have a billing address") unless owner.billing_address.present?
98
- self.errors.add(:base, "must have an email") unless owner.email.present?
98
+ def required_steps
99
+ 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])
99
101
  end
100
102
 
101
- after_purchase do |_|
102
- raise('expected submit_order to be purchased') unless submit_order&.purchased?
103
- submit_purchased!
104
- after_submit_purchased!
103
+ # All Fees and Orders
104
+ def submit_fees
105
+ (event_registrants + event_purchases)
105
106
  end
107
+
106
108
  end
107
109
 
108
110
  # Instance Methods
@@ -118,10 +120,6 @@ module EffectiveEventsEventRegistration
118
120
  submitted?
119
121
  end
120
122
 
121
- def can_visit_step?(step)
122
- can_revisit_completed_steps(step)
123
- end
124
-
125
123
  # Find or build
126
124
  def event_registrant(first_name:, last_name:, email:)
127
125
  registrant = event_registrants.find { |er| er.first_name == first_name && er.last_name == last_name && er.email == email }
@@ -132,96 +130,16 @@ module EffectiveEventsEventRegistration
132
130
  def build_event_registrants
133
131
  if event_registrants.blank?
134
132
  raise('expected owner and event to be present') unless owner && event
135
- event_registrants.build(first_name: owner.first_name, last_name: owner.last_name, email: owner.email)
133
+ event_registrants.build(
134
+ first_name: owner.try(:first_name),
135
+ last_name: owner.try(:last_name),
136
+ email: owner.try(:email)
137
+ )
136
138
  end
137
139
 
138
140
  event_registrants
139
141
  end
140
142
 
141
- # All Fees and Orders
142
- def submit_fees
143
- event_registrants
144
- end
145
-
146
- def submit_order
147
- orders.first
148
- end
149
-
150
- def find_or_build_submit_order
151
- order = submit_order || orders.build(user: owner)
152
- fees = submit_fees()
153
-
154
- # Adds fees, but does not overwrite any existing price.
155
- fees.each do |fee|
156
- order.add(fee) unless order.purchasables.include?(fee)
157
- end
158
-
159
- order.purchasables.each do |purchasable|
160
- order.remove(purchasable) unless fees.include?(purchasable)
161
- end
162
-
163
- # From Billing Step
164
- order.billing_address = owner.billing_address if owner.billing_address.present?
165
-
166
- # Important to add/remove anything
167
- order.save
168
-
169
- order
170
- end
171
-
172
- # Should be indempotent.
173
- def build_submit_fees_and_order
174
- return false if was_submitted?
175
-
176
- fees = submit_fees()
177
- raise('already has purchased submit fees') if fees.any?(&:purchased?)
178
-
179
- order = find_or_build_submit_order()
180
- raise('already has purchased submit order') if order.purchased?
181
-
182
- true
183
- end
184
-
185
- # If they go back and change registrants. Update the order right away.
186
- def registrants!
187
- save!
188
- build_submit_fees_and_order if submit_order.present?
189
- true
190
- end
191
-
192
- # Owner clicks on the Billing step. Next step is Checkout
193
- def billing!
194
- ready!
195
- end
196
-
197
- # Ready to check out
198
- def ready!
199
- build_submit_fees_and_order
200
- save!
201
- end
202
-
203
- # Called automatically via after_purchase hook above
204
- def submit_purchased!
205
- return false if was_submitted?
206
-
207
- wizard_steps[:checkout] = Time.zone.now
208
- submit!
209
- end
210
-
211
- # A hook to extend
212
- def after_submit_purchased!
213
- end
214
-
215
- # Draft -> Submitted requirements
216
- def submit!
217
- raise('already submitted') if was_submitted?
218
- raise('expected a purchased order') unless submit_order&.purchased?
219
-
220
- wizard_steps[:checkout] ||= Time.zone.now
221
- wizard_steps[:submitted] = Time.zone.now
222
- submitted!
223
- end
224
-
225
143
  private
226
144
 
227
145
  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_purchases, -> { order(:event_product_id, :created_at) }, inverse_of: :event
15
+ accepts_nested_attributes_for :event_purchases, allow_destroy: true
10
16
 
11
17
  # rich_text_body - Used by the select step
12
18
  has_many_rich_texts
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Effective
4
+ class EventProduct < ActiveRecord::Base
5
+ belongs_to :event
6
+
7
+ has_many :event_purchases
8
+ has_many :purchased_event_purchases, -> { EventPurchase.purchased }, class_name: 'Effective::EventPurchase'
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
+
26
+ timestamps
27
+ end
28
+
29
+ scope :sorted, -> { order(:position) }
30
+ scope :deep, -> { with_rich_text_body.includes(:purchased_event_purchases) }
31
+
32
+ before_validation(if: -> { event.present? }) do
33
+ self.position ||= (event.event_products.map(&:position).compact.max || -1) + 1
34
+ end
35
+
36
+ validates :title, presence: true, uniqueness: { scope: [:event_id] }
37
+ validates :price, presence: true
38
+
39
+ def to_s
40
+ title.presence || 'New Event Product'
41
+ end
42
+
43
+ def capacity_available?
44
+ return true if capacity.blank?
45
+ capacity <= purchased_event_purchases.count
46
+ end
47
+
48
+ def purchased_event_purchases_count
49
+ purchased_event_purchases.count
50
+ end
51
+
52
+ end
53
+ end
@@ -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 EventPurchases
5
+
6
+ module Effective
7
+ class EventPurchase < 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
@@ -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
@@ -34,7 +34,7 @@ module Effective
34
34
  self.position ||= (event.event_tickets.map(&:position).compact.max || -1) + 1
35
35
  end
36
36
 
37
- validates :title, presence: true
37
+ validates :title, presence: true, uniqueness: { scope: [:event_id] }
38
38
  validates :regular_price, presence: true
39
39
  validates :early_bird_price, presence: true, if: -> { event&.early_bird_end_at.present? }
40
40
 
@@ -0,0 +1,9 @@
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.price_field :price
6
+ = f.text_field :qb_item_name
7
+ = f.check_box :tax_exempt
8
+
9
+ = effective_submit(f)
@@ -0,0 +1,14 @@
1
+ = effective_form_with(model: [:admin, event_purchase], 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_purchases/fields', f: f, event: event_purchase.event
10
+
11
+ - if f.object.new_record?
12
+ = f.submit 'Save and Mark Paid'
13
+ - else
14
+ = f.submit 'Save'
@@ -1,7 +1,11 @@
1
1
  = effective_form_with(model: [:admin, event_ticket], engine: true) do |f|
2
2
  = f.hidden_field :event_id
3
3
 
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
8
+ = f.check_box :tax_exempt
4
9
  /= f.number_field :capacity, hint: 'The number of online purchases will be loosely limited to capacity.'
5
- = render 'effective/event_tickets/fields', f: f
6
10
 
7
11
  = effective_submit(f)
@@ -3,20 +3,36 @@
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
10
  %p An event must have tickets before registration can begin
15
11
 
12
+ %h2 Tickets
16
13
  - datatable = Admin::EffectiveEventTicketsDatatable.new(event_id: event.id)
17
14
  = render_inline_datatable(datatable)
18
15
 
19
- = tab 'Registration' do
16
+ = tab 'Products' do
17
+ %h2 Products
18
+ - datatable = Admin::EffectiveEventProductsDatatable.new(event_id: event.id)
19
+ = render_inline_datatable(datatable)
20
+
21
+ = tab 'Registrations' do
22
+ %h2 Registrations
23
+ - datatable = Admin::EffectiveEventRegistrationsDatatable.new(event_id: event.id)
24
+ .mb-4= render_inline_datatable(datatable)
25
+
26
+ = tab 'Registrants' do
27
+ %h2 Registrants
28
+ - datatable = Admin::EffectiveEventRegistrantsDatatable.new(event_id: event.id)
29
+ .mb-4= render_inline_datatable(datatable)
30
+
31
+ %h2 Purchases
32
+ - datatable = Admin::EffectiveEventPurchasesDatatable.new(event_id: event.id)
33
+ = render_inline_datatable(datatable)
34
+
35
+ = tab 'Wizard' do
20
36
  = render '/admin/events/form_event_registration_content', event: event
21
37
 
22
38
  = tab 'Access' do
@@ -0,0 +1,10 @@
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'
@@ -0,0 +1,10 @@
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)
@@ -0,0 +1,14 @@
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'
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_purchases, except: [:show]
21
23
  resources :event_registrations, only: [:index, :show]
22
24
  end
23
25
 
@@ -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_purchases_count, default: 0
17
18
 
18
19
  t.integer :roles_mask
19
20
  t.boolean :authenticate_user, default: false
@@ -65,6 +66,40 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
65
66
  t.timestamps
66
67
  end
67
68
 
69
+ create_table :event_products do |t|
70
+ t.integer :event_id
71
+
72
+ t.string :title
73
+ t.integer :capacity
74
+
75
+ t.integer :price
76
+
77
+ t.string :qb_item_name
78
+ t.boolean :tax_exempt, default: false
79
+
80
+ t.integer :position
81
+
82
+ t.timestamps
83
+ end
84
+
85
+ create_table :event_purchases do |t|
86
+ t.integer :event_id
87
+ t.integer :event_product_id
88
+
89
+ t.integer :owner_id
90
+ t.string :owner_type
91
+
92
+ t.integer :event_registration_id
93
+ t.string :event_registration_type
94
+
95
+ t.text :notes
96
+
97
+ t.integer :purchased_order_id
98
+ t.integer :price
99
+
100
+ t.timestamps
101
+ end
102
+
68
103
  create_table :event_registrations do |t|
69
104
  t.string :token
70
105
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.1.5'.freeze
3
3
  end
@@ -1,4 +1,4 @@
1
- module EffectiveMemberships
1
+ module EffectiveEvents
2
2
  module Generators
3
3
  class InstallGenerator < Rails::Generators::Base
4
4
  include Rails::Generators::Migration
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.1
4
+ version: 0.1.5
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-05 00:00:00.000000000 Z
11
+ date: 2022-01-12 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_products_controller.rb
183
+ - app/controllers/admin/event_purchases_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_products_datatable.rb
191
+ - app/datatables/admin/effective_event_purchases_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_purchases_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_product.rb
204
+ - app/models/effective/event_purchase.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_products/_form.html.haml
209
+ - app/views/admin/event_purchases/_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,21 +214,23 @@ 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_purchases/_fields.html.haml
208
218
  - app/views/effective/event_registrants/_fields.html.haml
209
219
  - app/views/effective/event_registrations/_content.html.haml
210
220
  - app/views/effective/event_registrations/_dashboard.html.haml
211
221
  - app/views/effective/event_registrations/_event_registration.html.haml
212
222
  - app/views/effective/event_registrations/_layout.html.haml
213
223
  - app/views/effective/event_registrations/_orders.html.haml
224
+ - app/views/effective/event_registrations/_purchases.html.haml
214
225
  - app/views/effective/event_registrations/_registrants.html.haml
215
226
  - app/views/effective/event_registrations/_summary.html.haml
216
227
  - app/views/effective/event_registrations/billing.html.haml
217
228
  - app/views/effective/event_registrations/checkout.html.haml
229
+ - app/views/effective/event_registrations/purchases.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