effective_events 0.1.10 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/controllers/admin/event_notifications_controller.rb +8 -0
  4. data/app/controllers/effective/event_registrations_controller.rb +0 -34
  5. data/app/controllers/effective/events_controller.rb +0 -15
  6. data/app/datatables/admin/effective_event_notifications_datatable.rb +52 -0
  7. data/app/datatables/admin/effective_event_registrants_datatable.rb +1 -1
  8. data/app/datatables/admin/effective_event_registrations_datatable.rb +2 -2
  9. data/app/datatables/admin/effective_event_tickets_datatable.rb +0 -6
  10. data/app/datatables/admin/effective_events_datatable.rb +13 -8
  11. data/app/datatables/effective_event_registrants_datatable.rb +1 -1
  12. data/app/datatables/effective_events_datatable.rb +1 -5
  13. data/app/helpers/effective_events_helper.rb +0 -4
  14. data/app/mailers/effective/events_mailer.rb +56 -0
  15. data/app/models/concerns/effective_events_event_registration.rb +6 -9
  16. data/app/models/effective/event.rb +5 -2
  17. data/app/models/effective/event_notification.rb +160 -0
  18. data/app/models/effective/event_registrant.rb +4 -0
  19. data/app/views/admin/event_notifications/_form.html.haml +44 -0
  20. data/app/views/admin/event_notifications/_form_event_registrant_purchased.html.haml +3 -0
  21. data/app/views/admin/events/_form.html.haml +6 -0
  22. data/app/views/effective/event_registrations/_addons.html.haml +1 -1
  23. data/app/views/effective/event_registrations/_dashboard.html.haml +1 -1
  24. data/app/views/effective/event_registrations/_event_registration.html.haml +1 -6
  25. data/app/views/effective/event_registrations/{_tickets.haml → _tickets.html.haml} +1 -1
  26. data/app/views/effective/event_registrations/submitted.html.haml +1 -0
  27. data/app/views/effective/event_registrations/{tickets.haml → tickets.html.haml} +0 -0
  28. data/app/views/effective/events/_event.html.haml +37 -17
  29. data/app/views/effective/events/index.html.haml +5 -8
  30. data/app/views/effective/events/show.html.haml +9 -13
  31. data/app/views/effective/events_mailer/event_registrant_purchased.liquid +17 -0
  32. data/config/effective_events.rb +11 -0
  33. data/config/routes.rb +1 -0
  34. data/db/migrate/01_create_effective_events.rb.erb +17 -0
  35. data/lib/effective_events/version.rb +1 -1
  36. data/lib/effective_events.rb +6 -1
  37. metadata +25 -6
  38. data/app/views/effective/events/_layout.html.haml +0 -1
  39. data/app/views/effective/events/_spacer.html.haml +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '069d27a813f8daeb16748df4948a0e653dbe0bb8d3a853e5fe8ef24fda74729c'
4
- data.tar.gz: 2214b6dbdac9cc9e824948303ff983a4aef264fc4544bb43dca0d208a492612c
3
+ metadata.gz: adf3a913271740485085f4e12ae04f6754a13d5d083dd6f36e9e2593758e3fcc
4
+ data.tar.gz: 7d0b73f2c8719a17df4e3d13e92b530621be01ec1f7571d04970fd15f844cbda
5
5
  SHA512:
6
- metadata.gz: 37f1f2d5c00228a0bfbc67ca1aeb49eb70b0691945c06bea4a2432d307658059bbc14bae09d7089c9bea649ab45ecd849bb44af087a90792f3d30827c45411bc
7
- data.tar.gz: 41f9da86b0be58b72eff25b4fd1853105e63be29782787135d90abd8e38fcec7910da9846e640f845635a7424039c3d852e0ebe4fb0032fbaadbd369bc1c4931
6
+ metadata.gz: 0b0b3d00b86109a754208c65df7e9ff9d172cc6ed4d0cc004181e69f1b7b2baf8ba2c80473e7909414a6a96b10ebe3438799f2d516a8e1c0768241685f40680a
7
+ data.tar.gz: 3eba654d48fcf0e1b4f14e44d1b85d5806e89ba959c3f592f4da22a32ef34a66861f4b991372e637becd5f4d7857846e1da819483823d6473e6ecba2245f91be
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Effective Events
2
2
 
3
- Events, event registrants, event tickets and event products.
3
+ Events, event registrants, event tickets, and event products.
4
4
 
5
5
  ## Getting Started
6
6
 
@@ -0,0 +1,8 @@
1
+ module Admin
2
+ class EventNotificationsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_events) }
5
+
6
+ include Effective::CrudController
7
+ end
8
+ end
@@ -9,39 +9,5 @@ module Effective
9
9
  EffectiveEvents.EventRegistration.deep.where(owner: current_user, event: event)
10
10
  }
11
11
 
