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

Determine what to do with children of cancelled tasks assigned to inactive users #12505

Closed
1 of 2 tasks
hschallhorn opened this issue Oct 29, 2019 · 13 comments
Closed
1 of 2 tasks
Labels
Feature: generic-queue Priority: High Escalations from Support, blocking issue/NO workaround, or "first in" priority for new work. Product: caseflow-queue Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Team: Echo 🐬 Type: Investigation

Comments

@hschallhorn
Copy link
Contributor

hschallhorn commented Oct 29, 2019

Spun out of #12483.

Some slack chatter.

In some scenarios, when we "reassign" tasks of an inactive user, some tasks are merely cancelled to be reassigned manually by a judge, team admin, quality reviewer, bva dispatch team member, etc. On occasion these tasks will have children that become orphaned due to their parent being cancelled. In some scenarios, these children can be moved to their new parent. In other scenarios, these downstream children should be cancelled.

This ticket exists to determine which path to take in which situation.

AC

  • Plan to handle children of cancelled tasks is created
  • Properly handling these children is specced out with another ticket(s) to do the work
@hschallhorn hschallhorn added the Priority: High Escalations from Support, blocking issue/NO workaround, or "first in" priority for new work. label Oct 30, 2019
@lomky
Copy link
Contributor

lomky commented Oct 31, 2019

Throwing a 2 at this after scoping it to planning out the work needed.

va-bot pushed a commit that referenced this issue Nov 1, 2019
Resolves #12394

### Description
Reassigns all tasks assigned to a user

### Acceptance Criteria
- [ ] Fails when original tasks are not in the correct state
- [ ] Leaves all reassigned tasks in the correct state

### Testing Plan

Users to test:
 - BVAAABSHIRE (Parent task is RootTask assigned to Bva)
 - QR_USER (Parent task assigned to `Organization` NOT using automatic child task assignment)
 - CSS_ID1 (Parent task assigned to `Organization` using automatic child task assignment)
 - BVASCASPER1 (Parent task assigned to `User` - `AttorneyTask`)

_All of this was done off of a fresh `make reset`_ 

#### BVAAABSHIRE
1. Check out the state of the user's current tasks
```ruby
user = User.find_by(css_id: "BVAAABSHIRE")
user.update_status!(Constants.USER_STATUSES.inactive)
JudgeTeam.for_judge(user).non_admins.each do |atty|
  OrganizationsUser.add_user_to_organization(user, JudgeTeam.first)
end
JudgeQualityReviewTask.create!(parent: QualityReviewTask.active.last, assigned_to: user, appeal: QualityReviewTask.active.last.appeal)
appeals = Task.open.where(assigned_to: user).order(:type, :status).map(&:appeal)
task_trees = appeals.map do |appeal|
 appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# assigned JudgeAssignTask
# Appeal 114 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, completed
#     └── JudgeAssignTask 3, assigned

# assigned JudgeDecisionReviewTask with completed AttorneyTask
# Appeal 50 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     └── JudgeDecisionReviewTask 3, assigned
#         └── AttorneyTask 1, completed

# on hold JudgeDecisionReviewTask with downstream children
# Appeal 111 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     └── JudgeDecisionReviewTask 3, on_hold
#         └── AttorneyTask 1, on_hold
#             └── TranslationColocatedTask 10, on_hold
#                 └── TranslationTask 10, assigned

# on hold JudgeDecisionReviewTask 
# Appeal 60 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     └── JudgeDecisionReviewTask 3, on_hold
#         └── AttorneyTask 1, in_progress

# JudgeQualityReviewTask (parent assigned to user)
# Appeal 17 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, assigned
#     ├── JudgeDecisionReviewTask 53, completed
#     │   └── AttorneyTask 54, completed
#     └── QualityReviewTask 11, on_hold
#         └── QualityReviewTask 46, on_hold
#             └── JudgeQualityReviewTask 3, assigned
```
2. Rake!
```bash
bundle exec rake tasks:reassign_from_user[3,false]
```
3. Check the state of the reassigned tasks
```ruby
Task.open.where(assigned_to: user).count
# => 0
appeals.map do |appeal|
  appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# assigned JudgeAssignTask
# Appeal 114 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, completed
#     ├── JudgeAssignTask 3, cancelled
#     └── DistributionTask 4, assigned

# assigned JudgeDecisionReviewTask with completed AttorneyTask
# Appeal 50 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     └── JudgeDecisionReviewTask 82, assigned
#         └── AttorneyTask 1, completed

# on hold JudgeDecisionReviewTask with downstream children
# Appeal 111 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     └── JudgeDecisionReviewTask 82, on_hold
#         └── AttorneyTask 1, on_hold
#             └── TranslationColocatedTask 10, on_hold
#                 └── TranslationTask 10, assigned

# on hold JudgeDecisionReviewTask 
# Appeal 60 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     └── JudgeDecisionReviewTask 82, on_hold
#         └── AttorneyTask 1, in_progress

# JudgeQualityReviewTask (parent assigned to user)
# Appeal 17 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, assigned
#     ├── JudgeDecisionReviewTask 53, completed
#     │   └── AttorneyTask 54, completed
#     └── QualityReviewTask 11, on_hold
#         └── QualityReviewTask 46, assigned
#             └── JudgeQualityReviewTask 3, cancelled

# ✅ Judge tasks assigned to user are cancelled
# ✅ Judge assign tasks are put back into distribution
# ✅ new JudgeDecisionReviewTasks are created for another judge
# ✅ AttorneyTasks are under their new parent 
# ✅ JudgeQualityReviewTask is cancelled with an "assigned" parent
```

