forked from railsbridge/bridge_troll
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Organizer can email individual and groups of attendees
* feature tests for emailing individuals and groups from the organizer console * refactor of the EventEmailAddresser JS * select2 recipient multiselect on the event email view * presenter objects for EventEmail and PastEventEmails * refactors on Events::EmailsController and spec
- Loading branch information
Rae Bonfanti
committed
Oct 14, 2015
1 parent
b70042d
commit 29340ed
Showing
14 changed files
with
494 additions
and
314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
Bridgetroll.EventEmailAddresser = { | ||
$recipientMultiSelect: -> | ||
$('select#recipients') | ||
|
||
init: -> | ||
this.$recipientMultiSelect().change => this.recalculateRecipients() | ||
$('.cc-organizers').change => this.toggleOrganizerCopy() | ||
|
||
this.initRecipientSelect(); | ||
this.recalculateRecipients(); | ||
this.toggleOrganizerCopy(); | ||
|
||
initRecipientSelect: -> | ||
$recipientMultiSelect = this.$recipientMultiSelect() | ||
$recipientMultiSelect.select2({ | ||
placeholder: 'Select recipients', | ||
width: '100%' | ||
}) | ||
|
||
$('#recipients-set-to-all').on 'click', (e) -> | ||
e.preventDefault() | ||
recipientIds = _.map attendees, (attendee) -> | ||
attendee.user_id | ||
$recipientMultiSelect.val(recipientIds).trigger 'change' | ||
|
||
$('#recipients-add-volunteers').on 'click', (e) => | ||
e.preventDefault() | ||
roleId = $(e.target).data('role-id') | ||
this.addRecipientGroup(roleId) | ||
|
||
$('#recipients-open-students-dropdown').on 'click', (e) -> | ||
e.preventDefault() | ||
$(this).toggleClass('open') | ||
|
||
$('#recipients-add-accepted-students').on 'click', (e) => | ||
e.preventDefault() | ||
roleId = $(e.target).data('role-id') | ||
this.addRecipientGroup(roleId, 'accepted') | ||
|
||
$('#recipients-add-waitlisted-students').on 'click', (e) => | ||
e.preventDefault() | ||
roleId = $(e.target).data('role-id') | ||
this.addRecipientGroup(roleId, 'waitlisted') | ||
|
||
$('#recipients-add-all-students').on 'click', (e) => | ||
e.preventDefault() | ||
roleId = $(e.target).data('role-id') | ||
this.addRecipientGroup(roleId) | ||
|
||
$('#recipients-remove-dropdown').on 'click', (e) -> | ||
e.preventDefault() | ||
$(this).toggleClass('open') | ||
|
||
$('#recipients-remove-no-shows').on 'click', (e) => | ||
e.preventDefault() | ||
this.removeNoShows() | ||
|
||
$('#recipients-remove-all').on 'click', (e) -> | ||
e.preventDefault() | ||
$recipientMultiSelect.val(null).trigger 'change' | ||
|
||
addRecipientGroup: (roleId, roleState) -> | ||
recipientGroup = _.filter attendees, (attendee) -> | ||
attendee.role_id == roleId | ||
|
||
if (roleState == 'accepted') | ||
recipientGroup = _.filter recipientGroup, (recipient) -> | ||
!recipient.waitlisted | ||
else if (roleState == 'waitlisted') | ||
recipientGroup = _.filter recipientGroup, (recipient) -> | ||
recipient.waitlisted | ||
|
||
recipientIds = _.map recipientGroup, (recipient) -> | ||
recipient.user_id | ||
|
||
this.$recipientMultiSelect().val((i, currentVal) -> | ||
_.union(currentVal, recipientIds) | ||
).trigger 'change' | ||
|
||
removeNoShows: -> | ||
if this.$recipientMultiSelect().val() | ||
currentRecipients = _.map this.$recipientMultiSelect().val(), (recipientId) -> | ||
_.find attendees, (attendee) -> attendee.user_id == recipientId | ||
|
||
recipientsWhoAttended = _.filter currentRecipients, (recipient) -> | ||
recipient.checkins_count > 0 | ||
|
||
recipientIds = _.map recipientsWhoAttended, (recipient) -> | ||
recipient.user_id | ||
|
||
this.$recipientMultiSelect().val(recipientIds).trigger 'change' | ||
|
||
recalculateRecipients: -> | ||
recipients = this.$recipientMultiSelect().val() | ||
count = if recipients then recipients.length else 0 | ||
|
||
noun = if (count == 1) then "person." else "people." | ||
$('.num').html("<b>#{count}</b> #{noun}") | ||
|
||
toggleOrganizerCopy: () -> | ||
checked = $('.cc-organizers').prop('checked') | ||
|
||
if (checked) | ||
$('.organizer-copy').show() | ||
else | ||
$('.organizer-copy').hide() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,62 @@ | ||
class Events::EmailsController < ApplicationController | ||
before_action :authenticate_user!, :validate_organizer!, :find_event | ||
module Events | ||
class EmailsController < ApplicationController | ||
before_action :authenticate_user!, :validate_organizer!, :find_event | ||
|
||
def new | ||
new_email = @event.event_emails.build(attendee_group: 'All') | ||
@email = EventEmailPresenter.new(new_email) | ||
@past_emails = PastEventEmailsPresenter.new(@event) | ||
end | ||
|
||
def new | ||
@email = @event.event_emails.build( | ||
attendee_group: 'All', | ||
) | ||
assign_ivars | ||
end | ||
def create | ||
recipient_ids = email_params[:recipients] ? email_params[:recipients].map(&:to_i) : [] | ||
recipient_rsvps = @event.rsvps.where(user_id: recipient_ids).includes(:user) | ||
|
||
cc_recipients = email_params[:cc_organizers] ? @event.organizers.map(&:email) : [current_user.email] | ||
|
||
@email = @event.event_emails.build( | ||
subject: email_params[:subject], | ||
body: email_params[:body], | ||
sender: current_user, | ||
recipient_rsvp_ids: recipient_rsvps.map(&:id), | ||
attendee_group: email_params[:attendee_group].to_i | ||
) | ||
|
||
unless @email.valid? | ||
@email = EventEmailPresenter.new(@email) | ||
@past_emails = PastEventEmailsPresenter.new(@event) | ||
flash[:alert] = "We were unable to send your email." | ||
return render :new | ||
end | ||
|
||
def create | ||
role_ids = if email_params[:attendee_group] == 'All' | ||
Role.attendee_role_ids | ||
else | ||
email_params[:attendee_group] | ||
end | ||
recipient_rsvps = @event.rsvps.where(role_id: role_ids).includes(:user) | ||
EventMailer.from_organizer( | ||
sender: current_user, | ||
recipients: recipient_rsvps.map { |rsvp| rsvp.user.email }, | ||
cc: cc_recipients, | ||
subject: email_params[:subject], | ||
body: email_params[:body], | ||
event: @event | ||
).deliver_now | ||
|
||
unless email_params[:include_waitlisted] | ||
recipient_rsvps = recipient_rsvps.confirmed | ||
end | ||
@email.save! | ||
|
||
if email_params[:only_checked_in] | ||
recipient_rsvps = recipient_rsvps.where('checkins_count > 0') | ||
redirect_to event_organizer_tools_path(@event), notice: <<-EOT | ||
Your email has been sent. Woo! | ||
EOT | ||
end | ||
|
||
if email_params[:cc_organizers] | ||
cc_recipients = @event.organizers.map(&:email) - [current_user.email] | ||
def show | ||
@email = @event.event_emails.find(params[:id]) | ||
end | ||
|
||
@email = @event.event_emails.build( | ||
subject: email_params[:subject], | ||
body: email_params[:body], | ||
sender: current_user, | ||
recipient_rsvp_ids: recipient_rsvps.map(&:id), | ||
attendee_group: email_params[:attendee_group].to_i, | ||
include_waitlisted: email_params[:include_waitlisted] | ||
) | ||
private | ||
|
||
unless @email.valid? | ||
assign_ivars | ||
return render :new | ||
def email_params | ||
params.require(:event_email) | ||
end | ||
|
||
EventMailer.from_organizer( | ||
sender: current_user, | ||
recipients: recipient_rsvps.map { |rsvp| rsvp.user.email } + [current_user.email], | ||
cc: cc_recipients, | ||
subject: email_params[:subject], | ||
body: email_params[:body], | ||
event: @event | ||
).deliver_now | ||
|
||
@email.save! | ||
|
||
redirect_to event_organizer_tools_path(@event), notice: <<-EOT | ||
Your mail has been sent. Woo! | ||
You will also get a copy of the email in your inbox to prove that email sending is working. | ||
EOT | ||
end | ||
|
||
def show | ||
@email = @event.event_emails.find(params[:id]) | ||
end | ||
|
||
private | ||
|
||
def email_params | ||
params.require(:event_email) | ||
end | ||
|
||
def find_event | ||
@event = Event.find_by_id(params[:event_id]) | ||
end | ||
|
||
def assign_ivars | ||
@rsvps = @event.rsvps.where(role_id: Role.attendee_role_ids).includes(:user) | ||
@emails = @event.event_emails.order(:created_at) | ||
|
||
@email_recipients = {} | ||
@emails.each do |email| | ||
@email_recipients[email.id] = { | ||
total: email.recipient_rsvps.length, | ||
volunteers: 0, | ||
students: 0 | ||
} | ||
email.recipient_rsvps.each do |rsvp| | ||
if rsvp.role_volunteer? | ||
@email_recipients[email.id][:volunteers] += 1 | ||
end | ||
if rsvp.role_student? | ||
@email_recipients[email.id][:students] += 1 | ||
end | ||
end | ||
def find_event | ||
@event = Event.find_by_id(params[:event_id]) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
class EventEmailPresenter | ||
attr_reader :event_email | ||
|
||
delegate :model_name, :to_key, :to_model, :persisted?, | ||
:errors, :attendee_group, :include_waitlisted, :only_checked_in, | ||
:cc_organizers, :subject, :body, to: :event_email | ||
|
||
def initialize(event_email) | ||
@event_email = event_email | ||
end | ||
|
||
def rsvps | ||
@rsvps ||= event.rsvps.where(role_id: Role.attendee_role_ids).includes(:user) | ||
end | ||
|
||
def volunteers_rsvps | ||
rsvps.where(role_id: Role::VOLUNTEER.id) | ||
end | ||
|
||
def students_accepted_rsvps | ||
rsvps.where(role_id: Role::STUDENT.id).confirmed | ||
end | ||
|
||
def students_waitlisted_rsvps | ||
rsvps.where(role_id: Role::STUDENT.id).where.not("waitlist_position IS NULL") | ||
end | ||
|
||
def event | ||
event_email.event | ||
end | ||
end |
Oops, something went wrong.