effective_events 0.1.3 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -2
- data/app/controllers/admin/event_products_controller.rb +8 -0
- data/app/controllers/admin/event_purchases_controller.rb +11 -0
- data/app/controllers/effective/event_registrations_controller.rb +2 -8
- data/app/datatables/admin/effective_event_products_datatable.rb +50 -0
- data/app/datatables/admin/effective_event_purchases_datatable.rb +41 -0
- data/app/datatables/admin/effective_event_registrations_datatable.rb +2 -1
- data/app/datatables/admin/effective_event_tickets_datatable.rb +10 -1
- data/app/datatables/admin/effective_events_datatable.rb +7 -6
- data/app/datatables/effective_event_purchases_datatable.rb +38 -0
- data/app/datatables/effective_event_registrations_datatable.rb +3 -4
- data/app/helpers/effective_events_helper.rb +22 -3
- data/app/models/concerns/effective_events_event_registration.rb +37 -104
- data/app/models/effective/event.rb +8 -2
- data/app/models/effective/event_product.rb +67 -0
- data/app/models/effective/event_purchase.rb +71 -0
- data/app/models/effective/event_registrant.rb +1 -0
- data/app/models/effective/event_ticket.rb +18 -4
- data/app/views/admin/event_products/_form.html.haml +12 -0
- data/app/views/admin/event_purchases/_form.html.haml +14 -0
- data/app/views/admin/event_tickets/_form.html.haml +9 -2
- data/app/views/admin/events/_form.html.haml +21 -5
- data/app/views/effective/event_purchases/_fields.html.haml +10 -0
- data/app/views/effective/event_registrations/_purchases.html.haml +9 -0
- data/app/views/effective/event_registrations/_registrants.html.haml +8 -9
- data/app/views/effective/event_registrations/_summary.html.haml +22 -25
- data/app/views/effective/event_registrations/billing.html.haml +8 -7
- data/app/views/effective/event_registrations/purchases.html.haml +14 -0
- data/config/effective_events.rb +2 -0
- data/config/routes.rb +2 -0
- data/db/migrate/01_create_effective_events.rb.erb +46 -9
- data/lib/effective_events/version.rb +1 -1
- data/lib/effective_events.rb +2 -1
- data/lib/generators/effective_events/install_generator.rb +6 -1
- metadata +14 -3
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19f4a303dbab49f23b15a28c71bce29f9d55036371c533a27f36ad3ac70ca1b4
|
4
|
+
data.tar.gz: ad51623c2087ccf9a1c2a2a97d1623f89224be38cd7aae06b246aedb2108e2e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d51690029093356830ee881f54881054b4eafa9b0aaf99d2389c9d8966a2d76b2d8456f11e9ef45ef7df92cddce73c89961094802c21a198a766b04373b0eb8
|
7
|
+
data.tar.gz: 68e1785f75da39ad9916a065c89dc79a3995602c250315276e165b58f4abf43bc4ab116c45698e1ee36cccfa7b7fe2c364efefab73d382deb58bd623e8064325
|
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
|
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::EventPurchase) { |purchase| purchase.owner == user || purchase.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 :
|
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::EventPurchase)
|
89
|
+
can(:mark_paid, Effective::EventPurchase) { |er| !er.event_registration_id.present? }
|
90
|
+
can(:destroy, Effective::EventPurchase) { |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_purchases_count == 0 }
|
97
|
+
|
98
|
+
can([:index, :show], EffectiveEvents.EventRegistration)
|
75
99
|
end
|
76
100
|
```
|
77
101
|
|
@@ -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:
|
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,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_purchases_count, label: 'Purchased'
|
24
|
+
col :capacity, visible: false
|
25
|
+
col :capacity_available, visible: false
|
26
|
+
|
27
|
+
col :purchased_event_purchases, label: 'Purchased by' do |product|
|
28
|
+
product.purchased_event_purchases.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
|
@@ -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,8 +13,17 @@ module Admin
|
|
13
13
|
col :regular_price, as: :price
|
14
14
|
col :early_bird_price, as: :price
|
15
15
|
|
16
|
-
col :
|
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_purchases, 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 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
|
@@ -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_purchases, label: 'Purchases', search: :string
|
20
21
|
col :orders, action: :show, visible: false, search: :string
|
21
22
|
|
22
23
|
actions_col(actions: []) do |er|
|
@@ -30,9 +31,7 @@ class EffectiveEventRegistrationsDatatable < Effective::Datatable
|
|
30
31
|
end
|
31
32
|
|
32
33
|
collection do
|
33
|
-
|
34
|
-
|
35
|
-
EffectiveEvents.EventRegistration.deep.where(owner: owner)
|
34
|
+
EffectiveEvents.EventRegistration.deep.where(owner: current_user)
|
36
35
|
end
|
37
36
|
|
38
37
|
end
|
@@ -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
|
-
|
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
|
-
|
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
|
+
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,29 @@ module EffectiveEventsEventRegistration
|
|
92
95
|
self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
|
93
96
|
end
|
94
97
|
|
95
|
-
#
|
96
|
-
validate(
|
97
|
-
|
98
|
-
|
98
|
+
# Validate all items are available
|
99
|
+
validate(unless: -> { current_step == :checkout || done? }) do
|
100
|
+
event_registrants.reject { |er| er.purchased? || er.event_ticket&.available? }.each do |item|
|
101
|
+
errors.add(:base, "The #{item.event_ticket} ticket is sold out and no longer available for purchase")
|
102
|
+
item.errors.add(:event_ticket_id, "#{item.event_ticket} is unavailable for purchase")
|
103
|
+
end
|
104
|
+
|
105
|
+
event_purchases.reject { |ep| ep.purchased? || ep.event_product&.available? }.each do |item|
|
106
|
+
errors.add(:base, "The #{item.event_product} product is sold out and no longer available for purchase")
|
107
|
+
item.errors.add(:event_product_id, "#{item.event_product} is unavailable for purchase")
|
108
|
+
end
|
99
109
|
end
|
100
110
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
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 - [:purchases])
|
105
114
|
end
|
115
|
+
|
116
|
+
# All Fees and Orders
|
117
|
+
def submit_fees
|
118
|
+
(event_registrants + event_purchases)
|
119
|
+
end
|
120
|
+
|
106
121
|
end
|
107
122
|
|
108
123
|
# Instance Methods
|
@@ -118,14 +133,16 @@ module EffectiveEventsEventRegistration
|
|
118
133
|
submitted?
|
119
134
|
end
|
120
135
|
|
121
|
-
|
122
|
-
|
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)
|
123
140
|
end
|
124
141
|
|
125
|
-
# Find or build
|
126
|
-
def
|
127
|
-
|
128
|
-
|
142
|
+
# Find or build. But it's not gonna work with more than 1. This is for testing only really.
|
143
|
+
def event_purchase(event_product:)
|
144
|
+
purchase = event_purchases.find { |ep| ep.event_product == event_product }
|
145
|
+
purchase || event_purchases.build(event_product: event_product, owner: owner)
|
129
146
|
end
|
130
147
|
|
131
148
|
# This builds the default event registrants used by the wizard form
|
@@ -142,90 +159,6 @@ module EffectiveEventsEventRegistration
|
|
142
159
|
event_registrants
|
143
160
|
end
|
144
161
|
|
145
|
-
# All Fees and Orders
|
146
|
-
def submit_fees
|
147
|
-
event_registrants
|
148
|
-
end
|
149
|
-
|
150
|
-
def submit_order
|
151
|
-
orders.first
|
152
|
-
end
|
153
|
-
|
154
|
-
def find_or_build_submit_order
|
155
|
-
order = submit_order || orders.build(user: owner)
|
156
|
-
fees = submit_fees()
|
157
|
-
|
158
|
-
# Adds fees, but does not overwrite any existing price.
|
159
|
-
fees.each do |fee|
|
160
|
-
order.add(fee) unless order.purchasables.include?(fee)
|
161
|
-
end
|
162
|
-
|
163
|
-
order.purchasables.each do |purchasable|
|
164
|
-
order.remove(purchasable) unless fees.include?(purchasable)
|
165
|
-
end
|
166
|
-
|
167
|
-
# From Billing Step
|
168
|
-
order.billing_address = owner.billing_address if owner.billing_address.present?
|
169
|
-
|
170
|
-
# Important to add/remove anything
|
171
|
-
order.save
|
172
|
-
|
173
|
-
order
|
174
|
-
end
|
175
|
-
|
176
|
-
# Should be indempotent.
|
177
|
-
def build_submit_fees_and_order
|
178
|
-
return false if was_submitted?
|
179
|
-
|
180
|
-
fees = submit_fees()
|
181
|
-
raise('already has purchased submit fees') if fees.any?(&:purchased?)
|
182
|
-
|
183
|
-
order = find_or_build_submit_order()
|
184
|
-
raise('already has purchased submit order') if order.purchased?
|
185
|
-
|
186
|
-
true
|
187
|
-
end
|
188
|
-
|
189
|
-
# If they go back and change registrants. Update the order right away.
|
190
|
-
def registrants!
|
191
|
-
save!
|
192
|
-
build_submit_fees_and_order if submit_order.present?
|
193
|
-
true
|
194
|
-
end
|
195
|
-
|
196
|
-
# Owner clicks on the Billing step. Next step is Checkout
|
197
|
-
def billing!
|
198
|
-
ready!
|
199
|
-
end
|
200
|
-
|
201
|
-
# Ready to check out
|
202
|
-
def ready!
|
203
|
-
build_submit_fees_and_order
|
204
|
-
save!
|
205
|
-
end
|
206
|
-
|
207
|
-
# Called automatically via after_purchase hook above
|
208
|
-
def submit_purchased!
|
209
|
-
return false if was_submitted?
|
210
|
-
|
211
|
-
wizard_steps[:checkout] = Time.zone.now
|
212
|
-
submit!
|
213
|
-
end
|
214
|
-
|
215
|
-
# A hook to extend
|
216
|
-
def after_submit_purchased!
|
217
|
-
end
|
218
|
-
|
219
|
-
# Draft -> Submitted requirements
|
220
|
-
def submit!
|
221
|
-
raise('already submitted') if was_submitted?
|
222
|
-
raise('expected a purchased order') unless submit_order&.purchased?
|
223
|
-
|
224
|
-
wizard_steps[:checkout] ||= Time.zone.now
|
225
|
-
wizard_steps[:submitted] = Time.zone.now
|
226
|
-
submitted!
|
227
|
-
end
|
228
|
-
|
229
162
|
private
|
230
163
|
|
231
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 :
|
9
|
-
accepts_nested_attributes_for :
|
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,67 @@
|
|
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
|
+
archived :boolean
|
26
|
+
|
27
|
+
timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
scope :sorted, -> { order(:position) }
|
31
|
+
scope :deep, -> { with_rich_text_body.includes(:purchased_event_purchases) }
|
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_purchases_count), 0].max
|
60
|
+
end
|
61
|
+
|
62
|
+
def purchased_event_purchases_count
|
63
|
+
purchased_event_purchases.length
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
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
|
@@ -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
|
-
|
51
|
-
|
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.
|
69
|
+
purchased_event_registrants.length
|
56
70
|
end
|
57
71
|
|
58
72
|
end
|
@@ -0,0 +1,12 @@
|
|
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 online purchases will be limited to capacity.'
|
6
|
+
= f.check_box :archived, label: 'Yes, archive this product and make it unavailable for purchase'
|
7
|
+
|
8
|
+
= f.price_field :price
|
9
|
+
= f.text_field :qb_item_name, label: 'Quickbooks item name'
|
10
|
+
= f.check_box :tax_exempt
|
11
|
+
|
12
|
+
= 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,14 @@
|
|
1
1
|
= effective_form_with(model: [:admin, event_ticket], engine: true) do |f|
|
2
2
|
= f.hidden_field :event_id
|
3
3
|
|
4
|
-
|
5
|
-
=
|
4
|
+
= f.text_field :title
|
5
|
+
= f.number_field :capacity, hint: 'The number of online purchases will be limited to capacity.'
|
6
|
+
= f.check_box :archived, label: 'Yes, archive this ticket and make it unavailable for purchase'
|
7
|
+
|
8
|
+
= f.price_field :regular_price
|
9
|
+
= f.price_field :early_bird_price
|
10
|
+
= f.text_field :qb_item_name, label: 'Quickbooks item name'
|
11
|
+
= f.check_box :tax_exempt
|
12
|
+
|
6
13
|
|
7
14
|
= 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 '
|
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,9 @@
|
|
1
|
+
= card do
|
2
|
+
.row
|
3
|
+
.col-sm
|
4
|
+
%h5.card-title= event_registration.wizard_step_title(:purchases)
|
5
|
+
.col-sm-auto.text-right
|
6
|
+
= link_to('Edit', wizard_path(:purchases)) if edit_effective_event_registrations_wizard?
|
7
|
+
|
8
|
+
- datatable = EffectiveEventPurchasesDatatable.new(event_registration: event_registration)
|
9
|
+
.mb-4= render_simple_datatable(datatable)
|
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
.
|
3
|
-
.
|
4
|
-
.
|
5
|
-
|
6
|
-
|
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
|
-
|
10
|
-
|
8
|
+
- datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
|
9
|
+
.mb-4= render_simple_datatable(datatable)
|
@@ -1,29 +1,26 @@
|
|
1
|
-
|
2
|
-
.
|
3
|
-
%
|
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
|
-
|
6
|
-
%tbody
|
9
|
+
- if request.path.start_with?('/admin')
|
7
10
|
%tr
|
8
|
-
%th
|
9
|
-
%td
|
10
|
-
=
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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))
|
@@ -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
|
-
|
7
|
-
|
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
|
-
|
12
|
-
|
9
|
+
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
10
|
+
= f.hidden_field :id
|
13
11
|
|
14
|
-
|
12
|
+
= f.fields_for(:owner, f.object.owner) do |fu|
|
13
|
+
= effective_address_fields(fu, :billing)
|
14
|
+
|
15
|
+
= f.save 'Save and Continue'
|
@@ -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/effective_events.rb
CHANGED
@@ -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_purchases_table_name = :event_purchases
|
5
7
|
config.event_registrations_table_name = :event_registrations
|
6
8
|
|
7
9
|
# Layout Settings
|
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
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
|
2
2
|
def change
|
3
|
-
create_table
|
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_purchases_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
|
25
|
-
add_index
|
25
|
+
add_index <%= @events_table_name %>, :title
|
26
|
+
add_index <%= @events_table_name %>, :end_at
|
26
27
|
|
27
|
-
create_table
|
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
|
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
|
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_purchases_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
|
94
|
-
add_index
|
95
|
-
add_index
|
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
|
data/lib/effective_events.rb
CHANGED
@@ -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,
|
9
|
+
:events_table_name, :event_registrants_table_name, :event_tickets_table_name,
|
10
|
+
:event_registrations_table_name, :event_products_table_name, :event_purchases_table_name,
|
10
11
|
:layout, :per_page, :use_effective_roles,
|
11
12
|
:event_registration_class_name
|
12
13
|
]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module EffectiveEvents
|
2
2
|
module Generators
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
4
4
|
include Rails::Generators::Migration
|
@@ -21,6 +21,11 @@ module EffectiveMemberships
|
|
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_purchases_table_name = ':' + EffectiveEvents.event_purchases_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
|
+
version: 0.1.7
|
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-
|
11
|
+
date: 2022-01-13 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
|