Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure vacols location isn't set incorrectly when user requests disposition change #15082

Merged
merged 8 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/models/tasks/hearing_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def verify_org_task_unique
def when_child_task_completed(child_task)
super

# do not move forward to change location or create ihp if there are
# other open hearing tasks
return unless appeal.tasks.open.where(type: HearingTask.name).empty?

if appeal.is_a?(LegacyAppeal)
Expand Down
16 changes: 13 additions & 3 deletions app/models/tasks/schedule_hearing_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,26 @@ def create_change_hearing_disposition_task(instructions = nil)
end

multi_transaction do
# cancel my children, myself, and my hearing task ancestor
# cancel the old HearingTask and create a new one associated with the same hearing
# NOTE: We need to first create new hearing task so there is at least one open hearing task for
# when_child_task_completed in HearingTask to prevent triggering of location change for legacy appeals
# with update below
new_hearing_task = hearing_task.cancel_and_recreate

# cancel my children, possibly myself, and possibly my hearing task ancestor
# NOTE: possibly because cancellation depends on whether or not the tasks are assigned to BVA org
children.open.update_all(status: Constants.TASK_STATUSES.cancelled, closed_at: Time.zone.now)

# cancel self for sure
update!(status: Constants.TASK_STATUSES.cancelled, closed_at: Time.zone.now)
tomas-nava marked this conversation as resolved.
Show resolved Hide resolved

# cancel parent for sure
ancestor_task_of_type(HearingTask)&.update!(
status: Constants.TASK_STATUSES.cancelled,
closed_at: Time.zone.now
)
tomas-nava marked this conversation as resolved.
Show resolved Hide resolved

# cancel the old HearingTask and create a new one associated with the same hearing
new_hearing_task = hearing_task.cancel_and_recreate
# create the association for new hearing task
HearingTaskAssociation.create!(hearing: hearing_task.hearing, hearing_task: new_hearing_task)

# create a ChangeHearingDispositionTask on the new HearingTask
Expand Down
104 changes: 66 additions & 38 deletions spec/models/tasks/schedule_hearing_task_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,64 +226,92 @@
end

describe "#create_change_hearing_disposition_task" do
let(:appeal) { create(:appeal) }
let(:root_task) { create(:root_task, appeal: appeal) }
let(:past_hearing_disposition) { Constants.HEARING_DISPOSITION_TYPES.postponed }
let(:hearing) { create(:hearing, appeal: appeal, disposition: past_hearing_disposition) }
let(:hearing_task) { create(:hearing_task, parent: root_task) }
let!(:disposition_task) do
create(:assign_hearing_disposition_task, parent: hearing_task)
end

let!(:association) { create(:hearing_task_association, hearing: hearing, hearing_task: hearing_task) }
let!(:hearing_task_2) { create(:hearing_task, parent: root_task) }
let!(:task) { create(:schedule_hearing_task, parent: hearing_task_2) }
let(:instructions) { "These are my detailed instructions for a schedule hearing task." }

let!(:disposition_task) do
create(:assign_hearing_disposition_task, parent: hearing_task)
end

subject { task.create_change_hearing_disposition_task(instructions) }

before do
[hearing_task, disposition_task].each { |task| task&.update!(status: Constants.TASK_STATUSES.completed) }
create(:hearing_task_association, hearing: hearing, hearing_task: hearing_task_2)
end

subject { task.create_change_hearing_disposition_task(instructions) }

it "creates new hearing and change hearing disposition tasks and cancels unwanted tasks" do
subject
shared_examples "creates new task" do
it "creates new hearing and change hearing disposition tasks and cancels unwanted tasks" do
subject