12
- # Allow only 1 in-progress event registration at a time
13
- before_action(only: [:new, :show], unless: -> { resource&.done? }) do
14
- existing = resource_scope.in_progress.where.not(id: resource).first
15
-
16
- if existing.present?
17
- flash[:success] = "You have been redirected to your existing in progress event registration"
18
- redirect_to effective_events.event_event_registration_build_path(existing.event, existing, existing.next_step)
19
- end
20
- end
21
-
22
- after_save do
23
- flash.now[:success] = ''
24
- end
25
-
26
- # The default redirect doesn't respect nested resources here
27
- def new
28
- self.resource ||= (find_wizard_resource || resource_scope.new)
29
- EffectiveResources.authorize!(self, :new, resource)
30
-
31
- redirect_to effective_events.event_event_registration_build_path(
32
- resource.event,
33
- (resource.to_param || :new),
34
- (resource.first_uncompleted_step || resource_wizard_steps.first)
35
- )
36
- end
37
-
38
- private
39
-
40
- def permitted_params
41
- model = (params.key?(:effective_event_registration) ? :effective_event_registration : :event_registration)
42
-
43
- params.require(model).permit!.except(:status, :status_steps, :wizard_steps, :submitted_at)
44
- end
45
-
46
12
  end
47
13
  end
@@ -7,21 +7,6 @@ module Effective
7
7
  Effective::Event.events(user: current_user, unpublished: unpublished)
8
8
  }
9
9
 
10
- def index
11
- @events ||= resource_scope
12
-
13
- @events = @events.paginate(page: params[:page])
14
-
15
- # if params[:search].present?
16
- # search = params[:search].permit(EffectiveEvents.permitted_params).delete_if { |k, v| v.blank? }
17
- # @events = @events.where(search) if search.present?
18
- # end
19
-
20
- EffectiveResources.authorize!(self, :index, Effective::Event)
21
-
22
- @page_title ||= ['Events', (" - Page #{params[:page]}" if params[:page])].compact.join
23
- end
24
-
25
10
  def show
26
11
  @event = resource_scope.find(params[:id])
27
12
 
@@ -0,0 +1,52 @@
1
+ class Admin::EffectiveEventNotificationsDatatable < Effective::Datatable
2
+ # filters do
3
+ # scope :all
4
+ # scope :started
5
+ # scope :completed
6
+ # end
7
+
8
+ datatable do
9
+ col :updated_at, visible: false
10
+ col :created_at, visible: false
11
+ col :id, visible: false
12
+
13
+ col :event
14
+ col :category
15
+
16
+ col :from do |event|
17
+ html_escape(event.from)
18
+ end
19
+
20
+ # col :reminder do |poll_notification|
21
+ # case poll_notification.category
22
+ # when 'When poll starts'
23
+ # poll_notification.poll.start_at&.strftime('%F %H:%M')
24
+ # when 'When poll ends'
25
+ # poll_notification.poll.end_at&.strftime('%F %H:%M')
26
+ # when 'Upcoming reminder'
27
+ # Effective::PollNotification::UPCOMING_REMINDERS.invert[poll_notification.reminder]
28
+ # when 'Reminder'
29
+ # Effective::PollNotification::REMINDERS.invert[poll_notification.reminder]
30
+ # when 'Before poll ends'
31
+ # Effective::PollNotification::UPCOMING_REMINDERS.invert[poll_notification.reminder]
32
+ # else
33
+ # raise('unexpected category')
34
+ # end
35
+ # end
36
+
37
+ col :subject
38
+
39
+ col :body do |notification|
40
+ simple_format(notification.body)
41
+ end
42
+
43
+ # col :started_at, visible: false
44
+ # col :completed_at
45
+
46
+ actions_col
47
+ end
48
+
49
+ collection do
50
+ Effective::EventNotification.all.deep
51
+ end
52
+ end
@@ -16,7 +16,7 @@ module Admin
16
16
  col :event_ticket, search: :string
17
17
  end
18
18
 
19
- col :purchased_order
19
+ col :purchased_order, visible: false
20
20
 
21
21
  col :first_name
22
22
  col :last_name
@@ -12,8 +12,8 @@ class Admin::EffectiveEventRegistrationsDatatable < Effective::Datatable
12
12
  col :event, search: :string
13
13
  col :owner
14
14
 
15
- col :event_registrants, search: :string
16
- col :event_addons, search: :string
15
+ col :event_registrants, search: :string, visible: false
16
+ col :event_addons, search: :string, visible: false
17
17
  col :orders, label: 'Order'
18
18
 
19
19
  actions_col
@@ -25,12 +25,6 @@ module Admin
25
25
  col :capacity, visible: false
26
26
  col :capacity_available, visible: false
27
27
 
28
- col :purchased_event_registrants, label: 'Registrants' do |ticket|
29
- ticket.purchased_event_registrants.sort_by(&:last_name).map do |registrant|
30
- content_tag(:div, registrant.last_first_name, class: 'col-resource_item')
31
- end.join.html_safe
32
- end
33
-
34
28
  actions_col
