Skip to content

Commit

Permalink
feat: Implement weekly email report
Browse files Browse the repository at this point in the history
Fixes #80
  • Loading branch information
sman591 committed May 27, 2019
1 parent 5401144 commit c4df212
Show file tree
Hide file tree
Showing 30 changed files with 600 additions and 38 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ gem 'validate_url'

# Background job processing
gem 'sidekiq', '< 6'
gem 'sidekiq-cron', '~> 1.1'

# Misc support gems
gem 'rails-settings-cached', '~> 0.7.2'
Expand Down
10 changes: 10 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ GEM
errbase (0.1.1)
erubi (1.8.0)
erubis (2.7.0)
et-orbi (1.2.1)
tzinfo
excon (0.64.0)
execjs (2.7.0)
factory_bot (5.0.2)
Expand All @@ -157,6 +159,9 @@ GEM
font-awesome-rails (4.7.0.5)
railties (>= 3.2, < 6.1)
formatador (0.2.5)
fugit (1.2.1)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
groupdate (4.1.1)
Expand Down Expand Up @@ -274,6 +279,7 @@ GEM
method_source (~> 0.9.0)
public_suffix (3.0.3)
puma (3.12.1)
raabro (1.1.6)
rack (2.0.7)
rack-protection (2.0.5)
rack
Expand Down Expand Up @@ -377,6 +383,9 @@ GEM
rack (>= 1.5.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
sidekiq-cron (1.1.0)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
simple_form (4.1.0)
actionpack (>= 5.0)
activemodel (>= 5.0)
Expand Down Expand Up @@ -496,6 +505,7 @@ DEPENDENCIES
shoulda (~> 3.5)
shoulda-matchers (~> 2.0)
sidekiq (< 6)
sidekiq-cron (~> 1.1)
simple_form
simple_spark
simplecov
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/manage/lib/setupDataTables.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var setupDataTables = function() {
{ orderable: true, data: "email" },
{ orderable: true, data: "role" },
{ orderable: true, data: "active" },
{ orderable: true, data: "receive_weekly_report" },
{ orderable: true, data: "created_at" }
]
});
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/manage/admins_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def destroy

def user_params
params.require(:user).permit(
:email, :password, :password_confirmation, :remember_me, :role, :is_active
:email, :password, :password_confirmation, :remember_me, :role, :is_active, :receive_weekly_report
)
end

Expand Down
2 changes: 2 additions & 0 deletions app/datatables/admin_datatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def view_columns
email: { source: "User.email" },
role: { source: "User.role", searchable: false },
active: { source: "User.is_active", searchable: false },
receive_weekly_report: { source: "User.receive_weekly_report", searchable: false },
created_at: { source: "User.created_at", searchable: false },
}
end
Expand All @@ -20,6 +21,7 @@ def data
email: link_to(bold(record.email), manage_admin_path(record)),
role: record.role.titleize,
active: record.is_active ? '<span class="badge badge-secondary">Active</span>'.html_safe : '<span class="badge badge-danger">Inactive<span>'.html_safe,
receive_weekly_report: record.receive_weekly_report ? '<span class="badge badge-success">Yes</span>'.html_safe : '<span class="badge badge-secondary">No<span>'.html_safe,
created_at: display_datetime(record.created_at),
}
end
Expand Down
11 changes: 11 additions & 0 deletions app/jobs/admin_weekly_report_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AdminWeeklyReportJob < ApplicationJob
queue_as :default

def perform
# Queue all eligible users and let the is_active (or other) logic determine if they should really receive it
users = User.where(receive_weekly_report: true)
users.each do |user|
AdminMailer.weekly_report(user.id).deliver_later
end
end
end
53 changes: 53 additions & 0 deletions app/mailers/admin_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class AdminMailer < ApplicationMailer
include Roadie::Rails::Automatic
add_template_helper(HackathonManagerHelper)

layout "admin_mailer"

def weekly_report(user_id)
# Don't send emails more than 7 days after event starts
stop_date = Date.parse(HackathonConfig["event_start_date"]) + 7.days
return if Date.today > stop_date

@user = User.find_by_id(user_id)

return unless @user.safe_receive_weekly_report

@period_start = 7.days.ago.at_beginning_of_day
@period_end = 1.day.ago.at_end_of_day
@period = @period_start..@period_end

@applications = report_metric(Questionnaire, :created_at)
@rsvp_confirmed = report_metric(Questionnaire.where(acc_status: "rsvp_confirmed"), :acc_status_date)
@rsvp_denied = report_metric(Questionnaire.where(acc_status: "rsvp_denied"), :acc_status_date)

