diff --git a/app/jobs/reports/authentication_report.rb b/app/jobs/reports/authentication_report.rb index efd31063938..4c06d40ae65 100644 --- a/app/jobs/reports/authentication_report.rb +++ b/app/jobs/reports/authentication_report.rb @@ -14,14 +14,14 @@ def perform(report_date) subject = "Weekly Authentication Report - #{report_date}" report_configs.each do |report_hash| - tables = weekly_authentication_report_tables(report_hash['issuers']) + reports = weekly_authentication_emailable_reports(report_hash['issuers']) report_hash['emails'].each do |email| ReportMailer.tables_report( email:, subject:, message:, - tables:, + reports:, attachment_format: :csv, ).deliver_now end @@ -30,11 +30,11 @@ def perform(report_date) private - def weekly_authentication_report_tables(issuers) + def weekly_authentication_emailable_reports(issuers) Reporting::AuthenticationReport.new( issuers:, time_range: report_date.all_week, - ).as_tables_with_options + ).as_emailable_reports end def report_configs diff --git a/app/jobs/reports/monthly_key_metrics_report.rb b/app/jobs/reports/monthly_key_metrics_report.rb index 25a0a8bda48..a2aee4dbaf4 100644 --- a/app/jobs/reports/monthly_key_metrics_report.rb +++ b/app/jobs/reports/monthly_key_metrics_report.rb @@ -43,11 +43,7 @@ def perform(date = Time.zone.today) ] reports.each do |report| - upload_to_s3(report.table, report_name: report.csv_name) - end - - email_tables = reports.map do |report| - [report.email_options, *report.table] + upload_to_s3(report.table, report_name: report.filename) end email_message = "Report: #{REPORT_NAME} #{date}" @@ -56,7 +52,7 @@ def perform(date = Time.zone.today) email: email_addresses, subject: "Monthly Key Metrics Report - #{date}", message: email_message, - tables: email_tables, + reports: reports, attachment_format: :xlsx, ).deliver_now end diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb index 46bff5aa33f..d9dd252ec48 100644 --- a/app/mailers/report_mailer.rb +++ b/app/mailers/report_mailer.rb @@ -40,7 +40,7 @@ def warn_error(email:, error:, env: Rails.env) # @param [String] subject # @param [String] env name of current deploy environment # @param [:csv,:xlsx] attachment_format - # @param [Array>>] tables + # @param [Array] reports # an array of tables (which are arrays of rows (arrays of strings)) # each table can have a first "row" that is a hash with options # @option opts [Boolean] :float_as_percent whether or not to render floats as percents @@ -49,40 +49,34 @@ def tables_report( email:, subject:, message:, - tables:, + reports:, attachment_format:, env: Identity::Hostdata.env || 'local' ) @message = message - @tables = tables.map(&:dup).each_with_index.map do |table, index| - options = table.first.is_a?(Hash) ? table.shift : {} - - options[:title] ||= "Table #{index + 1}" - - [options, *table] + @reports = reports.map(&:dup).each_with_index do |report, index| + report.title ||= "Table #{index + 1}" end case attachment_format when :csv - @tables.each do |options_and_table| - options, *table = options_and_table - - title = "#{options[:title].parameterize}.csv" + @reports.each do |report| + filename = "#{report.filename || report.title.parameterize}.csv" - attachments[title] = CSV.generate do |csv| - table.each do |row| + attachments[filename] = CSV.generate do |csv| + report.table.each do |row| csv << row end end end when :xlsx Axlsx::Package.new do |package| - @tables.each do |options_and_table| - options, *table = options_and_table + @reports.each do |report| + name = report.title.byteslice(0...31) - package.workbook.add_worksheet(name: options[:title].byteslice(0...31)) do |sheet| - table.each do |row| + package.workbook.add_worksheet(name: name) do |sheet| + report.table.each do |row| sheet.add_row(row) end end diff --git a/app/services/reporting/account_deletion_rate_report.rb b/app/services/reporting/account_deletion_rate_report.rb index f658ee35e29..79e02a4be55 100644 --- a/app/services/reporting/account_deletion_rate_report.rb +++ b/app/services/reporting/account_deletion_rate_report.rb @@ -15,13 +15,11 @@ def account_deletion_report def account_deletion_emailable_report EmailableReport.new( - email_options: { - title: 'Account deletion rate (last 30 days)', - float_as_percent: true, - precision: 4, - }, + title: 'Account deletion rate (last 30 days)', + float_as_percent: true, + precision: 4, table: account_deletion_report, - csv_name: 'account_deletion_rate', + filename: 'account_deletion_rate', ) end diff --git a/app/services/reporting/account_reuse_and_total_identities_report.rb b/app/services/reporting/account_reuse_and_total_identities_report.rb index 10c8fab9a00..7dc4dc909bb 100644 --- a/app/services/reporting/account_reuse_and_total_identities_report.rb +++ b/app/services/reporting/account_reuse_and_total_identities_report.rb @@ -30,12 +30,10 @@ def account_reuse_report def account_reuse_emailable_report EmailableReport.new( - email_options: { - title: "IDV app reuse rate #{stats_month}", - float_as_percent: true, - precision: 4, - }, - csv_name: 'account_reuse', + title: "IDV app reuse rate #{stats_month}", + float_as_percent: true, + precision: 4, + filename: 'account_reuse', table: account_reuse_report, ) end @@ -49,9 +47,9 @@ def total_identities_report def total_identities_emailable_report EmailableReport.new( - email_options: { title: 'Total proofed identities' }, + title: 'Total proofed identities', table: total_identities_report, - csv_name: 'total_profiles', + filename: 'total_profiles', ) end diff --git a/app/services/reporting/emailable_report.rb b/app/services/reporting/emailable_report.rb index 0693127f4c3..de9eb62f538 100644 --- a/app/services/reporting/emailable_report.rb +++ b/app/services/reporting/emailable_report.rb @@ -1,3 +1,23 @@ module Reporting - EmailableReport = Struct.new(:email_options, :table, :csv_name) + # Represents tabular data and how to render the table in an email body and + # name it as an attachment + # @!attribute [rw] table + # @return [Array>] + # @!attribute [rw] filename + # @return [String] filename for attachment + # @!attribute [rw] title + # @return [String] title for table in email body + # @!attribute [rw] float_as_percent + # @return [Boolean] whether or not floating point values should be rendered as percents + # @!attribute [rw] precision + # @return [Integer] number of digits of precision for rendering as percent + EmailableReport = Struct.new( + :table, + :filename, + :title, + :float_as_percent, + :precision, + ) do + alias_method :float_as_percent?, :float_as_percent + end end diff --git a/app/services/reporting/monthly_active_users_count_report.rb b/app/services/reporting/monthly_active_users_count_report.rb index 12e652834b1..813aa4c0185 100644 --- a/app/services/reporting/monthly_active_users_count_report.rb +++ b/app/services/reporting/monthly_active_users_count_report.rb @@ -17,11 +17,9 @@ def monthly_active_users_count_report def monthly_active_users_count_emailable_report EmailableReport.new( - email_options: { - title: "#{report_month_year} Active Users", - }, + title: "#{report_month_year} Active Users", table: monthly_active_users_count_report, - csv_name: 'monthly_active_users_count', + filename: 'monthly_active_users_count', ) end diff --git a/app/services/reporting/total_user_count_report.rb b/app/services/reporting/total_user_count_report.rb index c5ffa900499..4f3089a2ca5 100644 --- a/app/services/reporting/total_user_count_report.rb +++ b/app/services/reporting/total_user_count_report.rb @@ -17,9 +17,9 @@ def total_user_count_report def total_user_count_emailable_report EmailableReport.new( - email_options: { title: 'Total user count (all-time)' }, + title: 'Total user count (all-time)', table: total_user_count_report, - csv_name: 'total_user_count', + filename: 'total_user_count', ) end diff --git a/app/views/report_mailer/tables_report.html.erb b/app/views/report_mailer/tables_report.html.erb index 49e24b2b06b..3645d225f6f 100644 --- a/app/views/report_mailer/tables_report.html.erb +++ b/app/views/report_mailer/tables_report.html.erb @@ -1,12 +1,11 @@ <%# - @message: text to put in the beginning of the email -- @tables: an array of tables, expects first "row" to be an options hash +- @reports: an array of EmailableReport %> <%= @message %>
-<% @tables.each do |table| %> - <% options, header, *rows = table %> - -

