diff --git a/app/controllers/admin/emails_controller.rb b/app/controllers/admin/emails_controller.rb new file mode 100644 index 00000000..c5bbb690 --- /dev/null +++ b/app/controllers/admin/emails_controller.rb @@ -0,0 +1,14 @@ +class Admin::EmailsController < ApplicationController + before_filter :verify_organizer + layout "admin" + + def update + @conference.email_settings.update_attributes(params[:email_settings]) + redirect_to(admin_conference_email_settings_path(@conference.short_title), :notice => 'Settings have been successfully updated.') + end + + def show + @settings = @conference.email_settings + end + +end diff --git a/app/controllers/conference_registration_controller.rb b/app/controllers/conference_registration_controller.rb index 50b8d3d5..ed24ba3d 100644 --- a/app/controllers/conference_registration_controller.rb +++ b/app/controllers/conference_registration_controller.rb @@ -13,6 +13,7 @@ class ConferenceRegistrationController < ApplicationController end end + # TODO this is ugly def update conference = Conference.find_all_by_short_title(params[:id]).first person = current_user.person @@ -37,6 +38,8 @@ class ConferenceRegistrationController < ApplicationController redirect_message = "You are now registered." if update_registration redirect_message = "Registration updated." + else + Mailbot.registration_mail(request.host_with_port, conference, current_user.person).deliver end redirect_to(register_conference_path(:id => conference.short_title), :notice => redirect_message) end diff --git a/app/mailers/mailbot.rb b/app/mailers/mailbot.rb new file mode 100644 index 00000000..16251944 --- /dev/null +++ b/app/mailers/mailbot.rb @@ -0,0 +1,36 @@ +class Mailbot < ActionMailer::Base + default from: "no-reply@example.com" + + def registration_mail(host, conference, person) + mail(:to => person.email, + :from => conference.contact_email, + :reply_to => conference.contact_email, + :subject => conference.email_settings.registration_subject, + :body => conference.email_settings.generate_registration_email(host, conference, person)) + end + + def acceptance_mail(host, conference, person, event) + mail(:to => person.email, + :from => conference.contact_email, + :reply_to => conference.contact_email, + :subject => conference.email_settings.accepted_subject, + :body => conference.email_settings.generate_accepted_email(host, conference, person, event)) + end + + def rejection_mail(host, conference, person, event) + mail(:to => person.email, + :from => conference.contact_email, + :reply_to => conference.contact_email, + :subject => conference.email_settings.rejected_subject, + :body => conference.email_settings.generate_rejected_email(host, conference, person, event)) + end + + def confirm_reminder_mail(host, conference, person, event) + mail(:to => person.email, + :from => conference.contact_email, + :reply_to => conference.contact_email, + :subject => conference.email_settings.confirmed_without_registration_subject, + :body => conference.email_settings.confirmed_but_not_registered_email(host, conference, person, event)) + end + +end diff --git a/app/models/conference.rb b/app/models/conference.rb index 55c90d6c..a829acac 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -5,6 +5,7 @@ class Conference < ActiveRecord::Base has_paper_trail + has_one :email_settings, :dependent => :destroy has_one :call_for_papers, :dependent => :destroy has_many :events, :dependent => :destroy has_many :event_types, :dependent => :destroy @@ -18,6 +19,7 @@ class Conference < ActiveRecord::Base accepts_nested_attributes_for :tracks, :reject_if => proc {|r| r["name"].blank?}, :allow_destroy => true accepts_nested_attributes_for :venue accepts_nested_attributes_for :event_types, :allow_destroy => true + accepts_nested_attributes_for :email_settings validates_presence_of :title, :short_title, @@ -26,7 +28,7 @@ class Conference < ActiveRecord::Base validates_format_of :short_title, :with => /^[a-zA-Z0-9_-]*$/ before_create :generate_guid before_create :create_venue - + before_create :create_email_settings def self.current self.order("created_at DESC").first @@ -88,6 +90,10 @@ class Conference < ActiveRecord::Base true end + def create_email_settings + build_email_settings + true + end def generate_guid begin guid = SecureRandom.urlsafe_base64 diff --git a/app/models/email_settings.rb b/app/models/email_settings.rb new file mode 100644 index 00000000..a5e4e8c4 --- /dev/null +++ b/app/models/email_settings.rb @@ -0,0 +1,52 @@ +class EmailSettings < ActiveRecord::Base + attr_accessible :send_on_registration, :send_on_accepted, :send_on_rejected, :send_on_confirmed_without_registration, + :registration_email_template, :accepted_email_template, :rejected_email_template, :confirmed_email_template, + :registration_subject, :accepted_subject, :rejected_subject, :confirmed_without_registration_subject + + def get_values(host, conference, person, event) + h = { + "email" => person.email, + "name" => person.public_name, + "conference" => conference.title, + "proposalslink" => Rails.application.routes.url_helpers.conference_proposal_index_url(conference.short_title, :host => host), + "registrationlink" => Rails.application.routes.url_helpers.register_conference_url(conference.short_title, :host => host) + } + + if !event.nil? + h["eventtitle"] = event.title + end + h + end + + def generate_registration_email(host, conference, person) + values = get_values(host, conference, person, nil) + template = self.registration_email_template + parse_template(template, values) + end + + + def generate_accepted_email(host, conference, person, event) + values = get_values(host, conference, person, event) + template = self.accepted_email_template + parse_template(template, values) + end + + def generate_rejected_email(host, conference, person, event) + values = get_values(host, conference, person, event) + template = self.rejected_email_template + parse_template(template, values) + end + + def confirmed_but_not_registered_email(host, conference, person, event) + values = get_values(host, conference, person, event) + template = self.confirmed_email_template + parse_template(template, values) + end + + def parse_template(text, values) + values.each do |key, value| + text = text.sub"{#{key}}", value + end + text + end +end \ No newline at end of file diff --git a/app/models/event.rb b/app/models/event.rb index 0182b197..0c0a3f69 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -88,12 +88,8 @@ class Event < ActiveRecord::Base end def process_acceptance(options) -# if options[:send_mail] - # self.event_people.presenter.each do |event_person| - # event_person.generate_token! - # SelectionNotification.acceptance_notification(event_person).deliver - # end - # end + #if options[:send_mail] + #end end diff --git a/app/views/admin/conference/_sidebar.html.haml b/app/views/admin/conference/_sidebar.html.haml index cb8b4397..02f08fc7 100644 --- a/app/views/admin/conference/_sidebar.html.haml +++ b/app/views/admin/conference/_sidebar.html.haml @@ -23,4 +23,8 @@ - if activated == "Event Types" %li.active= link_to "Event Types", "#" - else - %li= link_to "Event Types", admin_conference_eventtype_list_path(@conference.short_title) \ No newline at end of file + %li= link_to "Event Types", admin_conference_eventtype_list_path(@conference.short_title) + - if activated == "Emails" + %li.active= link_to "Emails", "#" + - else + %li= link_to "Emails", admin_conference_email_settings_path(@conference.short_title) diff --git a/app/views/admin/emails/show.html.haml b/app/views/admin/emails/show.html.haml new file mode 100644 index 00000000..ce434195 --- /dev/null +++ b/app/views/admin/emails/show.html.haml @@ -0,0 +1,50 @@ +.container-fluid + .row-fluid + .span3 + = render 'admin/conference/sidebar', :activated => "Emails" + .span9 + = link_to "Template Help", "#", :id => "template-help-link" + #template-help + Valid attributes: + %table.table + %tr + %td {email} + %td The user's email address + %tr + %td {name} + %td The user's full name + %tr + %td {conference} + %td The full conference title + %tr + %td {proposalslink} + %td A link to the user's proposal page + %tr + %td {registrationlink} + %td A link to the registration page + %tr + %td {eventtitle} + %td The title of an accepted or rejected proposal + + = semantic_form_for(@settings, :url => admin_conference_email_settings_path(@conference.short_title),:html => {:multipart => true}) do |f| + = f.input :send_on_registration, :label => false, :hint => "Send an email when the user registers for the conference?" + = f.input :registration_subject + = f.input :registration_email_template, :input_html => { :rows => 10, :cols => 20} + = f.input :send_on_accepted, :label => false, :hint => "Send an email when the proposal is accepted?" + = f.input :accepted_subject + = f.input :accepted_email_template, :input_html => { :rows => 10, :cols => 20 } + = f.input :send_on_rejected, :label => false, :hint => "Send an email when the proposal is rejected?" + = f.input :rejected_subject + = f.input :rejected_email_template, :input_html => { :rows => 10, :cols => 20 } + = f.input :send_on_confirmed_without_registration, :label => false, :hint => "Send an email when a user has a confirmed proposal, but isn't yet registered?" + = f.input :confirmed_without_registration_subject + = f.input :confirmed_email_template, :input_html => { :rows => 10, :cols => 20 } + = f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"} + +:javascript + $(document).ready( function() { + $("#template-help").hide(); + $("#template-help-link").click(function() { + $("#template-help").toggle(); + }); + }); \ No newline at end of file diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index e84add8b..f1580d24 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -22,21 +22,26 @@ = @event.state.humanize %ul.dropdown-menu - - if @event.transition_possible? :accept - %li= link_to "Accept event (no email)", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :accept, :send_mail => false), + - if event.transition_possible? :accept + %li= link_to "Accept event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :accept, :send_mail => false), :method => :put, :hint => "Accept this event without sending an automated email." - - if @event.transition_possible? :reject - %li= link_to "Reject event (no email)", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :reject, :send_mail => false), + %li= link_to "Accept event (WITH email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :accept, :send_mail => true), + :method => :put, :hint => "Accept this event and send an automated email." + - if event.transition_possible? :reject + %li= link_to "Reject event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :reject, :send_mail => false), :method => :put, :confirm => "Are you sure?", :hint => "Reject this event without sending an automated email." - - if @event.transition_possible? :start_review - %li= link_to "Start review", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :start_review), + %li= link_to "Reject event (WITH email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :reject, :send_mail => true), + :method => :put, :confirm => "Are you sure?", + :hint => "Reject this event and send an automated email." + - if event.transition_possible? :start_review + %li= link_to "Start review", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :start_review), :method => :put - - if @event.transition_possible? :confirm - %li= link_to "Confirm event", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :confirm), + - if event.transition_possible? :confirm + %li= link_to "Confirm event", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :confirm), :method => :put, :hint => "Confirm that the speaker(s) will be present and that the event will actually take place." - - if @event.transition_possible? :cancel - %li= link_to "Cancel event", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :cancel), + - if event.transition_possible? :cancel + %li= link_to "Cancel event", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :cancel), :method => :put, :hint => "Mark this event as cancelled. Usually this means that the speakers had to cancel their appearance." %tr %td diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 902f8d43..1f058d87 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -33,10 +33,15 @@ - if event.transition_possible? :accept %li= link_to "Accept event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :accept, :send_mail => false), :method => :put, :hint => "Accept this event without sending an automated email." + %li= link_to "Accept event (WITH email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :accept, :send_mail => true), + :method => :put, :hint => "Accept this event and send an automated email." - if event.transition_possible? :reject %li= link_to "Reject event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :reject, :send_mail => false), :method => :put, :confirm => "Are you sure?", :hint => "Reject this event without sending an automated email." + %li= link_to "Reject event (WITH email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :reject, :send_mail => true), + :method => :put, :confirm => "Are you sure?", + :hint => "Reject this event and send an automated email." - if event.transition_possible? :start_review %li= link_to "Start review", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :start_review), :method => :put diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d8114c2b..e5cbe8d9 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -4,7 +4,7 @@ Devise.setup do |config| # ==> Mailer Configuration # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class with default "from" parameter. - config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" + config.mailer_sender = "no-reply@conferences.opensuse.org" # Configure the class responsible to send e-mails. # config.mailer = "Devise::Mailer" @@ -229,4 +229,4 @@ Devise.setup do |config| # When using omniauth, Devise cannot automatically set Omniauth path, # so you need to do it manually. For the users scope, it would be: # config.omniauth_path_prefix = "/my_engine/users/auth" -end \ No newline at end of file +end diff --git a/config/routes.rb b/config/routes.rb index 7bee72ea..2c98c58d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,6 +10,8 @@ Osem::Application.routes.draw do get "/schedule" => "schedule#show" put "/schedule" => "schedule#update" get "/registrations" => "registrations#show" + get "/emailsettings" => "emails#show", :as => "email_settings" + put "/emailsettings" => "emails#update", :as => "email_settings" get "/venue" => "venue#show", :as => "venue_info" put "/venue" => "venue#update", :as => "venue_update" get "/rooms" => "rooms#show", :as => "rooms_list" diff --git a/db/migrate/20130113105652_create_email_table.rb b/db/migrate/20130113105652_create_email_table.rb new file mode 100644 index 00000000..ba6bf60e --- /dev/null +++ b/db/migrate/20130113105652_create_email_table.rb @@ -0,0 +1,21 @@ +class CreateEmailTable < ActiveRecord::Migration + def up + create_table :email_settings do |t| + t.references :conference + t.boolean :send_on_registration, :default => true + t.boolean :send_on_accepted, :default => true + t.boolean :send_on_rejected, :default => true + t.boolean :send_on_confirmed_without_registration, :default => true + t.text :registration_email_template + t.text :accepted_email_template + t.text :rejected_email_template + t.text :confirmed_email_template + t.timestamps + end + + end + + def down + drop_table :email_settings + end +end diff --git a/db/migrate/20130113132225_add_subjects_to_email_settings.rb b/db/migrate/20130113132225_add_subjects_to_email_settings.rb new file mode 100644 index 00000000..9adb821c --- /dev/null +++ b/db/migrate/20130113132225_add_subjects_to_email_settings.rb @@ -0,0 +1,8 @@ +class AddSubjectsToEmailSettings < ActiveRecord::Migration + def change + add_column :email_settings, :registration_subject, :string + add_column :email_settings, :accepted_subject, :string + add_column :email_settings, :rejected_subject, :string + add_column :email_settings, :confirmed_without_registration_subject, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c40edbd1..27e2f103 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130107114930) do +ActiveRecord::Schema.define(:version => 20130113132225) do create_table "call_for_papers", :force => true do |t| t.date "start_date", :null => false @@ -58,6 +58,24 @@ ActiveRecord::Schema.define(:version => 20130107114930) do t.date "registration_end_date" end + create_table "email_settings", :force => true do |t| + t.integer "conference_id" + t.boolean "send_on_registration", :default => true + t.boolean "send_on_accepted", :default => true + t.boolean "send_on_rejected", :default => true + t.boolean "send_on_confirmed_without_registration", :default => true + t.text "registration_email_template" + t.text "accepted_email_template" + t.text "rejected_email_template" + t.text "confirmed_email_template" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "registration_subject" + t.string "accepted_subject" + t.string "rejected_subject" + t.string "confirmed_without_registration_subject" + end + create_table "event_attachments", :force => true do |t| t.integer "event_id" t.string "title", :null => false diff --git a/test/functional/mailbot_test.rb b/test/functional/mailbot_test.rb new file mode 100644 index 00000000..94e659b5 --- /dev/null +++ b/test/functional/mailbot_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class MailbotTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end