18F/identity-idp

View on GitHub
app/jobs/reports/fraud_metrics_report.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

require 'csv'
require 'reporting/fraud_metrics_lg99_report'

module Reports
  class FraudMetricsReport < BaseReport
    REPORT_NAME = 'fraud-metrics-report'

    attr_reader :report_date

    def initialize(report_date = nil, *args, **rest)
      @report_date = report_date
      super(*args, **rest)
    end

    def perform(date = Time.zone.yesterday.end_of_day)
      @report_date = date

      email_addresses = emails.select(&:present?)
      if email_addresses.empty?
        Rails.logger.warn 'No email addresses received - Fraud Metrics Report NOT SENT'
        return false
      end

      reports.each do |report|
        upload_to_s3(report.table, report_name: report.filename)
      end

      ReportMailer.tables_report(
        email: email_addresses,
        subject: "Fraud Metrics Report - #{report_date.to_date}",
        reports: reports,
        message: preamble,
        attachment_format: :xlsx,
      ).deliver_now
    end

    # Explanatory text to go before the report in the email
    # @return [String]
    def preamble(env: Identity::Hostdata.env || 'local')
      ERB.new(<<~ERB).result(binding).html_safe # rubocop:disable Rails/OutputSafety
        <% if env != 'prod' %>
          <div class="usa-alert usa-alert--info usa-alert--email">
            <div class="usa-alert__body">
              <%#
                NOTE: our AlertComponent doesn't support heading content like this uses,
                so for a one-off outside the Rails pipeline it was easier to inline the HTML here.
              %>
              <h2 class="usa-alert__heading">
                Non-Production Report
              </h2>
              <p class="usa-alert__text">
                This was generated in the <strong><%= env %></strong> environment.
              </p>
            </div>
          </div>
        <% end %>
      ERB
    end

    def reports
      @reports ||= fraud_metrics_lg99_report.as_emailable_reports
    end

    def fraud_metrics_lg99_report
      @fraud_metrics_lg99_report ||= Reporting::FraudMetricsLg99Report.new(
        time_range: report_date.all_month,
      )
    end

    def emails
      emails = [*IdentityConfig.store.team_daily_fraud_metrics_emails]
      if report_date.next_day.day == 1
        emails += IdentityConfig.store.team_monthly_fraud_metrics_emails
      end
      emails
    end

    def upload_to_s3(report_body, report_name: nil)
      _latest, path = generate_s3_paths(REPORT_NAME, 'csv', subname: report_name, now: report_date)

      if bucket_name.present?
        upload_file_to_s3_bucket(
          path: path,
          body: csv_file(report_body),
          content_type: 'text/csv',
          bucket: bucket_name,
        )
      end
    end

    def csv_file(report_array)
      CSV.generate do |csv|
        report_array.each do |row|
          csv << row
        end
      end
    end
  end
end