expect(hearing_task.reload.open?).to be_falsey
expect(hearing_task.closed_at).to_not be_nil
expect(disposition_task.reload.open?).to be_falsey
expect(disposition_task.closed_at).to_not be_nil
expect(hearing_task_2.reload.status).to eq Constants.TASK_STATUSES.cancelled
expect(hearing_task_2.closed_at).to_not be_nil
expect(task.reload.status).to eq Constants.TASK_STATUSES.cancelled
expect(task.closed_at).to_not be_nil
new_hearing_tasks = appeal.tasks.open.where(type: HearingTask.name)
expect(new_hearing_tasks.count).to eq 1
expect(new_hearing_tasks.first.hearing).to eq hearing
new_change_tasks = appeal.tasks.open.where(type: ChangeHearingDispositionTask.name)
expect(new_change_tasks.count).to eq 1
expect(new_change_tasks.first.parent).to eq new_hearing_tasks.first
expect(hearing_task.reload.open?).to be_falsey
expect(hearing_task.closed_at).to_not be_nil
expect(disposition_task.reload.open?).to be_falsey
expect(disposition_task.closed_at).to_not be_nil
expect(hearing_task_2.reload.status).to eq Constants.TASK_STATUSES.cancelled
expect(hearing_task_2.closed_at).to_not be_nil
expect(task.reload.status).to eq Constants.TASK_STATUSES.cancelled
expect(task.closed_at).to_not be_nil
new_hearing_tasks = appeal.tasks.open.where(type: HearingTask.name)
expect(new_hearing_tasks.count).to eq 1
expect(new_hearing_tasks.first.hearing).to eq hearing
new_change_tasks = appeal.tasks.open.where(type: ChangeHearingDispositionTask.name)
expect(new_change_tasks.count).to eq 1
expect(new_change_tasks.first.parent).to eq new_hearing_tasks.first
end
end
context "AMA appeal" do
let(:appeal) { create(:appeal) }
let(:past_hearing_disposition) { Constants.HEARING_DISPOSITION_TYPES.postponed }
let(:hearing) { create(:hearing, appeal: appeal, disposition: past_hearing_disposition) }

context "the past hearing disposition is nil" do
let(:past_hearing_disposition) { nil }
include_examples "creates new task"

it "does not create ihp tasks" do
subject

it "raises an error" do
expect { subject }
.to raise_error(Caseflow::Error::ActionForbiddenError)
.with_message(COPY::REQUEST_HEARING_DISPOSITION_CHANGE_FORBIDDEN_ERROR)
expect(InformalHearingPresentationTask.where(appeal_id: appeal.id).count).to eq(0)
end

context "the past hearing disposition is nil" do
let(:past_hearing_disposition) { nil }

it "raises an error" do
expect { subject }
.to raise_error(Caseflow::Error::ActionForbiddenError)
.with_message(COPY::REQUEST_HEARING_DISPOSITION_CHANGE_FORBIDDEN_ERROR)
end
end

context "there's no past inactive hearing task" do
let(:hearing_task) { nil }
let(:disposition_task) { nil }
let(:association) { nil }

it "raises an error" do
expect { subject }
.to raise_error(Caseflow::Error::ActionForbiddenError)
.with_message(COPY::REQUEST_HEARING_DISPOSITION_CHANGE_FORBIDDEN_ERROR)
end
end
end

context "there's no past inactive hearing task" do
let(:hearing_task) { nil }
let(:disposition_task) { nil }
let(:association) { nil }
context "Legacy Appeal" do
let(:vacols_case) { create(:case, bfcurloc: LegacyAppeal::LOCATION_CODES[:caseflow]) }
let(:veteran_participant_id) { "0000" }
let(:appeal) { create(:legacy_appeal, vacols_case: vacols_case) }
let(:case_hearing_past_disposition) { "P" }
let(:hearing) { create(:legacy_hearing, appeal: appeal, disposition: case_hearing_past_disposition) }

include_examples "creates new task"

it "raises an error" do
expect { subject }
.to raise_error(Caseflow::Error::ActionForbiddenError)
.with_message(COPY::REQUEST_HEARING_DISPOSITION_CHANGE_FORBIDDEN_ERROR)
it "does not change location" do
tomas-nava marked this conversation as resolved.
Show resolved Hide resolved
expect(vacols_case.reload.bfcurloc).to eq(LegacyAppeal::LOCATION_CODES[:caseflow])
end
end
end
Expand Down