#### QR_USER
1. Check out the state of the user's current tasks
```ruby
user = User.find_by(css_id: "QR_USER")
appeals = Task.open.where(assigned_to: user).order(:type, :status).map(&:appeal)
appeals.map do |appeal|
 appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# Appeal 17 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, assigned
#     ├── JudgeDecisionReviewTask 53, completed
#     │   └── AttorneyTask 54, completed
#     └── QualityReviewTask 11, on_hold
#         └── QualityReviewTask 46, assigned
```
2. Rake!
```bash
bundle exec rake tasks:reassign_from_user[46,false]
```
3. Check the state of the reassigned tasks
```ruby
Task.open.where(assigned_to: user).count
# => 0
appeals.map do |appeal|
  appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# Appeal 17 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── DistributionTask 4, assigned
#     ├── JudgeDecisionReviewTask 53, completed
#     │   └── AttorneyTask 54, completed
#     └── QualityReviewTask 11, assigned
#         └── QualityReviewTask 46, cancelled

# ✅ Tasks assigned to user are cancelled
# ✅ Organization task is reopened for admin to assign
```

#### CSS_ID1
1. Check out the state of the user's current tasks
```ruby
user = User.find_by(css_id: "CSS_ID1")
user.update_status!(Constants.USER_STATUSES.inactive)
org_tasks = Task.open.where(assigned_to: user).order(:type, :status).map(&:parent)
org_tasks.map do |parent|
 parent.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# AddressVerificationColocatedTask 5, on_hold
# └── AddressVerificationColocatedTask 15, assigned
# MissingRecordsColocatedTask 5, on_hold
# └── MissingRecordsColocatedTask 15, assigned
# StayedAppealColocatedTask 5, on_hold
# └── StayedAppealColocatedTask 15, assigned
```
2. Rake!
```bash
bundle exec rake tasks:reassign_from_user[15,false]
```
3. Check the state of the reassigned tasks
```ruby
Task.open.where(assigned_to: user).count
# => 0
org_tasks.map do |parent|
  parent.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# AddressVerificationColocatedTask 5, on_hold
# ├── AddressVerificationColocatedTask 15, cancelled
# └── AddressVerificationColocatedTask 16, assigned
# MissingRecordsColocatedTask 5, on_hold
# ├── MissingRecordsColocatedTask 15, cancelled
# └── MissingRecordsColocatedTask 16, assigned
# StayedAppealColocatedTask 5, on_hold
# ├── StayedAppealColocatedTask 15, cancelled
# └── StayedAppealColocatedTask 16, assigned

# ✅ Tasks assigned to user are cancelled
# ✅ Organization task is still on hold
# ✅ Another task of the same type has been opened for other colocated team members
```

