Skip to content

Commit

Permalink
987: Adds Caseworker PDF view (#219)
Browse files Browse the repository at this point in the history
* WIP

* Passing rspec

* Remove vestigial

* Map in all found identities

* Use locals

* Check for correct job

* Add supported for identity job
  • Loading branch information
allthesignals authored Aug 26, 2024
1 parent ea13e0a commit ee155ea
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 14 deletions.
7 changes: 7 additions & 0 deletions app/app/components/pinwheel_data_point_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,11 @@ def employer_address(address)
value: address
}
end

def client_full_name(full_name)
{
label: I18n.t("cbv.summaries.show.pdf.caseworker.client_full_name"),
value: full_name
}
end
end
6 changes: 4 additions & 2 deletions app/app/controllers/cbv/summaries_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Cbv::SummariesController < Cbv::BaseController
before_action :set_employments, only: %i[show update]
before_action :set_incomes, only: %i[show update]
before_action :set_payments, only: %i[show update]
before_action :set_identities, only: %i[show update]
skip_before_action :ensure_cbv_flow_not_yet_complete, if: -> { params[:format] == "pdf" }

def show
Expand All @@ -22,7 +23,7 @@ def show
cbv_flow_id: @cbv_flow.id
})

render pdf: "#{@cbv_flow.id}", layout: "pdf"
render pdf: "#{@cbv_flow.id}", layout: "pdf", locals: { is_caseworker: false }
end
end
end
Expand Down Expand Up @@ -70,7 +71,8 @@ def transmit_to_caseworker
cbv_flow: @cbv_flow,
payments: @payments,
employments: @employments,
incomes: @incomes
incomes: @incomes,
identities: @identities
).summary_email.deliver_now
@cbv_flow.touch(:transmitted_at)
end
Expand Down
22 changes: 19 additions & 3 deletions app/app/controllers/concerns/cbv/reports_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Cbv::ReportsHelper
include Cbv::PaymentsHelper

def payments_grouped_by_employer
summarize_by_employer(@payments, @employments, @incomes)
summarize_by_employer(@payments, @employments, @incomes, @identities)
end

def set_employments(account_id = nil)
Expand All @@ -15,11 +15,15 @@ def set_incomes(account_id = nil)
@incomes = account_id.nil? ? fetch_incomes : fetch_incomes_for_account_id(account_id)
end

def set_identities(account_id = nil)
@identities = account_id.nil? ? fetch_identities : fetch_identity_for_account_id(account_id)
end

def total_gross_income
@payments.reduce(0) { |sum, payment| sum + payment[:gross_pay_amount] }
end

def summarize_by_employer(payments, employments, incomes)
def summarize_by_employer(payments, employments, incomes, identities)
payments
.each_with_object({}) do |payment, hash|
account_id = payment[:account_id]
Expand All @@ -33,7 +37,8 @@ def summarize_by_employer(payments, employments, incomes)
has_income_data: has_income_data,
has_employment_data: has_employment_data,
income: has_income_data && incomes.find { |income| income["account_id"] == account_id },
employment: has_employment_data && employments.find { |employment| employment["account_id"] == account_id }
employment: has_employment_data && employments.find { |employment| employment["account_id"] == account_id },
identity: identities.find { |identity| identity["account_id"] == account_id }
}
hash[account_id][:total] += payment[:gross_pay_amount]
hash[account_id][:payments] << payment
Expand Down Expand Up @@ -64,6 +69,17 @@ def fetch_incomes_for_account_id(account_id)
pinwheel.fetch_income_metadata(account_id: account_id)["data"]
end

def fetch_identities
fetch_end_user_account_ids.map do |account_id|
next [] unless does_pinwheel_account_support_job?(account_id, "identity")
fetch_identity_for_account_id account_id
end.flatten
end

def fetch_identity_for_account_id(account_id)
pinwheel.fetch_identity(account_id: account_id)["data"]
end

def does_pinwheel_account_support_job?(account_id, job)
pinwheel_account = PinwheelAccount.find_by_pinwheel_account_id(account_id)
return false unless pinwheel_account
Expand Down
5 changes: 4 additions & 1 deletion app/app/mailers/caseworker_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ def set_params
@payments = params[:payments] if params[:payments]
@employments = params[:employments]
@incomes = params[:incomes]
@identities = params[:identities]
# shows caseworker-specific data
@is_caseworker = true
end

