-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add and populate aod_based_on_age column (#14763)
* add aod_based_on_age column to appeals * [Part 2] Populate age_aod column (#14764) * add and use conditionally_set_aod_based_on_age * add SetAppealAgeAodJob * enable finer access to reasons for AOD * exclude AttorneyClaimant from AOD logic * improve test coverage * handle case where aod_based_on_age changes to false
- Loading branch information
Showing
13 changed files
with
255 additions
and
15 deletions.
There are no files selected for viewing
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,66 @@ | ||
# frozen_string_literal: true | ||
|
||
# Early morning job that checks if the claimant meets the Advance-On-Docket age criteria. | ||
# If criteria is satisfied, all active appeals associated with claimant will be marked as AOD. | ||
# This job also handles the scenario where a claimant's DOB is updated such that their appeal(s) are no longer AOD. | ||
class SetAppealAgeAodJob < CaseflowJob | ||
include ActionView::Helpers::DateHelper | ||
|
||
def perform | ||
RequestStore.store[:current_user] = User.system_user | ||
|
||
aod_appeals_to_unset = appeals_to_unset_age_based_aod | ||
detail_msg = "IDs of appeals to remove age-related AOD: #{aod_appeals_to_unset.pluck(:id)}" | ||
aod_appeals_to_unset.update_all(aod_based_on_age: false, updated_at: Time.now.utc) | ||
|
||
# We expect there to be only one claimant on an appeal. Any claimant meeting the age criteria will cause AOD. | ||
appeals_for_aod = appeals_to_set_age_based_aod | ||
detail_msg += "\nIDs of appeals to be updated with age-related AOD: #{appeals_for_aod.pluck(:id)}" | ||
appeals_for_aod.update_all(aod_based_on_age: true, updated_at: Time.now.utc) | ||
|
||
log_success(detail_msg) | ||
rescue StandardError => error | ||
log_error(self.class.name, error, detail_msg) | ||
end | ||
|
||
protected | ||
|
||
def log_success(details) | ||
duration = time_ago_in_words(start_time) | ||
msg = "#{self.class.name} completed after running for #{duration}.\n#{details}" | ||
Rails.logger.info(msg) | ||
|
||
slack_service.send_notification("[INFO] #{msg}") | ||
end | ||
|
||
def log_error(collector_name, err, details) | ||
duration = time_ago_in_words(start_time) | ||
msg = "#{collector_name} failed after running for #{duration}. Fatal error: #{err.message}.\n#{details}" | ||
Rails.logger.info(msg) | ||
Rails.logger.info(err.backtrace.join("\n")) | ||
|
||
Raven.capture_exception(err, extra: { stats_collector_name: collector_name }) | ||
|
||
slack_service.send_notification("[ERROR] #{msg}") | ||
end | ||
|
||
private | ||
|
||
def appeals_to_unset_age_based_aod | ||
active_appeals_with_age_based_aod.joins(claimants: :person).where("people.date_of_birth > ?", 75.years.ago) | ||
end | ||
|
||
def active_appeals_with_age_based_aod | ||
Appeal.active.where(aod_based_on_age: true) | ||
end | ||
|
||
def appeals_to_set_age_based_aod | ||
active_appeals_without_age_based_aod.joins(claimants: :person).where("people.date_of_birth <= ?", 75.years.ago) | ||
end | ||
|
||
def active_appeals_without_age_based_aod | ||
# `aod_based_on_age` is initially nil | ||
# `aod_based_on_age` being false means that it was once true (in the case where the claimant's DOB was updated) | ||
Appeal.active.where(aod_based_on_age: [nil, false]) | ||
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
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,5 @@ | ||
class AddAgeAodColumnToAppeals < ActiveRecord::Migration[5.2] | ||
def change | ||
add_column :appeals, :aod_based_on_age, :boolean, comment: "If true, appeal is advance-on-docket due to claimant's age." | ||
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,5 @@ | ||
class AddAgeAodIndexToAppeals < Caseflow::Migration | ||
def change | ||
add_safe_index :appeals, :aod_based_on_age | ||
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,70 @@ | ||
# frozen_string_literal: true | ||
|
||
describe SetAppealAgeAodJob, :postgres do | ||
include_context "Metrics Reports" | ||
|
||
# rubocop:disable Metrics/LineLength | ||
let(:success_msg) do | ||
"[INFO] SetAppealAgeAodJob completed after running for less than a minute." | ||
end | ||
# rubocop:enable Metrics/LineLength | ||
|
||
describe "#perform" do | ||
let(:non_aod_appeal) { create(:appeal, :with_schedule_hearing_tasks) } | ||
|
||
# appeal with wrong date-of-birth causing AOD; it is fixed in the before block | ||
let(:age_aod_appeal_wrong_dob) { create(:appeal, :with_schedule_hearing_tasks, :advanced_on_docket_due_to_age) } | ||
|
||
let(:age_aod_appeal) { create(:appeal, :with_schedule_hearing_tasks, :advanced_on_docket_due_to_age) } | ||
let(:motion_aod_appeal) { create(:appeal, :with_schedule_hearing_tasks, :advanced_on_docket_due_to_motion) } | ||
|
||
let(:inactive_age_aod_appeal) { create(:appeal, :advanced_on_docket_due_to_age) } | ||
let(:cancelled_age_aod_appeal) { create(:appeal, :advanced_on_docket_due_to_age, :cancelled) } | ||
|
||
before do | ||
allow_any_instance_of(SlackService).to receive(:send_notification) { |_, first_arg| @slack_msg = first_arg } | ||
|
||
age_aod_appeal_wrong_dob.update(aod_based_on_age: true) | ||
# simulate date-of-birth being corrected | ||
age_aod_appeal_wrong_dob.claimant.person.update(date_of_birth: 50.years.ago) | ||
end | ||
|
||
it "sets aod_based_on_age for only active appeals with a claimant that satisfies the age criteria" do | ||
expect(non_aod_appeal.active?).to eq(true) | ||
expect(age_aod_appeal.active?).to eq(true) | ||
expect(motion_aod_appeal.active?).to eq(true) | ||
expect(inactive_age_aod_appeal.active?).to eq(false) | ||
expect(cancelled_age_aod_appeal.active?).to eq(false) | ||
|
||
expect(age_aod_appeal_wrong_dob.aod_based_on_age).to eq(true) | ||
|
||
described_class.perform_now | ||
expect(@slack_msg).to include(success_msg) | ||
|
||
# `aod_based_on_age` will be nil | ||
# `aod_based_on_age` being false means that it was once true (in the case where the claimant's DOB was updated) | ||
expect(non_aod_appeal.reload.aod_based_on_age).not_to eq(true) | ||
expect(inactive_age_aod_appeal.reload.aod_based_on_age).not_to eq(true) | ||
|
||
expect(age_aod_appeal.reload.aod_based_on_age).to eq(true) | ||
expect(motion_aod_appeal.reload.aod_based_on_age).to eq(false) | ||
|
||
expect(age_aod_appeal_wrong_dob.reload.aod_based_on_age).to eq(false) | ||
end | ||
|
||
context "when the entire job fails" do | ||
let(:error_msg) { "Some dummy error" } | ||
|
||
it "sends a message to Slack that includes the error" do | ||
slack_msg = "" | ||
allow_any_instance_of(SlackService).to receive(:send_notification) { |_, first_arg| slack_msg = first_arg } | ||
|
||
allow_any_instance_of(described_class).to receive(:appeals_to_set_age_based_aod).and_raise(error_msg) | ||
described_class.perform_now | ||
|
||
expected_msg = "#{described_class.name} failed after running for .*. Fatal error: #{error_msg}" | ||
expect(slack_msg).to match(/#{expected_msg}/) | ||
end | ||
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