@bus_metrics = BusList.all.map do |bus_list|
{
name: bus_list.name,
total: bus_list.passengers.count,
}
end

@messages_sent = Message.bulk.where(delivered_at: @period).count

@new_admissions_metrics = [@applications, @rsvp_confirmed, @rsvp_denied].any? { |x| x[:new].positive? }
@new_communication_metrics = @messages_sent.positive?

# Don't send email if no new activity
return if !@new_admissions_metrics && !@new_bus_list_metrics && !@new_communication_metrics

mail(
to: pretty_email(@user.full_name, @user.email),
subject: "Your Weekly Report",
)
end

private

def report_metric(query_base, new_query_field)
{
new: query_base.where(new_query_field => @period).count,
total: query_base.count,
}
end
end
10 changes: 8 additions & 2 deletions app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
class ApplicationMailer < ActionMailer::Base
default from: -> { HackathonConfig['email_from'] }
layout 'mailer'
default from: -> { HackathonConfig["email_from"] }
layout "mailer"

def pretty_email(name, email)
return email if name.blank?

"\"#{name}\" <#{email}>"
end
end
4 changes: 4 additions & 0 deletions app/mailers/mail_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ def bulk_message_email
message = Message.first
Mailer.bulk_message_email(message, User.first.id)
end

def admin_weekly_report
AdminMailer.weekly_report(User.first.id)
end
end
end
20 changes: 5 additions & 15 deletions app/mailers/mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,29 @@ class Mailer < ApplicationMailer
include Roadie::Rails::Automatic
add_template_helper(HackathonManagerHelper)

default from: -> { HackathonConfig['email_from'] }

def bulk_message_email(message_id, user_id, message = nil, use_examples = false)
@message = message || Message.find_by_id(message_id)
@user = User.find_by_id(user_id)
@message = message || Message.find_by_id(message_id)
@user = User.find_by_id(user_id)
@use_examples = use_examples
return if @user.blank? || @message.blank?

mail(
to: pretty_email(@user.full_name, @user.email),
subject: @message.subject
subject: @message.subject,
)
end

def incomplete_reminder_email(user_id)
@user = User.find_by_id(user_id)
return if @user.blank? || @user.admin? || @user.questionnaire || Time.now.to_date > Date.parse(HackathonConfig['last_day_to_apply'])
return if @user.blank? || @user.admin? || @user.questionnaire || Time.now.to_date > Date.parse(HackathonConfig["last_day_to_apply"])

Message.queue_for_trigger("user.24hr_incomplete_application", @user.id)
end

rescue_from SparkPostRails::DeliveryException do |e|
error_codes_to_not_retry = [
"1902" # Generation rejection
"1902", # Generation rejection
]
raise e unless e.blank? || error_codes_to_not_retry.include?(e.service_code)
end

private

def pretty_email(name, email)
return email if name.blank?

"\"#{name}\" <#{email}>"
end
end
5 changes: 5 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def email=(value)
super value.try(:downcase)
end

def safe_receive_weekly_report
return false unless is_active
receive_weekly_report
end

def first_name
return "" if questionnaire.blank?
questionnaire.first_name
Expand Down
50 changes: 50 additions & 0 deletions app/views/admin_mailer/weekly_report.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
%h1 Your Weekly Report

%p
For the week of
%strong
= @period_start.strftime("%A, %B %-d")
&ndash;
= @period_end.strftime("%A, %B %-d")

%h2 Admissions

- if @new_admissions_metrics
%p
📥&nbsp;
%strong= @applications[:new]
new applications (#{@applications[:total]} total)

%p
✅&nbsp;
%strong= @rsvp_confirmed[:new]
new RSVP confirmations (#{@rsvp_confirmed[:total]} total)

%p
❌&nbsp;
%strong= @rsvp_denied[:new]
new RSVP denials (#{@rsvp_denied[:total]} total)
- else
%p
%em No change from last week

%h2 Transportation

- @bus_metrics.each do |bus_metric|
%p
%u= bus_metric[:name]
%br
🚌&nbsp;
%strong= bus_metric[:total]
total passengers

%h2 Communication

- if @new_communication_metrics
%p
✉️&nbsp;
%strong= @messages_sent
new bulk emails sent out
- else
%p
%em No new bulk emails sent
Loading

0 comments on commit c4df212

Please sign in to comment.