def generate_pdf
WickedPdf.new.pdf_from_string(
render_to_string(template: "cbv/summaries/show", layout: "pdf", formats: [ :pdf ])
render_to_string(template: "cbv/summaries/show", layout: "pdf", formats: [ :pdf ], locals: { is_caseworker: true })
)
end
end
5 changes: 4 additions & 1 deletion app/app/models/pinwheel_account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ class PinwheelAccount < ApplicationRecord
EVENTS_MAP = {
"employment.added" => :employment_synced_at,
"income.added" => :income_synced_at,
"identity.added" => :identity_synced_at,
"paystubs.fully_synced" => :paystubs_synced_at
}

EVENTS_ERRORS_MAP = {
"employment.added" => :employment_errored_at,
"income.added" => :income_errored_at,
"identity.added" => :identity_errored_at,
"paystubs.fully_synced" => :paystubs_errored_at
}

def has_fully_synced?
(supported_jobs.exclude?("paystubs") || paystubs_synced_at.present?) &&
(supported_jobs.exclude?("employment") || employment_synced_at.present?) &&
(supported_jobs.exclude?("income") || income_synced_at.present?)
(supported_jobs.exclude?("income") || income_synced_at.present?) &&
(supported_jobs.exclude?("identity") || income_synced_at.present?)
end

def job_succeeded?(job)
Expand Down
4 changes: 4 additions & 0 deletions app/app/services/pinwheel_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ def fetch_employment(account_id:)
@http.get(build_url("#{ACCOUNTS_ENDPOINT}/#{account_id}/employment")).body
end

def fetch_identity(account_id:)
@http.get(build_url("#{ACCOUNTS_ENDPOINT}/#{account_id}/identity")).body
end

def fetch_income_metadata(account_id:)
@http.get(build_url("#{ACCOUNTS_ENDPOINT}/#{account_id}/income")).body
end
Expand Down
1 change: 1 addition & 0 deletions app/app/services/pinwheel_webhook_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class PinwheelWebhookManager
paystubs.fully_synced
employment.added
income.added
identity.added
]

def initialize
Expand Down
53 changes: 51 additions & 2 deletions app/app/views/cbv/summaries/show.pdf.erb
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
<h1><%= t(".pdf.client.header") %></h1>

<p><%= t(".pdf.client.description") %></p>
<% if is_caseworker %>
<p><%= t(".pdf.caseworker.description") %></p>
<div class="usa-alert usa-alert--info">
<div class="usa-alert__body">
<p class="usa-alert__text">
<strong><%= t(".pdf.caseworker.how_to_header") %></strong>
<%= t(".pdf.caseworker.how_to") %>
</p>
</div>
</div>
<% else %>
<p><%= t(".pdf.client.description") %></p>
<% end %>

<h2><%= t(".pdf.client.client_report_information") %></h2>

<% if is_caseworker %>
<%= render(TableComponent.new) do |table| %>
<%= table.with_header do %>
<h3 class="margin-0">Client Information</h3>
<% end %>
<%= table.with_row(
label: t(".pdf.caseworker.first_name"),
value: @cbv_flow.cbv_flow_invitation.first_name
) %>
<%= table.with_row(
label: t(".pdf.caseworker.middle_name"),
value: @cbv_flow.cbv_flow_invitation.middle_name
) %>
<%= table.with_row(
label: t(".pdf.caseworker.last_name"),
value: @cbv_flow.cbv_flow_invitation.last_name
) %>
<%= table.with_row(
label: t(".pdf.caseworker.client_id_number"),
value: @cbv_flow.cbv_flow_invitation.client_id_number
) %>
<%= table.with_row(
label: t(".pdf.caseworker.case_number"),
value: @cbv_flow.cbv_flow_invitation.case_number
) %>
<% end %>
<% end %>
<%= render(TableComponent.new) do |table| %>
<%= table.with_header do %>
<h3 class="margin-0">Report details</h3>
<% end %>
<% if @cbv_flow.confirmation_code.present? %>
<%= table.with_row(
label: t(".confirmation_code"),
label: t(".pdf.shared.confirmation_code"),
value: @cbv_flow.confirmation_code)
%>
<% end %>
Expand All @@ -26,6 +66,12 @@
label: t(".pdf.client.date_range"),
value: "#{format_parsed_date(@cbv_flow.cbv_flow_invitation.paystubs_query_begins_at)} to #{format_parsed_date(@cbv_flow.cbv_flow_invitation.snap_application_date)}")
%>
<% if is_caseworker %>
<%= table.with_row(
label: t(".pdf.caseworker.agreement_consent_timestamp"),
value: @cbv_flow.consented_to_authorized_use_at)
%>
<% end %>
<% end %>