35
29
  end
36
30
 
@@ -13,17 +13,21 @@ module Admin
13
13
  col :created_at, visible: false
14
14
  col :id, visible: false
15
15
 
16
- col :title
16
+ col :title do |event|
17
+ link_to event.title, effective_events.edit_admin_event_path(event)
18
+ end
19
+
20
+ col :slug, visible: false
17
21
  col :draft
18
- col :start_at, label: 'Event Start Date'
19
- col :end_at, label: 'Event End Date', visible: false
22
+ col :start_at, label: 'Start', visible: false
23
+ col :end_at, label: 'End', visible: false
20
24
  col :excerpt, visible: false
21
25
 
22
26
  col :registration_start_at, label: 'Registration opens', visible: false
23
27
  col :registration_end_at, label: 'Registration closes', visible: false
24
28
  col :early_bird_end_at, label: 'Early bird ends', visible: false
25
29
 
26
- col :early_bird do |event|
30
+ col :early_bird, visible: false do |event|
27
31
  if event.early_bird?
28
32
  content_tag(:span, event.early_bird_status, class: 'badge badge-success')
29
33
  else
@@ -31,10 +35,11 @@ module Admin
31
35
  end
32
36
  end
33
37
 
34
- col :event_tickets, search: :string
35
- col :event_products, search: :string
36
- col :event_registrants, search: :string
37
- col :event_addons, search: :string
38
+ # These show too much information to be useful to admins, rely on the edit screen
39
+ # col :event_tickets, search: :string
40
+ # col :event_products, search: :string
41
+ # col :event_registrants, search: :string
42
+ # col :event_addons, search: :string
38
43
 
39
44
  col :roles, visible: false
40
45
  col :authenticate_user, visible: false
@@ -1,4 +1,4 @@
1
- # Used on the Event Registrations registrants step
1
+ # Used on the Event Registrations tickets step
2
2
 
3
3
  class EffectiveEventRegistrantsDatatable < Effective::Datatable
4
4
  datatable do
@@ -13,11 +13,7 @@ class EffectiveEventsDatatable < Effective::Datatable
13
13
  col :start_at, label: 'Date', as: :date
14
14
 
15
15
  col :title, label: 'Title' do |event|
16
- if event.registerable?
17
- link_to(event.to_s, effective_events.new_event_event_registration_path(event))
18
- else
19
- event.to_s
20
- end
16
+ link_to(event.to_s, effective_events.event_path(event))
21
17
  end
22
18
 
23
19
  col :registration_start_at, visible: false
@@ -30,8 +30,4 @@ module EffectiveEventsHelper
30
30
  end
31
31
  end
32
32
 
33
- def edit_effective_event_registrations_wizard?
34
- params[:controller] == 'effective/event_registrations' && defined?(resource) && resource.draft?
35
- end
36
-
37
33
  end
@@ -0,0 +1,56 @@
1
+ module Effective
2
+ class EventsMailer < EffectiveResources.parent_mailer_class
3
+ default from: -> { EffectiveResources.mailer_sender }
4
+ layout -> { EffectiveResources.mailer_layout }
5
+
6
+ include EffectiveEmailTemplatesMailer if EffectiveEvents.use_effective_email_templates
7
+
8
+ def event_registrant_purchased(event_registrant, opts = {})
9
+ @assigns = assigns_for(event_registrant)
10
+ @event_registrant = event_registrant
11
+
12
+ mail(to: event_registrant.email, **headers_for(event_registrant, opts))
13
+ end
14
+
15
+ protected
16
+
17
+ def headers_for(resource, opts = {})
18
+ resource.respond_to?(:log_changes_datatable) ? opts.merge(log: resource) : opts
19
+ end
20
+
21
+ def assigns_for(resource)
22
+ if resource.kind_of?(EventRegistrant)
23
+ return event_registrant_assigns(resource).merge(event_assigns(resource.event)).merge(event_ticket_assigns(resource.event_ticket))
24
+ end
25
+
26
+ raise('unexpected resource')
27
+ end
28
+
29
+ def event_assigns(resource)
30
+ raise('expected an event') unless resource.kind_of?(Event)
31
+
32
+ values = {
33
+ name: resource.title,
34
+ date: resource.start_at.strftime('%F %H:%M'),
35
+ url: effective_events.event_url(resource)
36
+ }
37
+
38
+ { event: values }
39
+ end
40
+
41
+ def event_ticket_assigns(resource)
42
+ raise('expected an event ticket') unless resource.kind_of?(EventTicket)
43
+
44
+ values = { name: resource.title }
45
+ { ticket: values }
46
+ end
47
+
48
+ def event_registrant_assigns(resource)
49
+ raise('expected an event registrant') unless resource.kind_of?(EventRegistrant)
50
+
51
+ values = { name: resource.name, email: resource.email }
52
+ { registrant: values }
53
+ end
54
+
55
+ end
56
+ end
@@ -15,14 +15,6 @@ module EffectiveEventsEventRegistration
15
15
 