<%= options[:title] %>

+<% @reports.each do |report| %> + <% header, *rows = report.table %> +

<%= report.title %>

@@ -21,8 +20,8 @@ <% row.each do |cell| %>
> - <% if cell.is_a?(Float) && options[:float_as_percent] %> - <%= number_to_percentage(cell * 100, precision: options[:precision] || 2) %> + <% if cell.is_a?(Float) && report.float_as_percent? %> + <%= number_to_percentage(cell * 100, precision: report.precision || 2) %> <% else %> <%= number_with_delimiter(cell) %> <% end %> diff --git a/lib/reporting/authentication_report.rb b/lib/reporting/authentication_report.rb index 8b50947e271..19dbebb3b77 100644 --- a/lib/reporting/authentication_report.rb +++ b/lib/reporting/authentication_report.rb @@ -61,10 +61,16 @@ def as_tables ] end - def as_tables_with_options + def as_emailable_reports [ - [{ title: 'Overview' }, *overview_table], - [{ title: 'Authentication Funnel Metrics' }, *funnel_metrics_table], + Reporting::EmailableReport.new( + title: 'Overview', + table: overview_table, + ), + Reporting::EmailableReport.new( + title: 'Authentication Funnel Metrics', + table: funnel_metrics_table, + ), ] end diff --git a/lib/reporting/monthly_proofing_report.rb b/lib/reporting/monthly_proofing_report.rb index e2df9c57a4c..fefebbcd7d4 100644 --- a/lib/reporting/monthly_proofing_report.rb +++ b/lib/reporting/monthly_proofing_report.rb @@ -29,7 +29,7 @@ def self.all_events end # @param [Array] issuers - # @param [Range