-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a mechanisim for admins to upload a csv of know risky trns and ninos that will cause claims with these attributes to be flagged in the admin ui. Flagged values can be removed by uploading a CSV without those values. According to the govuk guidance we can't show multiple notification banners on a page and should combine their content. We may want to use a different method to display fraud prevention warnings to admins.
- Loading branch information
Showing
21 changed files
with
527 additions
and
7 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
app/controllers/admin/fraud_risk_csv_downloads_controller.rb
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,25 @@ | ||
module Admin | ||
class FraudRiskCsvDownloadsController < BaseAdminController | ||
before_action :ensure_service_operator | ||
|
||
def show | ||
respond_to do |format| | ||
format.csv do | ||
send_data(csv, filename: "fraud_risk.csv") | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def csv | ||
CSV.generate do |csv| | ||
csv << %w[field value] | ||
|
||
RiskIndicator.order(created_at: :asc).pluck(:field, :value).each do |row| | ||
csv << row | ||
end | ||
end | ||
end | ||
end | ||
end |
28 changes: 28 additions & 0 deletions
28
app/controllers/admin/fraud_risk_csv_uploads_controller.rb
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,28 @@ | ||
module Admin | ||
class FraudRiskCsvUploadsController < BaseAdminController | ||
before_action :ensure_service_operator | ||
|
||
def new | ||
@form = FraudRiskCsvUploadForm.new | ||
end | ||
|
||
def create | ||
@form = FraudRiskCsvUploadForm.new(fraud_risk_csv_upload_params) | ||
|
||
if @form.save | ||
redirect_to( | ||
new_admin_fraud_risk_csv_upload_path, | ||
notice: "Fraud prevention list uploaded successfully." | ||
) | ||
else | ||
render :new | ||
end | ||
end | ||
|
||
private | ||
|
||
def fraud_risk_csv_upload_params | ||
params.require(:admin_fraud_risk_csv_upload_form).permit(:file) | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
module Admin | ||
class FraudRiskCsvUploadForm | ||
include ActiveModel::Model | ||
|
||
attr_accessor :file | ||
|
||
validates :file, presence: true | ||
|
||
validate :csv_has_required_headers, if: -> { file.present? } | ||
|
||
validate :all_records_are_valid, if: -> { file.present? && csv_has_required_headers? } | ||
|
||
def initialize(params = {}) | ||
super | ||
end | ||
|
||
def save | ||
return false unless valid? | ||
|
||
ApplicationRecord.transaction do | ||
RiskIndicator.where.not(id: records.map(&:id)).destroy_all | ||
|
||
records.each(&:save!) | ||
end | ||
|
||
true | ||
end | ||
|
||
private | ||
|
||
def csv | ||
@csv ||= CSV.parse(file.read, headers: true, skip_blanks: true) | ||
end | ||
|
||
def records | ||
@records ||= csv.map do |row| | ||
RiskIndicator.find_or_initialize_by(row.to_h) | ||
end.uniq { |record| record.attributes.slice("field", "value") } | ||
end | ||
|
||
def all_records_are_valid | ||
records.select(&:invalid?).each do |record| | ||
errors.add(:base, record.errors.map(&:message).join(", ")) | ||
end | ||
end | ||
|
||
def csv_has_required_headers | ||
unless csv_has_required_headers? | ||
errors.add(:base, "csv is missing required headers `field`, `value`") | ||
end | ||
end | ||
|
||
def csv_has_required_headers? | ||
csv.headers.include?("field") && csv.headers.include?("value") | ||
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,34 @@ | ||
class RiskIndicator < ApplicationRecord | ||
SUPPORTED_FIELDS = %w[ | ||
teacher_reference_number | ||
national_insurance_number | ||
].freeze | ||
|
||
validates :field, presence: { | ||
message: "'field' can't be blank" | ||
} | ||
|
||
validates :value, presence: { | ||
message: "'value' can't be blank" | ||
} | ||
|
||
validates :value, uniqueness: {scope: :field} | ||
|
||
validates :field, | ||
inclusion: { | ||
in: SUPPORTED_FIELDS, | ||
message: "'%{value}' is not a valid attribute - must be one of #{SUPPORTED_FIELDS.join(", ")}" | ||
} | ||
|
||
def self.flagged_attributes(claim) | ||
where( | ||
"field = 'national_insurance_number' AND LOWER(value) = :value", | ||
value: claim.national_insurance_number&.downcase | ||
).or( | ||
where( | ||
field: "teacher_reference_number", | ||
value: claim.eligibility.try(:teacher_reference_number) | ||
) | ||
).pluck(:field).compact | ||
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
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 @@ | ||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds"> | ||
<h1 class="govuk-heading-xl"> | ||
Fraud risk CSV upload | ||
</h1> | ||
|
||
<%= form_with( | ||
url: admin_fraud_risk_csv_uploads_path, | ||
model: @form, | ||
builder: GOVUKDesignSystemFormBuilder::FormBuilder | ||
) do |f| %> | ||
<%= f.govuk_error_summary %> | ||
|
||
<%= f.govuk_file_field( | ||
:file, | ||
label: { text: "Upload fraud risk CSV file" }, | ||
hint: { | ||
text: "Currently supported attributes are #{RiskIndicator::SUPPORTED_FIELDS.join(", ")}." | ||
} | ||
) %> | ||
|
||
<%= f.govuk_submit "Upload CSV" %> | ||
<% end %> | ||
|
||
<%= govuk_link_to( | ||
"Download CSV", | ||
admin_fraud_risk_csv_download_path(format: :csv), | ||
class: "govuk-button" | ||
) %> | ||
</div> | ||
</div> |
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 |
---|---|---|
|
@@ -131,3 +131,9 @@ | |
- verification | ||
:journeys_sessions: | ||
- answers | ||
:risk_indicators: | ||
- id | ||
- field | ||
- value | ||
- created_at | ||
- updated_at |
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,12 @@ | ||
class CreateRiskIndicators < ActiveRecord::Migration[7.0] | ||
def change | ||
create_table :risk_indicators, id: :uuid do |t| | ||
t.string :field, null: false | ||
t.string :value, null: false | ||
|
||
t.index %i[field value], unique: true | ||
|
||
t.timestamps | ||
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,6 @@ | ||
FactoryBot.define do | ||
factory :risk_indicator do | ||
field { "teacher_reference_number" } | ||
value { "1234567" } | ||
end | ||
end |
Oops, something went wrong.