16
16
  module ClassMethods
17
17
  def effective_events_event_registration?; true; end
18
-
19
- def all_wizard_steps
20
- const_get(:WIZARD_STEPS).keys
21
- end
22
-
23
- def required_wizard_steps
24
- [:start, :summary, :billing, :checkout, :submitted]
25
- end
26
18
  end
27
19
 
28
20
  included do
@@ -90,7 +82,7 @@ module EffectiveEventsEventRegistration
90
82
  validates :owner, presence: true
91
83
  validates :event, presence: true
92
84
 
93
- # Registrants Step
85
+ # Tickets Step
94
86
  validate(if: -> { current_step == :tickets }) do
95
87
  self.errors.add(:event_registrants, "can't be blank") unless present_event_registrants.present?
96
88
  end
@@ -118,6 +110,11 @@ module EffectiveEventsEventRegistration
118
110
  (event_registrants + event_addons)
119
111
  end
120
112
 
113
+ def after_submit_purchased!
114
+ notifications = event.event_notifications.select(&:registrant_purchased?)
115
+ notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
116
+ end
117
+
121
118
  end
122
119
 
123
120
  # Instance Methods
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Effective
4
4
  class Event < ActiveRecord::Base
5
- has_many :event_tickets, -> { EventTicket.sorted }, inverse_of: :event
5
+ has_many :event_tickets, -> { EventTicket.sorted }, inverse_of: :event, dependent: :destroy
6
6
  accepts_nested_attributes_for :event_tickets, allow_destroy: true
7
7
 
8
- has_many :event_products, -> { EventProduct.sorted }, inverse_of: :event
8
+ has_many :event_products, -> { EventProduct.sorted }, inverse_of: :event, dependent: :destroy
9
9
  accepts_nested_attributes_for :event_products, allow_destroy: true
10
10
 
11
11
  has_many :event_registrants, -> { order(:event_ticket_id, :created_at) }, inverse_of: :event
@@ -14,6 +14,9 @@ module Effective
14
14
  has_many :event_addons, -> { order(:event_product_id, :created_at) }, inverse_of: :event
15
15
  accepts_nested_attributes_for :event_addons, allow_destroy: true
16
16
 
17
+ has_many :event_notifications, -> { order(:id) }, inverse_of: :event, dependent: :destroy
18
+ accepts_nested_attributes_for :event_notifications, allow_destroy: true
19
+
17
20
  # rich_text_body - Used by the select step
18
21
  has_many_rich_texts
19
22
 