<h2><%= t(".pdf.client.employment_payment_details") %></h2>
Expand All @@ -38,6 +84,9 @@
<%= table.with_header do %>
<h3 class="margin-0"><%= summary[:employer_name] %> Employment Information</h3>
<% end %>
<% if is_caseworker %>
<%= table.with_data_point(:client_full_name, summary[:identity]["full_name"]) %>
<% end %>
<% if summary[:has_employment_data] %>
<%= table.with_data_point(:employer_phone, summary[:employment]["employer_phone_number"]["value"]) %>
<%= table.with_data_point(:employer_address, summary[:employment]["employer_address"]["raw"]) %>
Expand Down
13 changes: 13 additions & 0 deletions app/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,17 @@ en:
none_found: No payments found. Please refresh the page after a few minutes.
payment: Payment of %{amount} before taxes on %{date}
pdf:
caseworker:
agreement_consent_timestamp: Agreement Consent Timestamp
case_number: Case number
client_full_name: Client full name (linked to payroll account)
client_id_number: CIN
description: The following income information was retrieved with the client's consent and has been submitted by them to their benefits agency. The client is also able to download a client-facing copy of this report.
first_name: Client's first name
how_to: This report includes payment information from the past 90 days. In most cases, you only need to review income from the last 30 days for eligibility purposes. Use data beyond the 30-day period only if necessary. Key fields for income verification are highlighted in yellow.
how_to_header: 'How to use this report:'
last_name: Client's last name
middle_name: Client's middle name
client:
address: Employer address
client_report_information: Client and Report Information
Expand All @@ -243,6 +254,8 @@ en:
description: We have collected your income information with your consent and sent it to your benefits agency. Any additional income that you weren't able to add to this report should be shared separately with your benefits agency.
employment_payment_details: Employment and payment details
header: Income Verification Report
shared:
confirmation_code: Confirmation code
phone_number: Employer phone
send_report: Share my report with benefits agency
table_caption: 'Employer %{number}: %{employer_name}'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddErrorEventColumnForIdentity < ActiveRecord::Migration[7.1]
def change
add_column :pinwheel_accounts, :identity_errored_at, :timestamp
add_column :pinwheel_accounts, :identity_synced_at, :timestamp
end
end
4 changes: 3 additions & 1 deletion app/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_08_14_203311) do
ActiveRecord::Schema[7.1].define(version: 2024_08_26_161050) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -74,6 +74,8 @@
t.datetime "employment_errored_at", precision: nil
t.datetime "income_errored_at", precision: nil
t.datetime "paystubs_errored_at", precision: nil
t.datetime "identity_errored_at", precision: nil
t.datetime "identity_synced_at", precision: nil
t.index ["cbv_flow_id"], name: "index_pinwheel_accounts_on_cbv_flow_id"
end

Expand Down
4 changes: 3 additions & 1 deletion app/spec/controllers/cbv/summaries_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RSpec.describe Cbv::SummariesController do
include PinwheelApiHelper

let(:supported_jobs) { %w[income paystubs employment] }
let(:supported_jobs) { %w[income paystubs employment identity] }
let(:flow_started_seconds_ago) { 300 }
let(:employment_errored_at) { nil }
let(:cbv_flow) { create(:cbv_flow, :with_pinwheel_account, created_at: flow_started_seconds_ago.seconds.ago, case_number: "ABC1234", supported_jobs: supported_jobs, employment_errored_at: employment_errored_at) }
Expand All @@ -27,6 +27,7 @@
stub_request_end_user_paystubs_response
stub_request_employment_info_response unless employment_errored_at
stub_request_income_metadata_response if supported_jobs.include?("income")
stub_request_identity_response
end