#### BVASCASPER1
1. Check out the state of the user's current tasks
```ruby
user = User.find_by(css_id: "BVASCASPER1")
appeals = Task.open.where(assigned_to: user).order(:type, :status).map(&:appeal)
appeals.map do |appeal|
 appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# in progress Task
# Appeal 60 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     └── JudgeDecisionReviewTask 82, on_hold
#         └── AttorneyTask 1, in_progress

# on hold Task
# Appeal 96 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     └── JudgeDecisionReviewTask 82, on_hold
#         └── AttorneyTask 1, on_hold
#             └── HearingClarificationColocatedTask 5, on_hold
#                 └── HearingClarificationColocatedTask 16, assigned
```
2. Rake!
```bash
bundle exec rake tasks:reassign_from_user[1,false]
```
3. Check the state of the reassigned tasks
```ruby
Task.open.where(assigned_to: user).count
# => 0
appeals.map do |appeal|
  appeal.structure_render(:assigned_to_id, :status)
end.each { |tree| puts tree }
# in progress Task
# Appeal 60 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     │   └── AttorneyTask 1, cancelled
#     └── JudgeAssignTask 3, assigned

# on hold Task
# Appeal 96 [assigned_to_id, status]
# └── RootTask 4, on_hold
#     ├── JudgeDecisionReviewTask 3, cancelled
#     │   └── AttorneyTask 1, cancelled
#     │       └── HearingClarificationColocatedTask 5, on_hold
#     │           └── HearingClarificationColocatedTask 16, assigned
#     └── JudgeAssignTask 3, assigned

# ✅ AttorneyTasks and JudgeDecisionReviewTasks are cancelled
# ✅ New JudgeAssignTask created
```