@@ -0,0 +1,160 @@
1
+ module Effective
2
+ class EventNotification < ActiveRecord::Base
3
+ log_changes(to: :event) if respond_to?(:log_changes)
4
+
5
+ belongs_to :event
6
+
7
+ CATEGORIES = ['Registrant purchased']
8
+ EMAIL_TEMPLATE_VARIABLES = ['event.name', 'event.date', 'event.url', 'ticket.name', 'registrant.name', 'registrant.email']
9
+
10
+ #CATEGORIES = ['Upcoming reminder', 'When event starts', 'Reminder', 'Before event ends', 'When event ends']
11
+
12
+ # UPCOMING_REMINDERS = {
13
+ # '1 hour before' => 1.hours.to_i,
14
+ # '3 hours before' => 3.hours.to_i,
15
+ # '6 hours before' => 6.hours.to_i,
16
+ # '12 hours before' => 12.hours.to_i,
17
+ # '1 day before' => 1.days.to_i,
18
+ # '2 days before' => 2.days.to_i,
19
+ # '3 days before' => 3.days.to_i,
20
+ # '4 days before' => 4.days.to_i,
21
+ # '5 days before' => 5.days.to_i,
22
+ # '6 days before' => 6.days.to_i,
23
+ # '1 week before' => 1.weeks.to_i,
24
+ # '2 weeks before' => 2.weeks.to_i,
25
+ # '3 weeks before' => 3.weeks.to_i,
26
+ # '1 month before' => 1.month.to_i
27
+ # }
28
+
29
+ # REMINDERS = {
30
+ # '1 hour after' => 1.hours.to_i,
31
+ # '3 hours after' => 3.hours.to_i,
32
+ # '6 hours after' => 6.hours.to_i,
33
+ # '12 hours after' => 12.hours.to_i,
34
+ # '1 day after' => 1.days.to_i,
35
+ # '2 days after' => 2.days.to_i,
36
+ # '3 days after' => 3.days.to_i,
37
+ # '4 days after' => 4.days.to_i,
38
+ # '5 days after' => 5.days.to_i,
39
+ # '6 days after' => 6.days.to_i,
40
+ # '1 week after' => 1.weeks.to_i,
41
+ # '2 weeks after' => 2.weeks.to_i,
42
+ # '3 weeks after' => 3.weeks.to_i,
43
+ # '1 month after' => 1.month.to_i
44
+ # }
45
+
46
+ effective_resource do
47
+ category :string
48
+ reminder :integer # Number of seconds before event.start_at
49
+
50
+ # Email
51
+ from :string
52
+ subject :string
53
+ body :text
54
+
55
+ # Tracking background jobs email send out
56
+ started_at :datetime
57
+ completed_at :datetime
58
+
59
+ timestamps
60
+ end
61
+
62
+ scope :sorted, -> { order(:id) }
63
+ scope :deep, -> { includes(:event) }
64
+
65
+ scope :started, -> { where.not(started_at: nil) }
66
+ scope :completed, -> { where.not(completed_at: nil) }
67
+
68
+ # Called by a future event_notifier rake task
69
+ scope :notifiable, -> { where(started_at: nil, completed_at: nil) }
70
+
71
+ validates :category, presence: true, inclusion: { in: CATEGORIES }
72
+
73
+ validates :from, presence: true, email: true
74
+ validates :subject, presence: true
75
+ validates :body, presence: true
76
+
77
+ if EffectiveEvents.use_effective_email_templates
78
+ validates :body, liquid: true
79
+ validates :subject, liquid: true
80
+ end
81
+
82
+ # validates :reminder, if: -> { reminder? || upcoming_reminder? || before_event_ends? },
83
+ # presence: true, uniqueness: { scope: [:event_id, :category], message: 'already exists' }
84
+
85
+ def to_s
86
+ 'event notification'
87
+ end
88
+
89
+ def email_template
90
+ 'event_' + category.to_s.parameterize.underscore
91
+ end
92
+
93
+ def registrant_purchased?
94
+ category == 'Registrant purchased'
95
+ end
96
+
97
+ # def upcoming_reminder?
98
+ # category == 'Upcoming reminder'
99
+ # end
100
+
101
+ # def event_start?
102
+ # category == 'When event starts'
103
+ # end
104
+
105
+ # def reminder?
106
+ # category == 'Reminder'
107
+ # end
108
+
109
+ # def before_event_ends?
110
+ # category == 'Before event ends'
111
+ # end
112
+
113
+ # def event_end?
114
+ # category == 'When event ends'
115
+ # end
116
+
117
+ # def notifiable?
118
+ # started_at.blank? && completed_at.blank?
119
+ # end
120
+
121
+ def notify_now?
122
+ true
123
+
124
+ #return false unless notifiable?
125
+
126
+ # case category
127
+ # when 'When event starts'
128
+ # event.available?
129
+ # when 'When event ends'
130
+ # event.ended?
131
+ # when 'Upcoming reminder'
132
+ # !event.started? && event.start_at < (Time.zone.now + reminder)
133
+ # when 'Reminder'
134
+ # !event.ended? && event.start_at < (Time.zone.now - reminder)
135
+ # when 'Before event ends'
136
+ # !event.ended? && event.end_at.present? && event.end_at < (Time.zone.now + reminder)
137
+ # else
138
+ # raise('unexpected category')
139
+ # end
140
+ end
141
+
142
+ def notify!(force: false, event_registrants: nil)
143
+ return false unless (notify_now? || force)
144
+
145
+ # We send one email to each registrant
146
+ event_registrants ||= event.event_registrants.purchased
147
+
148
+ update_column(:started_at, Time.zone.now)
149
+
150
+ opts = { from: from, subject: subject, body: body }
151
+
152
+ event_registrants.each do |event_registrant|
153
+ EffectiveEvents.send_email(email_template, event_registrant, opts)
154
+ end
155
+
156
+ update_column(:completed_at, Time.zone.now)
157
+ end
158
+
159
+ end
160
+ end
@@ -58,6 +58,10 @@ module Effective
58
58
  "#{event_ticket} - #{last_first_name}"
59
59
  end
60
60
 
61
+ def name
62
+ "#{first_name} #{last_name}"
63
+ end
64
+
61
65
  def last_first_name
62
66
  "#{last_name}, #{first_name}"
63
67
  end