context "when rendering views" do
Expand Down Expand Up @@ -113,6 +114,7 @@
stub_request_end_user_paystubs_response
stub_request_employment_info_response
stub_request_income_metadata_response
stub_request_identity_response
end

context "without consent" do
Expand Down
7 changes: 6 additions & 1 deletion app/spec/controllers/concerns/cbv/reports_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
load_relative_json_file('request_income_metadata_response.json')['data']
end

let(:identities) do
load_relative_json_file('request_identity_response.json')['data']
end

let(:parsed_payments) do
helper.parse_payments(payments)
end
Expand All @@ -29,7 +33,7 @@

describe "aggregate payments" do
it "groups by employer" do
expect(helper.summarize_by_employer(parsed_payments, [ employments ], [ incomes ])).to eq({
expect(helper.summarize_by_employer(parsed_payments, [ employments ], [ incomes ], [ identities ])).to eq({
account_id => {
employer_name: "Acme Corp",
payments: [
Expand All @@ -56,6 +60,7 @@
has_employment_data: true,
employment: employments,
income: incomes,
identity: identities,
total: 480720
}
})
Expand Down
1 change: 1 addition & 0 deletions app/spec/factories/pinwheel_account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
paystubs_synced_at { DateTime.now }
employment_synced_at { DateTime.now }
income_synced_at { DateTime.now }
identity_synced_at { DateTime.now }
end
end
4 changes: 3 additions & 1 deletion app/spec/mailers/caseworker_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
let(:payments) { stub_post_processed_payments(account_id) }
let(:employments) { stub_employments(account_id) }
let(:incomes) { stub_incomes(account_id) }
let(:identities) { stub_identities(account_id) }
let(:email_address) { "[email protected]" }
let(:mail) {
CaseworkerMailer.with(
email_address: email_address,
cbv_flow: cbv_flow,
payments: payments,
employments: employments,
incomes: incomes
incomes: incomes,
identities: identities
).summary_email.deliver_now
}

Expand Down
3 changes: 2 additions & 1 deletion app/spec/mailers/previews/caseworker_mailer_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def summary_email
payments = stub_post_processed_payments(cbv_flow.pinwheel_accounts.first.pinwheel_account_id)
employments = stub_employments(cbv_flow.pinwheel_accounts.first.pinwheel_account_id)
incomes = stub_incomes(cbv_flow.pinwheel_accounts.first.pinwheel_account_id)
CaseworkerMailer.with(cbv_flow: cbv_flow, case_number: "12345", payments: payments, employments: employments, incomes: incomes).summary_email
identities = stub_identities(cbv_flow.pinwheel_accounts.first.pinwheel_account_id)
CaseworkerMailer.with(cbv_flow: cbv_flow, case_number: "12345", payments: payments, employments: employments, incomes: incomes, identities: identities).summary_email
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"data":{"id":"9583558c-f54c-455d-9519-554416106a0a","created_at":"2024-08-23T19:26:34.541298+00:00","updated_at":"2024-08-23T19:26:34.541298+00:00","account_id":"03e29160-f7e7-4a28-b2d8-813640e030d3","full_name":"Ash Userton","emails":["[email protected]"],"date_of_birth":"1993-08-28","last_four_ssn":"1234","address":{"raw":"20429 Pinwheel Drive, New York City, NY 99999","line1":"20429 Pinwheel Drive","line2":null,"city":"New York City","state":"NY","postal_code":"99999","country":"US"},"phone_numbers":[{"value":"+12345556789","type":null}]},"meta":{"refreshed_at":"2024-08-23T19:26:34.676325+00:00"}}
9 changes: 9 additions & 0 deletions app/spec/support/pinwheel_api_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ def request_employment_info_response_null_employment_status_bug
)
end

def stub_request_identity_response
stub_request(:get, %r{#{PinwheelService::ACCOUNTS_ENDPOINT}/[0-9a-fA-F\-]{36}/identity})
.to_return(
status: 200,
body: load_relative_json_file('request_identity_response.json').to_json,
headers: { 'Content-Type': 'application/json;charset=UTF-8' }
)
end

def load_relative_file(filename)
File.read(File.join(
File.dirname(__FILE__),
Expand Down
Loading

0 comments on commit ee155ea

Please sign in to comment.