Skip to content

Commit

Permalink
Add cancel method to DispositionTask (#9823)
Browse files Browse the repository at this point in the history
Resolves #9539

### Description
Adds a `cancel!` method to the `DispositionTask` that makes required changes on parent `HearingTask` and associated legacy/ama appeal.
  • Loading branch information
tomas-nava authored and va-bot committed Mar 8, 2019
1 parent 3abc047 commit db3ece9
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 1 deletion.
45 changes: 44 additions & 1 deletion app/models/tasks/disposition_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
# The task is marked complete when these children tasks are completed.
class DispositionTask < GenericTask
before_create :check_parent_type
after_update :update_appeal_location_after_cancel, if: :task_just_canceled_and_has_legacy_appeal?
after_update :create_ihp_tasks_after_cancel, if: :task_just_canceled_and_has_ama_appeal?

class HearingDispositionNotCanceled < StandardError; end
class HearingDispositionNotNoShow < StandardError; end

class << self
Expand All @@ -32,8 +35,16 @@ def check_parent_type
end
end

def cancel!
if hearing_disposition != Constants.HEARING_DISPOSITION_TYPES.cancelled
fail HearingDispositionNotCanceled
end

update!(status: Constants.TASK_STATUSES.cancelled)
end

def mark_no_show!
if parent&.hearing_task_association&.hearing&.disposition != Constants.HEARING_DISPOSITION_TYPES.no_show
if hearing_disposition != Constants.HEARING_DISPOSITION_TYPES.no_show
fail HearingDispositionNotNoShow
end

Expand All @@ -48,4 +59,36 @@ def mark_no_show!
on_hold_duration: 25.days
)
end

private

def task_just_canceled?
saved_change_to_attribute?("status") && cancelled?
end

def task_just_canceled_and_has_legacy_appeal?
task_just_canceled? && appeal.is_a?(LegacyAppeal)
end

def task_just_canceled_and_has_ama_appeal?
task_just_canceled? && appeal.is_a?(Appeal)
end

def create_ihp_tasks_after_cancel
RootTask.create_ihp_tasks!(appeal, parent)
end

def update_appeal_location_after_cancel
location = if appeal.vsos.empty?
LegacyAppeal::LOCATION_CODES[:case_storage]
else
LegacyAppeal::LOCATION_CODES[:service_organization]
end

AppealRepository.update_location!(appeal, location)
end

def hearing_disposition
parent&.hearing_task_association&.hearing&.disposition
end
end
10 changes: 10 additions & 0 deletions app/models/tasks/hearing_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,14 @@

class HearingTask < GenericTask
has_one :hearing_task_association

private

def update_status_if_children_tasks_are_complete
if children.select(&:active?).empty?
return update!(status: :cancelled) if children.select { |c| c.type == DispositionTask.name && c.cancelled? }.any?
end

super
end
end
134 changes: 134 additions & 0 deletions spec/models/tasks/disposition_task_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,140 @@
end
end

describe ".cancel!" do
let(:disposition) { nil }
let(:appeal) { FactoryBot.create(:appeal) }
let(:root_task) { FactoryBot.create(:root_task, appeal: appeal) }
let(:hearing_task) { FactoryBot.create(:hearing_task, parent: root_task, appeal: appeal) }
let(:hearing) { FactoryBot.create(:hearing, appeal: appeal, disposition: disposition) }
let!(:hearing_task_association) do
FactoryBot.create(
:hearing_task_association,
hearing: hearing,
hearing_task: hearing_task
)
end
let!(:schedule_hearing_task) do
FactoryBot.create(
:schedule_hearing_task,
parent: hearing_task,
appeal: appeal,
assigned_to: HearingsManagement.singleton,
status: Constants.TASK_STATUSES.completed
)
end
let!(:disposition_task) do
FactoryBot.create(
:ama_disposition_task,
parent: hearing_task,
appeal: appeal,
status: Constants.TASK_STATUSES.in_progress
)
end

subject { disposition_task.cancel! }

context "the appeal is an AMA appeal" do
context "the task's hearing's disposition is canceled" do
let(:disposition) { Constants.HEARING_DISPOSITION_TYPES.cancelled }

it "cancels the disposition task and its parent hearing task" do
expect(disposition_task.cancelled?).to be_falsey
expect(hearing_task.on_hold?).to be_truthy

expect { subject }.to_not raise_error

expect(disposition_task.cancelled?).to be_truthy
expect(hearing_task.cancelled?).to be_truthy
expect(InformalHearingPresentationTask.where(appeal: appeal).length).to eq 0
end

context "the appeal has a VSO" do
let(:participant_id_with_pva) { "000000" }
let(:appeal) do
create(:appeal, claimants: [create(:claimant, participant_id: participant_id_with_pva)])
end

before do
Vso.create(
name: "Paralyzed Veterans Of America",
role: "VSO",
url: "paralyzed-veterans-of-america",
participant_id: "2452383"
)

allow_any_instance_of(BGSService).to receive(:fetch_poas_by_participant_ids)
.with([participant_id_with_pva]).and_return(
participant_id_with_pva => {
representative_name: "PARALYZED VETERANS OF AMERICA, INC.",
representative_type: "POA National Organization",
participant_id: "2452383"
}
)
end

it "creates an IHP task" do
expect(InformalHearingPresentationTask.where(appeal: appeal).length).to eq 0

subject

expect(InformalHearingPresentationTask.where(appeal: appeal).length).to eq 1
end
end
end

context "the task's hearing's disposition is not canceled" do
let(:disposition) { Constants.HEARING_DISPOSITION_TYPES.postponed }

it "raises an error" do
expect(disposition_task.cancelled?).to be_falsey
expect { subject }.to raise_error(DispositionTask::HearingDispositionNotCanceled)
expect(disposition_task.cancelled?).to be_falsey
end
end
end

context "the appeal is a legacy appeal" do
let(:vacols_case) { FactoryBot.create(:case, bfcurloc: LegacyAppeal::LOCATION_CODES[:schedule_hearing]) }
let(:appeal) { create(:legacy_appeal, vacols_case: vacols_case) }
let(:hearing) { create(:legacy_hearing, appeal: appeal, disposition: disposition) }
let(:disposition) { Constants.HEARING_DISPOSITION_TYPES.cancelled }

context "there's no associated VSO" do
it "updates the case location to case storage (81)" do
subject

expect(vacols_case.reload.bfcurloc).to eq(LegacyAppeal::LOCATION_CODES[:case_storage])
end
end

context "there is an associated VSO" do
let(:participant_id) { "1234" }
let!(:vso) { create(:vso, name: "Gogozim", participant_id: participant_id) }

before do
allow(BGSService).to receive(:power_of_attorney_records).and_return(
appeal.veteran_file_number => {
file_number: appeal.veteran_file_number,
power_of_attorney: {
legacy_poa_cd: "3QQ",
nm: "Clarence Darrow",
org_type_nm: "POA Attorney",
ptcpnt_id: participant_id
}
}
)
end

it "updates the case location to service organization (55)" do
subject

expect(vacols_case.reload.bfcurloc).to eq(LegacyAppeal::LOCATION_CODES[:service_organization])
end
end
end
end

describe ".mark_no_show!" do
let(:disposition) { nil }
let(:appeal) { FactoryBot.create(:appeal) }
Expand Down

0 comments on commit db3ece9

Please sign in to comment.