@@ -0,0 +1,44 @@
1
+ = effective_form_with(model: [:admin, event_notification], engine: true) do |f|
2
+ - if inline_datatable?
3
+ = f.hidden_field :event_id
4
+ - else
5
+ = f.select :event_id, Effective::Event.sorted.all
6
+
7
+ = f.select :category, Effective::EventNotification::CATEGORIES,
8
+ label: 'Send an email notification'
9
+
10
+ - # Render email templates
11
+ - Effective::EventNotification::CATEGORIES.each do |category|
12
+ - template = 'event_' + category.parameterize.underscore
13
+
14
+ = f.show_if :category, category do
15
+ = render "/admin/event_notifications/form_#{template}", f: f
16
+
17
+ - if f.object.category == category && f.object.persisted?
18
+ = f.text_field :from
19
+ = f.text_field :subject
20
+ = f.text_area :body, rows: 10
21
+
22
+ - elsif EffectiveEvents.use_effective_email_templates == false
23
+ = f.text_field :from, value: EffectiveResources.mailer_sender
24
+ = f.text_field :subject, value: ''
25
+ = f.text_area :body, rows: 10, value: ''
26
+
27
+ - else
28
+ - email_template = Effective::EmailTemplate.where(template_name: template).first!
29
+
30
+ = f.text_field :from, value: email_template.from
31
+ = f.text_field :subject, value: email_template.subject
32
+ = f.text_area :body, rows: 10, value: email_template.body
33
+
34
+ - if EffectiveEvents.use_effective_email_templates
35
+
36
+ %p The available variables are:
37
+
38
+ %ul
39
+ - Effective::EventNotification::EMAIL_TEMPLATE_VARIABLES.each do |variable|
40
+ %li {{ #{variable} }}
41
+
42
+ %small.text-muted Only a developer can add additional variables
43
+
44
+ = effective_submit(f)
@@ -0,0 +1,3 @@
1
+ .alert.alert-warning
2
+ %strong When registrant purchased
3
+ notifications will be sent to each registrant at time of purchase.
@@ -16,6 +16,12 @@
16
16
  - datatable = Admin::EffectiveEventProductsDatatable.new(event_id: event.id)
17
17
  = render_inline_datatable(datatable)
18
18
 
19
+ = tab 'Email' do
20
+ %p Click New to add one or more emails.
21
+
22
+ - datatable = Admin::EffectiveEventNotificationsDatatable.new(event_id: event.id)
23
+ = render_datatable(datatable, inline: true, simple: true)
24
+
19
25
  = tab 'Registrations' do
20
26
  %h2 Registrations
21
27
  - datatable = Admin::EffectiveEventRegistrationsDatatable.new(event_id: event.id)
@@ -3,7 +3,7 @@
3
3
  .col-sm
4
4
  %h5.card-title= event_registration.wizard_step_title(:addons)
5
5
  .col-sm-auto.text-right
6
- = link_to('Edit', wizard_path(:addons)) if edit_effective_event_registrations_wizard?
6
+ = link_to('Edit', wizard_path(:addons)) if edit_effective_wizard?
7
7
 
8
8
  - datatable = EffectiveEventAddonsDatatable.new(event_registration: event_registration)
9
9
  .mb-4= render_simple_datatable(datatable)
@@ -17,7 +17,7 @@
17
17
  = link_to('Abandon registration', effective_events.event_event_registration_path(registration.event, registration), 'data-confirm': "Really delete #{registration}?", 'data-method': :delete, class: 'btn btn-danger')
18
18
  to register for another event.
19
19
 
20
- %hr
20
+ %hr
21
21
 
22
22
  %h2 Event Registrations
23
23
 
@@ -1,8 +1,3 @@
1
1
  .effective-event-registration
2
- - blacklist = EffectiveEvents.EventRegistration.required_wizard_steps
3
- - steps = event_registration.required_steps - blacklist
4
-
5
- = render "effective/event_registrations/summary", event_registration: event_registration
6
-
7
- - steps.select { |step| event_registration.has_completed_step?(step) }.each do |partial|
2
+ - event_registration.render_steps.each do |partial|
8
3
  = render "effective/event_registrations/#{partial}", event_registration: event_registration, step: partial
@@ -3,7 +3,7 @@
3
3
  .col-sm
4
4
  %h5.card-title= event_registration.wizard_step_title(:tickets)
5
5
  .col-sm-auto.text-right
6
- = link_to('Edit', wizard_path(:tickets)) if edit_effective_event_registrations_wizard?
6
+ = link_to('Edit', wizard_path(:tickets)) if edit_effective_wizard?
7
7
 
8
8
  - datatable = EffectiveEventRegistrantsDatatable.new(event_registration: event_registration)
9
9
  .mb-4= render_simple_datatable(datatable)
@@ -9,6 +9,7 @@
9
9
 
10
10
  = link_to "Return to Dashboard", root_path, class: 'btn btn-lg btn-primary mb-4'
11
11
 
12
+ = render 'effective/event_registrations/summary', event_registration: resource
12
13
  = render 'effective/event_registrations/event_registration', event_registration: resource
13
14
  = render 'effective/event_registrations/orders', event_registration: resource
14
15
 
@@ -1,21 +1,41 @@
1
- .effective-event
2
- %table.table.effective-events-table
3
- %tbody
4
- %tr
5
- %td Starts
6
- %td= event.start_at
1
+ .card
2
+ .card-body
3
+ %table.table.effective-events-table
4
+ %tbody
5
+ %tr
6
+ %th Dates
7
+ %td
8
+ Starts: #{event.start_at&.strftime('%F %R')}
9
+ %br
10
+ Ends: #{event.end_at&.strftime('%F %R')}
7
11
 
8
- %tr
9
- %td Ends
10
- %td= event.end_at
12
+ %tr
13
+ %th Registration Closes
14
+ %td= event.registration_end_at.strftime('%F %R')
11
15
 
12
- %tr
13
- %td Registration Closes
14
- %td= event.registration_end_at
16
+ %tr
17
+ %th Early Bird
18
+ %td
19
+ Status: #{event.early_bird_status}
20
+ %br
21
+ Ends: #{event.early_bird_end_at&.strftime('%F %R')}
15
22
 
16
- %tr
17
- %td Early Bird Status
18
- %td= event.early_bird_status
23
+ %tr
24
+ %th Tickets
25
+ %td
26
+ %ul.pl-3
27
+ - event.event_tickets.each do |ticket|
28
+ %li= "#{ticket} (#{price_to_currency(ticket.price)})"
19
29
 
20
- .event-content.event-excerpt
21
- = event.excerpt
30
+ - if event.event_products.present?
31
+ %tr
32
+ %th Add-ons
33
+ %td
34
+ %ul.pl-0
35
+ - event.event_products.each do |product|
36
+ %li= "#{product} (#{price_to_currency(product.price)})"
37
+
38
+ - if event.body.present?
39
+ %tr
40
+ %th Description
41
+ %td= event.body
@@ -1,8 +1,5 @@
1
- %h1= @page_title
2
-
3
- = render 'layout' do
4
- .effective-events
5
- = render partial: @events, spacer_template: 'spacer'
6
-
7
- %nav.d-flex.justify-content-center
8
- = bootstrap_paginate(@events, per_page: EffectiveEvents.per_page)
1
+ = card do
2
+ - if @datatable.present?(self)
3
+ = render_datatable(@datatable, simple: true)
4
+ - else
5
+ %p There are no events open for registration. When there are, we'll show them here.
@@ -1,16 +1,12 @@
1
- = render 'layout' do
2
- .effective-event
3
- - if @event.sold_out?
4
- .alert.alert-warning This event is sold out.
1
+ .effective-event
2
+ - if @event.sold_out?
3
+ .alert.alert-warning This event is sold out.
5
4
 
6
- - if @event.closed?
7
- .alert.alert-warning This event is no longer available.
5
+ - if @event.closed?
6
+ .alert.alert-warning This event is no longer available.
8
7
 
9
- - if @event.registerable?
10
- .resource-buttons
11
- = link_to 'Register', effective_events.new_event_event_registration_path(@event), class: 'btn btn-primary'
8
+ - if @event.registerable?
9
+ .resource-buttons
10
+ = link_to 'Register', effective_events.new_event_event_registration_path(@event), class: 'btn btn-primary'
12
11
 
13
- = render 'effective/events/event', event: @event
14
-
15
- .event-body.event-content
16
- = @event.body
12
+ = render 'effective/events/event', event: @event
@@ -0,0 +1,17 @@
1
+ ---
2
+ subject: 'You have been registered for {{ event.title }}'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ registrant.name }},
6
+
7
+ Your ticket {{ ticket.name }} has been purchased.
8
+
9
+ You are registered for {{ event.name }}
10
+
11
+ The event starts on {{ event.date }}
12
+
13
+ {{ event.url }}
14
+
15
+ Thank you.
16
+
17
+ Please contact us for assistance.
@@ -18,4 +18,15 @@ EffectiveEvents.setup do |config|
18
18
 
