effective_events 0.1.10 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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