effective_events 0.1.1 → 0.1.5
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.
- checksums.yaml +4 -4
- 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 +41 -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 +1 -1
- data/app/datatables/effective_event_purchases_datatable.rb +38 -0
- data/app/datatables/effective_event_registrations_datatable.rb +1 -3
- data/app/helpers/effective_events_helper.rb +12 -1
- data/app/models/concerns/effective_events_event_registration.rb +21 -103
- data/app/models/effective/event.rb +8 -2
- data/app/models/effective/event_product.rb +53 -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 +1 -1
- data/app/views/admin/event_products/_form.html.haml +9 -0
- data/app/views/admin/event_purchases/_form.html.haml +14 -0
- data/app/views/admin/event_tickets/_form.html.haml +5 -1
- 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 +10 -0
- data/app/views/effective/event_registrations/purchases.html.haml +14 -0
- data/config/routes.rb +2 -0
- data/db/migrate/01_create_effective_events.rb.erb +35 -0
- data/lib/effective_events/version.rb +1 -1
- data/lib/generators/effective_events/install_generator.rb +1 -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: 46897bd3260153bd17103b73716d32aca3b46d77335c9c8ac80b033ac881041b
|
4
|
+
data.tar.gz: 7da214c575b80246b79edc8c8c0467352e7629dea228a809db80a4c8fc53f14a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd8c3c426638f64c649408ea2da9ce57a5965c33c33aafde8255327b8c2eecf01ff0e8077b73d772575045e38e86f4648cdf79661f0b44d2d083e3ebab92a3e8
|
7
|
+
data.tar.gz: 4331ea43140b17dce1a0c0850688cf7b57627df10dbefde960d64fdf7cba63d63f3a285f79141a4c73a23f0941dc3f94632f5e1445201fbf0a97eac24c7c26f7
|
@@ -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,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
|
@@ -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
|
-
|
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' :
|
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
|
-
|
96
|
-
|
97
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
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(
|
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 :
|
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,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
|
@@ -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,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 '
|
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
|
|
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.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-
|
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
|