19
19
  # Events can be restricted by role
20
20
  config.use_effective_roles = true
21
+
22
+ # Mailer Configuration
23
+ #
24
+ # Additional mailer settings for parent_mailer, delivery_method, layout, sender and admin
25
+ # are required fields in config/initializers/effective_resources.rb
26
+
27
+ # Configure the class responsible to send e-mails.
28
+ # config.mailer = 'Effective::EventsMailer'
29
+
30
+ # Use effective email templates for event notifications
31
+ config.use_effective_email_templates = true
21
32
  end
data/config/routes.rb CHANGED
@@ -21,6 +21,7 @@ EffectiveEvents::Engine.routes.draw do
21
21
  resources :event_registrants, except: [:show]
22
22
  resources :event_addons, except: [:show]
23
23
  resources :event_registrations, only: [:index, :show]
24
+ resources :event_notifications, except: [:show]
24
25
  end
25
26
 
26
27
  end
@@ -131,5 +131,22 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0]
131
131
  add_index <%= @event_registrations_table_name %>, :status
132
132
  add_index <%= @event_registrations_table_name %>, :token
133
133
 
134
+ create_table <%= @event_notifications_table_name %> do |t|
135
+ t.references :event
136
+
137
+ t.string :category
138
+ t.integer :reminder
139
+
140
+ t.string :from
141
+ t.string :subject
142
+ t.text :body
143
+
144
+ t.datetime :started_at
145
+ t.datetime :completed_at
146
+
147
+ t.datetime :updated_at
148
+ t.datetime :created_at
149
+ end
150
+
134
151
  end
