effective_events 0.18.2 → 0.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/datatables/admin/effective_event_registrants_datatable.rb +7 -2
- data/app/helpers/effective_events_helper.rb +2 -2
- data/app/models/concerns/effective_events_event_registration.rb +5 -1
- data/app/models/effective/event_registrant.rb +20 -8
- data/app/views/admin/event_tickets/_form.html.haml +15 -6
- data/app/views/admin/events/_form_event.html.haml +3 -14
- data/app/views/effective/event_registrants/_fields_member_or_non_member.html.haml +22 -12
- data/app/views/effective/event_registrants/_fields_questions.html.haml +6 -9
- data/app/views/effective/event_registrations/_event_tickets.html.haml +57 -37
- data/app/views/effective/event_registrations/_form_blank_registrants.html.haml +2 -4
- data/db/migrate/101_create_effective_events.rb +1 -0
- data/lib/effective_events/version.rb +1 -1
- data/lib/effective_events.rb +7 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5b3feac5b9f393375a9e93df6bed8aaa3db611ced3dcb8dfa9a2a585ec6cfb5
|
4
|
+
data.tar.gz: 7e071a9e0906b0fef5856be8d89b9de74dd201506d8ef740ed8df5b4f92a8d5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b251b9c7e3334462eb15e80cc208b78ec2173437ad31462e906da59ab027d4140179b6cbf525c5abd4c48be53e3843182a2c4b50f1b5c22acf4876becd600c3
|
7
|
+
data.tar.gz: 880ce99932a1e32bf8a6f3953aed66b4b98b0ae8af33af19d81e0a927d2cc9f676d39450db8e96f9f47c6f2f5b262e90e967faee49f463f511409d62be0336ad
|
@@ -42,8 +42,12 @@ module Admin
|
|
42
42
|
col :promoted, visible: false
|
43
43
|
|
44
44
|
col :name do |er|
|
45
|
-
if er.
|
45
|
+
if er.user.present?
|
46
|
+
"#{link_to(er.user, "/admin/users/#{er.user.id}/edit", target: '_blank')}<br><small>#{mail_to(er.user.email)}</small>"
|
47
|
+
elsif er.first_name.present? && er.email.present?
|
46
48
|
"#{er.first_name} #{er.last_name}<br><small>#{mail_to(er.email)}</small>"
|
49
|
+
elsif er.first_name.present?
|
50
|
+
"#{er.first_name} #{er.last_name}"
|
47
51
|
elsif er.owner.present?
|
48
52
|
er.owner.to_s + ' - GUEST'
|
49
53
|
else
|
@@ -51,7 +55,8 @@ module Admin
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
col :user, label: 'Member'
|
58
|
+
col :user, label: 'Member', visible: false
|
59
|
+
col :member_or_non_member_choice, visible: false
|
55
60
|
|
56
61
|
col :orders, visible: false
|
57
62
|
col :price, as: :price
|
@@ -34,7 +34,7 @@ module EffectiveEventsHelper
|
|
34
34
|
].compact.sort.uniq
|
35
35
|
|
36
36
|
if prices.length > 1
|
37
|
-
"#{(prices.first == 0 ? '$0' : price_to_currency(prices.first))}
|
37
|
+
"#{(prices.first == 0 ? '$0' : price_to_currency(prices.first))} or #{(prices.last == 0 ? '$0' : price_to_currency(prices.last))}"
|
38
38
|
else
|
39
39
|
(prices.first == 0 ? '$0' : price_to_currency(prices.first))
|
40
40
|
end
|
@@ -97,7 +97,7 @@ module EffectiveEventsHelper
|
|
97
97
|
|
98
98
|
return if url.blank?
|
99
99
|
|
100
|
-
"Can't find the
|
100
|
+
"Can't find the member you need? <a href='#{url}' target='blank'>Click here</a> to add them to your #{EffectiveResources.etd(EffectiveMemberships.Organization)}."
|
101
101
|
end
|
102
102
|
|
103
103
|
end
|
@@ -164,7 +164,7 @@ module EffectiveEventsEventRegistration
|
|
164
164
|
|
165
165
|
def required_steps
|
166
166
|
return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
|
167
|
-
event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:addons])
|
167
|
+
event&.event_products.unarchived.present? ? wizard_step_keys : (wizard_step_keys - [:addons])
|
168
168
|
end
|
169
169
|
|
170
170
|
def find_or_build_submit_fees
|
@@ -344,6 +344,10 @@ module EffectiveEventsEventRegistration
|
|
344
344
|
end
|
345
345
|
|
346
346
|
save!
|
347
|
+
|
348
|
+
update_submit_fees_and_order! if submit_order.present? && !submit_order.purchased?
|
349
|
+
|
350
|
+
true
|
347
351
|
end
|
348
352
|
|
349
353
|
private
|
@@ -4,7 +4,8 @@ module Effective
|
|
4
4
|
class EventRegistrant < ActiveRecord::Base
|
5
5
|
self.table_name = (EffectiveEvents.event_registrants_table_name || :event_registrants).to_s
|
6
6
|
|
7
|
-
PERMITTED_BLANK_REGISTRANT_CHANGES = ["first_name", "last_name", "email", "company", "user_id", "user_type", "blank_registrant", "response1", "response2", "response3"]
|
7
|
+
PERMITTED_BLANK_REGISTRANT_CHANGES = ["first_name", "last_name", "email", "company", "user_id", "user_type", "blank_registrant", "member_or_non_member_choice", "response1", "response2", "response3"]
|
8
|
+
MEMBER_OR_NON_MEMBER_CHOICES = ['Add a regular registration', 'Add a member registration']
|
8
9
|
|
9
10
|
acts_as_purchasable
|
10
11
|
acts_as_archived
|
@@ -31,7 +32,8 @@ module Effective
|
|
31
32
|
email :string
|
32
33
|
company :string
|
33
34
|
|
34
|
-
blank_registrant
|
35
|
+
blank_registrant :boolean
|
36
|
+
member_or_non_member_choice :string # Used by Member or Non-Member tickets to indicate a member or non-member
|
35
37
|
|
36
38
|
waitlisted :boolean
|
37
39
|
promoted :boolean # An admin marked this registrant as promoted from the waitlist
|
@@ -98,12 +100,18 @@ module Effective
|
|
98
100
|
validates :company, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:company) }
|
99
101
|
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
validates :
|
106
|
-
validates :
|
103
|
+
# Member or Non-Member Ticket
|
104
|
+
validates :member_or_non_member_choice, presence: true, if: -> { event_ticket&.member_or_non_member? && present_registrant? }
|
105
|
+
|
106
|
+
with_options(if: -> { event_ticket&.member_or_non_member? && present_registrant? && member_or_non_member_choice == 'Add a regular registration' }) do
|
107
|
+
validates :first_name, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:first_name) }
|
108
|
+
validates :last_name, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:last_name) }
|
109
|
+
validates :email, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:email) }
|
110
|
+
validates :company, presence: true, unless: -> { EffectiveEvents.event_registrant_required_fields.exclude?(:company) }
|
111
|
+
end
|
112
|
+
|
113
|
+
with_options(if: -> { event_ticket&.member_or_non_member? && present_registrant? && member_or_non_member_choice == 'Add a member registration' }) do
|
114
|
+
validates :user_id, presence: { message: 'Please select a member' }
|
107
115
|
end
|
108
116
|
|
109
117
|
after_defer do
|
@@ -140,6 +148,10 @@ module Effective
|
|
140
148
|
user&.is?(:member)
|
141
149
|
end
|
142
150
|
|
151
|
+
def member_or_non_member_choice
|
152
|
+
self[:member_or_non_member_choice] || 'Add a regular registration'
|
153
|
+
end
|
154
|
+
|
143
155
|
def member_email
|
144
156
|
email.presence || user&.email
|
145
157
|
end
|
@@ -27,18 +27,26 @@
|
|
27
27
|
= f.number_field :capacity, hint: "The number of registrations will be limited to capacity. Leave blank for unlimited capacity."
|
28
28
|
= f.check_box :display_capacity, label: "Yes, display the remaining ticket capacity to users during registration", hint: "Leave blank to hide the capacity."
|
29
29
|
|
30
|
-
- if
|
30
|
+
- if EffectiveEvents.delayed?
|
31
|
+
- event_delayed = f.object.event&.delayed?
|
32
|
+
- f.object.waitlist = false if !event_delayed
|
33
|
+
|
31
34
|
= f.check_box :waitlist,
|
32
35
|
label: "Yes, add to waitlist once capacity is reached",
|
33
|
-
hint: "requires a delayed payment
|
36
|
+
hint: "requires a event with delayed payment. Once capacity is reached, new registrations will be added to the waitlist. Payment information is collected but not charged for waitlisted registrants. To waitlist everyone and promote later, set the capacity to zero.",
|
37
|
+
disabled: !event_delayed
|
34
38
|
.row
|
35
39
|
.col-md-6
|
36
|
-
|
37
|
-
|
40
|
+
= f.price_field :early_bird_price,
|
41
|
+
hint: 'requires an event with early bird date. A price of $0 will allow a checkout for free. Leave blank for no early bird price.',
|
42
|
+
disabled: !f.object.event&.early_bird_end_at.present?
|
38
43
|
|
39
44
|
= f.show_if_any(:category, ['Regular', 'Member or Non-Member']) do
|
40
45
|
= f.price_field :regular_price, hint: 'A price of $0 will allow a checkout for free.'
|
41
46
|
|
47
|
+
= f.show_if_any(:category, ['Member Only']) do
|
48
|
+
= f.static_field :regular_price, value: 'None'
|
49
|
+
|
42
50
|
= f.show_if_any(:category, ['Member Only', 'Member or Non-Member']) do
|
43
51
|
= f.price_field :member_price, hint: 'A price of $0 will allow a checkout for free when selecting a member.'
|
44
52
|
|
@@ -47,10 +55,11 @@
|
|
47
55
|
.col-md-6= f.text_field :qb_item_name, label: 'QuickBooks item name'
|
48
56
|
|
49
57
|
= f.check_box :tax_exempt
|
50
|
-
= f.check_box :archived, label: 'Archive this ticket.
|
58
|
+
= f.check_box :archived, label: 'Archive this ticket. While archived, it cannot be purchased by users but registrants can only be added by an admin.'
|
51
59
|
|
52
60
|
= card('Questions') do
|
53
|
-
%p
|
61
|
+
%p
|
62
|
+
%small.text-muted Please add up to 3 questions to ask during registration. Each ticket will have their own unique answers. Leave a question blank to skip.
|
54
63
|
|
55
64
|
= f.text_field :question1, label: 'Question 1'
|
56
65
|
= f.text_field :question2, label: 'Question 2'
|
@@ -1,19 +1,8 @@
|
|
1
1
|
= effective_form_with(model: [:admin, event], engine: true) do |f|
|
2
2
|
= f.text_field :title, label: "Title"
|
3
3
|
|
4
|
-
|
5
|
-
= f.
|
6
|
-
.row
|
7
|
-
.col-md-6
|
8
|
-
= f.datetime_field :published_start_at, hint: 'The event will be available starting on this date and time. Leave blank to publish immediately.'
|
9
|
-
.col-md-6
|
10
|
-
= f.datetime_field :published_end_at, label: 'Published start', hint: 'The event will not appear on the website after this date and time. Leave blank for no end date.', date_linked: false
|
11
|
-
|
12
|
-
= f.check_box :save_as_draft, label: "Save as a draft. It will not appear on the website and can only be accessed by admin users."
|
13
|
-
|
14
|
-
- if f.object.persisted? || f.object.errors.include?(:slug)
|
15
|
-
- current_url = (effective_events.event_url(f.object) rescue nil)
|
16
|
-
= f.text_field :slug, hint: "The slug controls this event's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This event is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url }".html_safe
|
4
|
+
= acts_as_published_fields(f)
|
5
|
+
= acts_as_slugged_fields(f, url: (effective_events.event_url(f.object) rescue nil))
|
17
6
|
|
18
7
|
.row
|
19
8
|
.col
|
@@ -47,7 +36,7 @@
|
|
47
36
|
= f.url_field :external_registration_url, hint: "The url for external event registration. Must start with http(s)://"
|
48
37
|
|
49
38
|
.col-md-6
|
50
|
-
- if
|
39
|
+
- if EffectiveEvents.delayed?
|
51
40
|
%h2 Delayed Payments
|
52
41
|
%p The online payment for this event will be charged as follows:
|
53
42
|
|
@@ -1,16 +1,28 @@
|
|
1
|
-
-
|
2
|
-
|
3
|
-
-
|
1
|
+
- if current_user.try(:is_any?, :member, :admin)
|
2
|
+
= f.radios :member_or_non_member_choice, Effective::EventRegistrant::MEMBER_OR_NON_MEMBER_CHOICES, label: false, inline: true
|
3
|
+
- else
|
4
|
+
= f.hidden_field :member_or_non_member_choice, value: 'Add a regular registration'
|
4
5
|
|
5
|
-
= f.
|
6
|
-
= f.
|
6
|
+
= f.show_if(:member_or_non_member_choice, 'Add a member registration', nested: true) do
|
7
|
+
= f.hidden_field :first_name, value: nil
|
8
|
+
= f.hidden_field :last_name, value: nil
|
9
|
+
= f.hidden_field :email, value: nil
|
10
|
+
= f.hidden_field :company, value: nil
|
7
11
|
|
8
|
-
- # Choose
|
9
|
-
|
10
|
-
|
12
|
+
- # Choose ANY member
|
13
|
+
- klass = (f.object.user || current_user).class
|
14
|
+
- ajax_url = (@select2_users_ajax_path || effective_memberships.member_users_membership_select2_ajax_index_path) unless Rails.env.test?
|
11
15
|
|
12
|
-
= f.
|
13
|
-
|
16
|
+
= f.hidden_field :user_type, value: klass.name
|
17
|
+
= f.select :user_id, klass.all, ajax_url: ajax_url, label: 'Member', hint: effective_events_event_registrant_user_hint()
|
18
|
+
|
19
|
+
- # Choose RELATED ORGANIZATION member
|
20
|
+
-# = f.hidden_field :user_type, value: current_user.class.name
|
21
|
+
-# = f.select :user_id, effective_events_event_registrant_user_collection(f.object), hint: effective_events_event_registrant_user_hint()
|
22
|
+
|
23
|
+
= f.show_if(:member_or_non_member_choice, 'Add a regular registration', nested: true) do
|
24
|
+
= f.hidden_field :user_type, value: nil
|
25
|
+
= f.hidden_field :user_id, value: nil
|
14
26
|
|
15
27
|
- # Choose non-member
|
16
28
|
.row
|
@@ -20,5 +32,3 @@
|
|
20
32
|
.row
|
21
33
|
.col-md= f.email_field :email
|
22
34
|
.col-md= f.text_field :company
|
23
|
-
|
24
|
-
%hr
|
@@ -1,11 +1,8 @@
|
|
1
|
-
- if ticket.
|
2
|
-
|
1
|
+
- if ticket.question1.present?
|
2
|
+
= f.text_field :response1, label: ticket.question1
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
- if ticket.question2.present?
|
5
|
+
= f.text_field :response2, label: ticket.question2
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
- if ticket.question3.present?
|
11
|
-
= f.text_field :response3, label: ticket.question3
|
7
|
+
- if ticket.question3.present?
|
8
|
+
= f.text_field :response3, label: ticket.question3
|
@@ -1,43 +1,63 @@
|
|
1
|
-
.
|
2
|
-
|
3
|
-
|
1
|
+
- tickets = resource.event.event_tickets.reject(&:archived?)
|
2
|
+
- member_column = tickets.any? { |ticket| ticket.member_only? || ticket.member_or_non_member? }
|
3
|
+
- waitlist = tickets.any? { |ticket| ticket.waitlist? }
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
- all_member_only_tickets = tickets.all? { |ticket| ticket.member_only? }
|
6
|
+
- any_member_only_tickets = tickets.any? { |ticket| ticket.member_only? }
|
7
7
|
|
8
|
-
|
8
|
+
= card do
|
9
|
+
%table.table.table-sm.table-striped
|
10
|
+
%thead
|
11
|
+
%tr
|
12
|
+
%th Ticket
|
13
|
+
%th Price
|
9
14
|
|
10
|
-
%
|
11
|
-
|
15
|
+
%tbody
|
16
|
+
- tickets.each do |ticket|
|
12
17
|
%tr
|
13
|
-
%
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
%
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
18
|
+
%td
|
19
|
+
= ticket.to_s
|
20
|
+
- if ticket.capacity.present? && ticket.display_capacity?
|
21
|
+
%br
|
22
|
+
%small
|
23
|
+
#{ticket.capacity_available} remaining
|
24
|
+
- if ticket.waitlist?
|
25
|
+
before waitlist
|
26
|
+
|
27
|
+
%td
|
28
|
+
%ul.list-unstyled.mb-0
|
29
|
+
- if resource.event.early_bird? && ticket.early_bird_price.present? && ticket.early_bird_price != 0 && ticket.early_bird_price != ticket.member_price && ticket.early_bird_price != ticket.regular_price
|
30
|
+
%li
|
31
|
+
- if ticket.regular_price.present? && ticket.regular_price != 0
|
32
|
+
%div
|
33
|
+
%s.mr-2.text-muted
|
34
|
+
= price_to_currency(ticket.regular_price)
|
35
|
+
|
36
|
+
- if ticket.member_price.present? && ticket.member_price != 0
|
37
|
+
%div
|
38
|
+
%s.text-muted
|
39
|
+
= price_to_currency(ticket.member_price)
|
40
|
+
.badge.badge-secondary.mr-2 Members
|
41
|
+
|
42
|
+
%div
|
43
|
+
= price_to_currency(ticket.early_bird_price)
|
44
|
+
.badge.badge-warning Early Bird
|
45
|
+
|
39
46
|
- else
|
40
|
-
|
47
|
+
- if ticket.regular_price.present?
|
48
|
+
%li
|
49
|
+
= price_to_currency(ticket.regular_price)
|
50
|
+
|
51
|
+
- if ticket.member_price.present?
|
52
|
+
%li
|
53
|
+
= price_to_currency(ticket.member_price)
|
54
|
+
.badge.badge-secondary Members
|
55
|
+
|
56
|
+
- if waitlist
|
57
|
+
%p If the ticket capacity has been reached you will be added to the waitlist.
|
41
58
|
|
42
|
-
|
43
|
-
|
59
|
+
- unless current_user.try(:is?, :member)
|
60
|
+
- if all_member_only_tickets
|
61
|
+
.alert.alert-info.mb-4 You must be a member to purchase tickets.
|
62
|
+
- elsif any_member_only_tickets
|
63
|
+
.alert.alert-info.mb-4 You must be a member to purchase some of these tickets.
|
@@ -22,10 +22,8 @@
|
|
22
22
|
= render('effective/event_registrants/fields_regular', f: fr)
|
23
23
|
- elsif ticket.member_only?
|
24
24
|
= render('effective/event_registrants/fields_member_only', f: fr)
|
25
|
-
- elsif ticket.member_or_non_member?
|
26
|
-
= render('effective/event_registrants/
|
27
|
-
- elsif ticket.member_or_non_member? && !registrant.member_registrant?
|
28
|
-
= render('effective/event_registrants/fields_regular', f: fr)
|
25
|
+
- elsif ticket.member_or_non_member?
|
26
|
+
= render('effective/event_registrants/fields_member_or_non_member', f: fr)
|
29
27
|
- else
|
30
28
|
- raise("Unexpected ticket category: #{ticket.category || 'nil'}")
|
31
29
|
|
data/lib/effective_events.rb
CHANGED
@@ -24,12 +24,17 @@ module EffectiveEvents
|
|
24
24
|
mailer&.constantize || Effective::EventsMailer
|
25
25
|
end
|
26
26
|
|
27
|
-
def categories
|
27
|
+
def self.categories
|
28
28
|
Array(config[:categories]) - [nil, false, '']
|
29
29
|
end
|
30
30
|
|
31
|
-
def event_registrant_required_fields
|
31
|
+
def self.event_registrant_required_fields
|
32
32
|
(Array(config[:event_registrant_required_fields]) - [nil, false, '']).map(&:to_sym)
|
33
33
|
end
|
34
34
|
|
35
|
+
# If we can create delayed payment events at all
|
36
|
+
def self.delayed?
|
37
|
+
!!EffectiveOrders.try(:delayed?)
|
38
|
+
end
|
39
|
+
|
35
40
|
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.
|
4
|
+
version: 0.19.1
|
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: 2024-
|
11
|
+
date: 2024-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|