TODO: 
- [x] Fix `JudgeDecisionReviewTask` reassign
- [x] Add test instructions for other users
- [x] Reassess tasks with parents assigned to other users
- [x] Determine what to do with downstream children (ticketed #12505)
@araposo-tistatech
Copy link

@hschallhorn,

Can you confirm the below are the only parent/child task associations we will run into in this case?

“PARENT TASK”, “CHILD TASK”
[[“JudgeAssignTask”, “AttorneyTask”],
[“JudgeDispatchReturnTask”, “AttorneyDispatchReturnTask”],
[“BvaDispatchTask”, “JudgeDispatchReturnTask”],
[“QualityReviewTask”, “JudgeQualityReviewTask”],
[“JudgeDecisionReviewTask”, “AttorneyTask”],
[“JudgeDecisionReviewTask”, “AttorneyRewriteTask”],
[“JudgeQualityReviewTask”, “AttorneyQualityReviewTask”]]

@hschallhorn
Copy link
Contributor Author

hschallhorn commented Apr 20, 2020

Here are the scenarios and the number of times the scenario occurs (investigation)
A judge leaves the board and the following tasks are cancelled, leaving orphaned child tasks

  • JudgeAssignTasks with child ColocatedTasks (257)
  • JudgeQualityReviewTasks with child ColocatedTasks (22)
  • JudgeDispatchReturnTasks with child ColocatedTasks (5)
  • JudgeQualityReviewTasks with child AttorneyQualityReviewTasks (86)
  • JudgeDispatchReturnTasks with child AttorneyDispatchReturnTasks (21)

An attorney leaves the board and the following tasks are cancelled, leaving orphaned child tasks

  • AttorneyTasks with child ColocatedTasks (2152)
  • AttorneyRewriteTasks with child ColocatedTasks (127)
  • AttorneyQualityReviewTasks with child ColocatedTasks (18)
  • AttorneyDispatchReturnTasks with child ColocatedTasks (5)

A QualityReview team member leaves the board and the following tasks are cancelled, leaving orphaned child tasks

  • QualityReviewTasks with child JudgeQualityReviewTasks (151)

A judge leaves the board and the following tasks are cancelled, leaving orphaned child tasks

  • ChangeHearingDispositionTasks with child TranscriptionTasks (1)
  • ChangeHearingDispositionTasks with child EvidenceSubmissionWindowTasks (1)

A LitigationSupport team member leaves the board and the following tasks are cancelled, leaving orphaned child tasks

  • VacateMotionMailTasks with child PulacCerulloTask task (1)

@hschallhorn
Copy link
Contributor Author

Suggestions

  1. Move the orphaned child tasks to the parent task
  • JudgeQualityReviewTasks child ColocatedTasks move to parent QualityReviewTask
  • JudgeDispatchReturnTasks with child ColocatedTasks move to parent DispatchTask
  • AttorneyTasks with child ColocatedTasks move to new JudgeAssignTask
  • AttorneyRewriteTasks with child ColocatedTasks move to parent JudgeDecisionReviewTask
  • AttorneyQualityReviewTasks with child ColocatedTasks move to parent JudgeQualityReviewTask
  • AttorneyDispatchReturnTasks with child ColocatedTasks move to parent JudgeDispatchReturnTask
  • ChangeHearingDispositionTasks with child TranscriptionTasks move to parent HearinqTask
  • ChangeHearingDispositionTasks with child EvidenceSubmissionWindowTasks move to parent HearinqTask
  • VacateMotionMailTasks with child PulacCerulloTask task move to parent VacateMotionMailTask
  1. Cancel these tasks as new QR or dispatch tasks will be created for the judge or quality review team member
  • JudgeQualityReviewTasks with child AttorneyQualityReviewTasks
  • JudgeDispatchReturnTasks with child AttorneyDispatchReturnTasks
  • QualityReviewTasks with child JudgeQualityReviewTasks
  1. Still pondering this one as the case moves back to the distribution pool. We don't want to move the admin action to the distribution tasks as that will block it from being distributed to a new judge
  • JudgeAssignTasks with child ColocatedTasks (257)

@araposo-tistatech
Copy link

@hschallhorn can you explain what you mean by the first option "Move the orphaned child tasks to the parent task"? My moving it to the parent task do you mean moving it to the user that has that parent task?

@hschallhorn
Copy link
Contributor Author

Here is an example!

Currently: Say an attorney leaves the board and there is a AttorneyDispatchReturnTask assigned to them that will now be cancelled and it has a downstream OtherColocatedTask (admin action). This would make the parent JudgeDispatchReturnTask "assigned" and able to be assigned to a different attorney, but leaves an open OtherColocatedTask. This could leave us with a colocated task that never gets completed before the appeal is dispatched.

Proposed: "Move the orphaned child tasks to the parent task" means we will make that JudgeDispatchReturnTask the parent of the previously orphaned OtherColocatedTask tasks. VLJ support an continue working this OtherColocatedTask and the judge can assign the a AttorneyDispatchReturnTask to a new attorney once the admin action is completed.

Task trees

BEFORE REASSIGN

Appeal 17635 (direct_review)                    STATUS    ASGN_TO
└── RootTask                                    on_hold   Bva
    └── BvaDispatchTask                         on_hold   BvaDispatch
        └── BvaDispatchTask                     on_hold   VACOWILLIW
            └── JudgeDispatchReturnTask         on_hold   VACOCARACA
                └── AttorneyDispatchReturnTask  on_hold   VACOPARKT
                    └── OtherColocatedTask      on_hold   Colocated
                        └── OtherColocatedTask  assigned  VACOAUSTIT1

AFTER CANCELLING (CURRENT)

Appeal 17635 (direct_review)                    STATUS    ASGN_TO
└── RootTask                                    on_hold   Bva
    └── BvaDispatchTask                         on_hold   BvaDispatch
        └── BvaDispatchTask                     on_hold   VACOWILLIW
            └── JudgeDispatchReturnTask         assigned  VACOCARACA
                └── AttorneyDispatchReturnTask  cancelled VACOPARKT
                    └── OtherColocatedTask      on_hold   Colocated     <- Orphaned 
                        └── OtherColocatedTask  assigned  VACOAUSTIT1   <- tasks

AFTER CANCELLING (PROPOSED)

Appeal 17635 (direct_review)                    STATUS    ASGN_TO
└── RootTask                                    on_hold   Bva
    └── BvaDispatchTask                         on_hold   BvaDispatch
        └── BvaDispatchTask                     on_hold   VACOWILLIW
            └── JudgeDispatchReturnTask         on_hold   VACOCARACA
                ├── AttorneyDispatchReturnTask  cancelled VACOPARKT
                └── OtherColocatedTask          on_hold   Colocated
                    └── OtherColocatedTask      assigned  VACOAUSTIT1

@hschallhorn hschallhorn added Feature: generic-queue Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Type: Investigation labels Apr 22, 2020
@araposo-tistatech
Copy link

@hschallhorn regrets, realized I did not add the Boards thoughts to this ticket. They agree with the first two suggestions and would like for the colocated tasks to remain active even if the cases is assigned back to distribution.

@araposo-tistatech
Copy link

@hschallhorn please let me know if further definition is needed here.

@hschallhorn
Copy link
Contributor Author

would like for the colocated tasks to remain active even if the cases is assigned back to distribution

The open question is where these should move to. If they remain where they are, the case could be dispatched without the work being completed. If the move to under the distribution task, they will block distribution.

@araposo-tistatech
Copy link

Sent email to the Board inquire where the colocated tasks should move to.

@araposo-tistatech
Copy link

araposo-tistatech commented Aug 26, 2020

What is the concern of having the colocated tasks block distribution? The Board feels this might be the better option since the attorney and/or VLJ would not be able to work the case until those are completed anyway, but they will confirm this with the DVCs.

@hschallhorn
Copy link
Contributor Author

That is true! If that's what the board would like moving forward, that works for me! Happy to finally have a resolution for this

@hschallhorn
Copy link
Contributor Author

hschallhorn commented Aug 26, 2020

Resolution:

  1. Move the orphaned child tasks to the parent task
  • JudgeQualityReviewTasks child ColocatedTasks move to parent QualityReviewTask
  • JudgeDispatchReturnTasks with child ColocatedTasks move to parent DispatchTask
  • AttorneyTasks with child ColocatedTasks move to new JudgeAssignTask
  • AttorneyRewriteTasks with child ColocatedTasks move to parent JudgeDecisionReviewTask
  • AttorneyQualityReviewTasks with child ColocatedTasks move to parent JudgeQualityReviewTask
  • AttorneyDispatchReturnTasks with child ColocatedTasks move to parent JudgeDispatchReturnTask
  • ChangeHearingDispositionTasks with child TranscriptionTasks move to parent HearinqTask
  • ChangeHearingDispositionTasks with child EvidenceSubmissionWindowTasks move to parent HearinqTask
  • VacateMotionMailTasks with child PulacCerulloTask task move to parent VacateMotionMailTask
  1. Cancel these tasks as new QR or dispatch tasks will be created for the judge or quality review team member
  • JudgeQualityReviewTasks with child AttorneyQualityReviewTasks
  • JudgeDispatchReturnTasks with child AttorneyDispatchReturnTasks
  • QualityReviewTasks with child JudgeQualityReviewTasks
  1. Move to block new distribution task
  • JudgeAssignTasks with child ColocatedTasks (257)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: generic-queue Priority: High Escalations from Support, blocking issue/NO workaround, or "first in" priority for new work. Product: caseflow-queue Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Team: Echo 🐬 Type: Investigation
Projects
None yet
Development

No branches or pull requests

5 participants
@lomky @lpciferri @hschallhorn @araposo-tistatech and others