135
152
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveEvents
2
- VERSION = '0.1.10'.freeze
2
+ VERSION = '0.2.3'.freeze
3
3
  end
@@ -9,7 +9,8 @@ module EffectiveEvents
9
9
  :events_table_name, :event_registrants_table_name, :event_tickets_table_name,
10
10
  :event_registrations_table_name, :event_products_table_name, :event_addons_table_name,
11
11
  :layout, :per_page, :use_effective_roles,
12
- :event_registration_class_name
12
+ :event_registration_class_name,
13
+ :mailer, :use_effective_email_templates
13
14
  ]
14
15
  end
15
16
 
@@ -19,4 +20,8 @@ module EffectiveEvents
19
20
  event_registration_class_name&.constantize || Effective::EventRegistration
20
21
  end
21
22
 
23
+ def self.mailer_class
24
+ mailer&.constantize || Effective::EventsMailer
25
+ end
26
+
22
27
  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.10
4
+ version: 0.2.3
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-17 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: effective_email_templates
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: Event registrations, tickets and products
168
182
  email:
169
183
  - info@codeandeffect.com
@@ -180,6 +194,7 @@ files:
180
194
  - app/assets/stylesheets/effective_events.scss
181
195
  - app/assets/stylesheets/effective_events/base.scss
182
196
  - app/controllers/admin/event_addons_controller.rb
197
+ - app/controllers/admin/event_notifications_controller.rb
183
198
  - app/controllers/admin/event_products_controller.rb
184
199
  - app/controllers/admin/event_registrants_controller.rb
185
200
  - app/controllers/admin/event_registrations_controller.rb
@@ -188,6 +203,7 @@ files:
188
203
  - app/controllers/effective/event_registrations_controller.rb
189
204
  - app/controllers/effective/events_controller.rb
190
205
  - app/datatables/admin/effective_event_addons_datatable.rb
206
+ - app/datatables/admin/effective_event_notifications_datatable.rb
191
207
  - app/datatables/admin/effective_event_products_datatable.rb
192
208
  - app/datatables/admin/effective_event_registrants_datatable.rb
193
209
  - app/datatables/admin/effective_event_registrations_datatable.rb
@@ -198,14 +214,18 @@ files:
198
214
  - app/datatables/effective_event_registrations_datatable.rb
199
215
  - app/datatables/effective_events_datatable.rb
200
216
  - app/helpers/effective_events_helper.rb
217
+ - app/mailers/effective/events_mailer.rb
201
218
  - app/models/concerns/effective_events_event_registration.rb
202
219
  - app/models/effective/event.rb
203
220
  - app/models/effective/event_addon.rb
221
+ - app/models/effective/event_notification.rb
204
222
  - app/models/effective/event_product.rb
205
223
  - app/models/effective/event_registrant.rb
206
224
  - app/models/effective/event_registration.rb
207
225
  - app/models/effective/event_ticket.rb
208
226
  - app/views/admin/event_addons/_form.html.haml
227
+ - app/views/admin/event_notifications/_form.html.haml
228
+ - app/views/admin/event_notifications/_form_event_registrant_purchased.html.haml
209
229
  - app/views/admin/event_products/_form.html.haml
210
230
  - app/views/admin/event_registrants/_form.html.haml
211
231
  - app/views/admin/event_tickets/_form.html.haml
@@ -223,20 +243,19 @@ files:
223
243
  - app/views/effective/event_registrations/_layout.html.haml
224
244
  - app/views/effective/event_registrations/_orders.html.haml
225
245
  - app/views/effective/event_registrations/_summary.html.haml
226
- - app/views/effective/event_registrations/_tickets.haml
246
+ - app/views/effective/event_registrations/_tickets.html.haml
227
247
  - app/views/effective/event_registrations/addons.html.haml
228
248
  - app/views/effective/event_registrations/billing.html.haml
229
249
  - app/views/effective/event_registrations/checkout.html.haml
230
250
  - app/views/effective/event_registrations/start.html.haml
231
251
  - app/views/effective/event_registrations/submitted.html.haml
232
252
  - app/views/effective/event_registrations/summary.html.haml
233
- - app/views/effective/event_registrations/tickets.haml
253
+ - app/views/effective/event_registrations/tickets.html.haml
234
254
  - app/views/effective/events/_dashboard.html.haml
235
255
  - app/views/effective/events/_event.html.haml
236
- - app/views/effective/events/_layout.html.haml
237
- - app/views/effective/events/_spacer.html.haml
238
256
  - app/views/effective/events/index.html.haml
239
257
  - app/views/effective/events/show.html.haml
258
+ - app/views/effective/events_mailer/event_registrant_purchased.liquid
240
259
  - config/effective_events.rb
241
260
  - config/routes.rb
242
261
  - db/migrate/01_create_effective_events.rb.erb
@@ -1 +0,0 @@
1
- = yield
@@ -1 +0,0 @@
1
- %hr