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

AOD Docket for Subsequent Appeals #14085

Closed
2 tasks
araposo-tistatech opened this issue Apr 24, 2020 · 22 comments · Fixed by #15237
Closed
2 tasks

AOD Docket for Subsequent Appeals #14085

araposo-tistatech opened this issue Apr 24, 2020 · 22 comments · Fixed by #15237
Assignees
Labels
blocked This is blocked Feature: case-details Priority: Medium Blocking issue w/workaround, or "second in" priority for new work. Product: caseflow-queue release-notes This ticket should get release notes generated on merge Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Team: Echo 🐬 Type: Enhancement Enhancement to an existing feature

Comments

@araposo-tistatech
Copy link

araposo-tistatech commented Apr 24, 2020

User or job story

When an appellant/claimant reaches the age of 75 an AOD needs to be applied to the current and all subsequent cases/claims. If an AOD is for any other categories (weather-related, homelessness, financial distress, etc) the AOD should only apply to the current appeal/claim and not any subsequent.

Acceptance criteria

  • Only age AODs are applied on the claimant level
  • All other categories (weather-related, homelessness, financial distress, etc) should apply the AOD on the appeal/claim level

Background/context

We've found out policy on AOD. There should be an AOD motion for every case that is to be granted AOD status. In legacy cases (VACOLS), this was done by a manual flip of each case to AOD. Sometimes, after consultation, one motion caused more than one case to be granted AOD status, but only as an exception to policy. Therefore each AOD case should have a unique motion granted.

This excludes AOD for age, which is auto granted AOD status by age of the claimant for all cases associated with that claimant.

Technical notes

Other notes

Resources/other links

Slack Convo related to flagged Batteam issue.

@araposo-tistatech araposo-tistatech changed the title AOD Docket AOD Docket for Subsequent Appeals Apr 24, 2020
@hschallhorn hschallhorn added Priority: High Escalations from Support, blocking issue/NO workaround, or "first in" priority for new work. Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Feature: case-details Product: caseflow-queue Team: Echo 🐬 Type: Enhancement Enhancement to an existing feature labels Apr 24, 2020
@ajspotts
Copy link
Contributor

what is this chart?

1 | 
2 | 
3 | |||||||
5 | |||||
8 | 

Why 3?

  • Investigation and understanding context

Why 5?

  • Updating database to have aod motions have a related appeal
  • Leaving in support for aod motions that were created before this change. Don't think there is a way to backfill these appeals

@hschallhorn hschallhorn added Priority: Medium Blocking issue w/workaround, or "second in" priority for new work. release-notes This ticket should get release notes generated on merge and removed Priority: High Escalations from Support, blocking issue/NO workaround, or "first in" priority for new work. labels Apr 30, 2020
@hschallhorn
Copy link
Contributor

hschallhorn commented Apr 30, 2020

Updated priority to medium as a fix for this bug has already been pushed in #14087. Let's reassess if this association change is needed before prioritizing as high.

@yoomlam
Copy link
Contributor

yoomlam commented Jul 29, 2020

A possible solution is described in this comment.

One solution to address #14085 is to add an appeal_id column to advance_on_docket_motions (which will allow many motions to be associated to a single appeal, an n-to-1 relationship). The exception will be age-related AOD motions, where the appeal_id will likely be null since age-related AOD motions are applicable to all open and subsequent appeals (setting the appeal_id to a single non-null value will be misleading since age-related AOD motions can apply to many appeals).

@yoomlam
Copy link
Contributor

yoomlam commented Jul 30, 2020

@hschallhorn If I understand correctly, we still have a problem where subsequent appeals are being incorrectly indicated as AOD due to a granted motion for a prior appeal, correct? In other words, is the only remaining work for this ticket to address the scenario I described?

UPDATE: Hunter replied:

Bingo!

@TedM-BVA
Copy link

TedM-BVA commented Aug 4, 2020

You are correct in that we have a problem understanding the status of appeals generated after an AOD motion is granted for a common claimant. Our understanding is that once an AOD motion is granted, this will not affect subsequently filed appeals under the same claimant. That is expected policy, but is it reflected in the database? Shortest version of our question: where do we find the most direct and accurate AOD status for a given appeal?

@yoomlam
Copy link
Contributor

yoomlam commented Aug 4, 2020

Hi @TedM-BVA!

is it reflected in the database?

No. Currently in Caseflow, AOD motions are associated with the claimant and not with any particular appeal.

where do we find the most direct and accurate AOD status for a given appeal?

To determine if an appeal is AOD, Caseflow checks if there is any granted AOD motion that was created after the appeal's receipt date. I guess this must have been the understanding at the time this was implemented.

Upon completion of this ticket, non-age-related AOD motions will be associated with specific appeals. As a result, you will be able to query the AOD motions table (advance_on_docket_motions) to get all non-age-related AOD motions associated with a specific appeal.

@mikesanford
Copy link

Hi @yoomlam! So, if an AOD motion is granted, all subsequent appeals are AOD'd in the database, but the AOD designation is not necessarily displayed in the UI?

@yoomlam
Copy link
Contributor

yoomlam commented Aug 5, 2020

Good morning @mikesanford. If an AOD motion is granted, all subsequent appeals is currently presented as AOD in the UI. Let me know if you see otherwise. Once this ticket is completed, non-age-related AOD motions will apply to a single appeal and new subsequent appeals without an associated granted AOD motion specific to that appeal should not be displayed as AOD.

@yoomlam
Copy link
Contributor

yoomlam commented Aug 18, 2020

AOD status can be modified on an appeal by editing an AOD Motion in the Case Details page and clicking Edit under TYPE:
image

From this UI, only one AOD motion (regardless of 'disposition' or 'reason') can be associated with an appeal.

@hschallhorn
Copy link
Contributor

Looking into what AOD motions are currently being applied to active appeals and what we might do to link them to their proper appeals

aod_motions = AdvanceOnDocketMotion.granted.where.not(reason: :age)
active_appeals = Appeal.active
active_claimants = Claimant.where(decision_review: active_appeals)
active_people = Person.where(participant_id: active_claimants.pluck(:participant_id))
active_aod_motions = aod_motions.where(person: active_people)
active_aod_motions.count
=> 299

aod_motion_people = Person.where(id: active_aod_motions.pluck(:person_id))
aod_motion_claimants = Claimant.where(participant_id: aod_motion_people.pluck(:participant_id))
aod_motion_appeals = Appeal.where(id: aod_motion_claimants.where(decision_review_type: Appeal.name).pluck(:decision_review_id))
aod_motion_appeals.count
=> 472

aod_motion_claimant_appeal_counts = aod_motion_people.map do |person|
  [person.id, Claimant.where(participant_id: person.participant_id, decision_review_type: Appeal.name).count]
end
aod_motion_claimant_appeal_counts.select { |id, count| count > 1 }.count
=> 108

So we currently have

  • 299 aod motions that could apply to 472 appeals.
  • 108 people that have a non age based aod motion granted with multiple appeals

How do we backfill these motions with the appeals they apply to?

As we previously did not associate aod motions with specific appeals, if a veteran has 2 appeals active at the board and an AOD motion had previously been granted for one of them, if we do not backfill these motions with the appeal they SHOULD have been associated with, there could be appeals that are AOD that are no longer considered to be AOD by our new logic

  • Should we try to update those motions with the appeal they were most likely granted for?
  • How do we resolve which appeal these should be applied to if the claimant has multiple appeals that were active during that time?

@hschallhorn
Copy link
Contributor

hschallhorn commented Aug 24, 2020

Let's pull an actual report on these appeals.

uuids = Appeal.
  active.
  joins(claimants: :person).
  joins("LEFT OUTER JOIN advance_on_docket_motions on advance_on_docket_motions.person_id = people.id").
  where("advance_on_docket_motions.created_at > appeals.established_at").
  where("advance_on_docket_motions.granted = ?", true).
  where("advance_on_docket_motions.reason <> ?", :age).
  pluck(:uuid)
uuids.count
=> 271

Here is a list of only AOD motions that apply to multiple appeals http://query.prod.appeals.va.gov/question/82 As of today there are only 26 motions that "apply" to multiple appeals

Waiting to hear back on what information we'd like from this.

@hschallhorn
Copy link
Contributor

One option is to try to track down the original request in our logs to see if the request was made for this appeal. These requests come in as

[localhost] [ad581605-1596-4836-ba14-97a912adfc19] [localhost] [AOD_USER ] Started POST "/appeals/bce47518-3e0e-4f68-ae00-38e02d030b55/advance_on_docket_motions" for ::1 at 2020-08-24 16:55:15 -0400
[2020-08-24 16:55:15 -0400] Processing by AdvanceOnDocketMotionsController#create as JSON
[2020-08-24 16:55:15 -0400]   Parameters: {"advance_on_docket_motions"=>{"reason"=>"serious_illness", "granted"=>true}, "appeal_id"=>"bce47518-3e0e-4f68-ae00-38e02d030b55"}

@araposo-tistatech
Copy link
Author

One option is to try to track down the original request in our logs to see if the request was made for this appeal. These requests come in as

[localhost] [ad581605-1596-4836-ba14-97a912adfc19] [localhost] [AOD_USER ] Started POST "/appeals/bce47518-3e0e-4f68-ae00-38e02d030b55/advance_on_docket_motions" for ::1 at 2020-08-24 16:55:15 -0400
[2020-08-24 16:55:15 -0400] Processing by AdvanceOnDocketMotionsController#create as JSON
[2020-08-24 16:55:15 -0400]   Parameters: {"advance_on_docket_motions"=>{"reason"=>"serious_illness", "granted"=>true}, "appeal_id"=>"bce47518-3e0e-4f68-ae00-38e02d030b55"}

I like this idea, can we add this information to the report in Metabase? Something like the following:

appeal id (not sure if we allow PII in Metabase)
appellant name
array_agg
motions reason
granted

This should help us identify which appeal was granted a motion for each appellant that we can have the Board verify.

@hschallhorn
Copy link
Contributor

Checking our logs to see if we can write a script to see which appeals these motions were created for.
According to http://query.prod.appeals.va.gov/question/82, appeals with UUIDs of 258d844c-71c0-44c7-b0ea-5e9119d08296 or 1183e71a-3602-4b52-add4-5eac52231f03 could have been the appeal that spawned the AOD request on August 24, 2020 at 5:19 PM

awslogs get dsva-appeals-certification-prod/opt/caseflow-certification/src/log/caseflow-certification.out ALL --start='24/8/2020' --end='25/8/2020' --filter-pattern='Started POST "/appeals/258d844c-71c0-44c7-b0ea-5e9119d08296/advance_on_docket_motions"'
# Nada
awslogs get dsva-appeals-certification-prod/opt/caseflow-certification/src/log/caseflow-certification.out ALL --start='24/8/2020' --end='25/8/2020' --filter-pattern='Started POST "/appeals/1183e71a-3602-4b52-add4-5eac52231f03/advance_on_docket_motions"'
dsva-appeals-certification-prod/opt/caseflow-certification/src/log/caseflow-certification.out i-08a240446d5b357b7 [appeals.cf.ds.va.gov] [4991abbc-f584-43cd-935f-4fcca586dd5e] [10.247.40.41] [vacoEdwarC1 [email protected]] [2020-08-24 13:19:29 -0400] Started POST "/appeals/1183e71a-3602-4b52-add4-5eac52231f03/advance_on_docket_motions" for 127.0.0.1 at 2020-08-24 13:19:29 -0400

Ohhhhh baby

@hschallhorn
Copy link
Contributor

AdvanceOnDocketMotion.group(:appeal_type).count
=> {nil=>1707, "Appeal"=>12}

Up and running!

@hschallhorn
Copy link
Contributor

hschallhorn commented Aug 31, 2020

JUST updated http://query.prod.appeals.va.gov/question/84. Only showing granted motions as granted motions are the only ones that affect more than reporting.

@araposo-tistatech
Copy link
Author

@hschallhorn Mike is requesting we add the "file number" (I believe this is the docket number, but I am confirming with him) to the report so he can go through these. Is that something we can add?

@hschallhorn
Copy link
Contributor

Added!

va-bot pushed a commit that referenced this issue Sep 2, 2020
Resolves #14781

### Description
Prioritize associated cases before bulk assigning tasks.

### Acceptance Criteria
- [ ] Code compiles correctly

Cases are prioritized in the following order for Bulk Assign: 
1. CAVC AOD Cases
2. AOD Cases
3. CAVC Cases
4. Regular appeal stream

### Testing Plan
(See #14501, #14510, and #14523 for reference.)
1. Make BVATWARNER an admin so that the bulk "Assign tasks" button appears
   ```ruby
   OrganizationsUser.make_user_admin(User.find_by(css_id: "BVATWARNER"), HearingsManagement.singleton)
   ```
1. Sign in as BVATWARNER and go to `/organizations/hearings-management`
1. Make some cases AOD or CAVC
   * grant AOD Motion per case -- do [this](#14085 (comment)) as AOD_USER (in an incognito window to avoid logging out BVATWARNER)
   * create a CAVC case (is there a better way?):
      ```ruby
      corres=FactoryBot.create(:correspondent, stafkey:"777");
      folder=FactoryBot.create(:folder, ticknum: "000100777");
      vcase= FactoryBot.create(:case, :type_cavc_remand, :assigned, bfkey: "77777", user: User.find_by(css_id: "BVATWARNER"), correspondent: corres, folder: folder);
      appeal=FactoryBot.create(:legacy_appeal, vacols_case: vcase);

      ht=FactoryBot.create(:hearing_task, appeal: appeal, assigned_by: nil);
      ahdt=FactoryBot.create(:assign_hearing_disposition_task, parent: ht, assigned_by: nil);
      FactoryBot.create(:no_show_hearing_task, parent: ahdt, assigned_by: nil);

      UpdateCachedAppealsAttributesJob.perform_now
      ```
   * create AOD CAVC case (by combining the procedures above)
1. As BVATWARNER, refresh the `/organizations/hearings-management` page to see AOD and CAVC cases
1. Perform bulk "Assign tasks" with "No Show Hearing Task" type and ensure priority cases are assigned first (see the "Assigned" tab)
@araposo-tistatech
Copy link
Author

@hschallhorn please see below Mike S. response on the list of appeals with AOD motions applied to multiple appeals:

"The vase majority are appeals that were cancelled by the Clerk's office and properly redocketed. The others were ones where the Veteran simply had multiple appeals pending at the time the AOD motion was submitted. Since AOD was granted, they should retain their AOD status.

All of that said, all the appeals listed on the spreadsheet should maintain their AOD status. Leaving that status on cancelled appeals will have no practical effect as they aren't really appeals anymore."

@hschallhorn
Copy link
Contributor

Let's start associating these motions with appeals!

First question, can aod motions apply to legacy appeals?

No! Here's screenshots of the "Edit" buton an aod team member would hit to create an AOD motion for an appeal. Appears only for ama appeals.

Legacy AMA
Screen Shot 2020-09-14 at 5 30 02 PM Screen Shot 2020-09-14 at 5 29 52 PM

Code that controls this:

{!appeal.isLegacyAppeal && this.props.canEditAod && (

Let's start by looking at appeals that are 1 to 1 with aod motions.

motion_id_to_single_appeal_ids = Appeal.
  joins(claimants: :person).
  joins("LEFT OUTER JOIN advance_on_docket_motions ON advance_on_docket_motions.person_id = people.id").
  where("advance_on_docket_motions.created_at > appeals.established_at").
  group("advance_on_docket_motions.id").
  having("COUNT(appeals.uuid) = 1").
  pluck("advance_on_docket_motions.id, (array_agg(appeals.id))[1]")

motion_id_to_single_appeal_ids.count
=> 1587

# Matches http://query.prod.appeals.va.gov/question/93

motion_id, appeal_id = motion_id_to_single_appeal_ids.first
AdvanceOnDocketMotion.find(motion_id).update!(appeal_id: appeal_id, appeal_type: Appeal.name)
AdvanceOnDocketMotion.find(motion_id).appeal.uuid
=> "4ce40ce4-60d1-4505-b483-704b1ca5535c"

# Also matches http://query.prod.appeals.va.gov/question/93
motion_id_to_single_appeal_ids.each do |motion_id, appeal_id|
  AdvanceOnDocketMotion.find(motion_id).update!(appeal_id: appeal_id, appeal_type: Appeal.name)
end

AdvanceOnDocketMotion.where(appeal_id: nil).count
=> 177

motion_id_to_multiple_appeal_ids = Appeal.
  joins(claimants: :person).
  joins("LEFT OUTER JOIN advance_on_docket_motions ON advance_on_docket_motions.person_id = people.id").
  where("advance_on_docket_motions.created_at > appeals.established_at AND  advance_on_docket_motions.appeal_id IS NULL").
  group("advance_on_docket_motions.id").
  having("COUNT(appeals.uuid) > 1").
  pluck("advance_on_docket_motions.id, array_agg(appeals.id)").
  uniq { |_, appeal_ids| appeal_ids }

motion_id_to_multiple_appeal_ids.count
=> 173

motion_id, appeal_ids =  motion_id_to_multiple_appeal_ids.detect { |id, _| id == 84 }
motion = AdvanceOnDocketMotion.find(motion_id)
motion.update!(appeal_id: appeal_ids.shift, appeal_type: Appeal.name)
appeal_ids.each { |appeal_id| motion.dup.tap { |dupe| dupe.update!(appeal_id: appeal_id) } }

AdvanceOnDocketMotion.where(appeal_id: appeal_ids)
[#<AdvanceOnDocketMotion:0x000000000a78ba68
  id: 84,
  person_id: 1503,
  user_id: 2122,
  reason: "financial_distress",
  created_at: Tue, 28 May 2019 12:56:25 UTC +00:00,
  updated_at: Mon, 14 Sep 2020 22:11:52 UTC +00:00,
  granted: false,
  appeal_type: "Appeal",
  appeal_id: 1672>,
 #<AdvanceOnDocketMotion:0x000000000a78b838
  id: 1799,
  person_id: 1503,
  user_id: 2122,
  reason: "financial_distress",
  created_at: Mon, 14 Sep 2020 22:12:09 UTC +00:00,
  updated_at: Mon, 14 Sep 2020 22:12:09 UTC +00:00,
  granted: false,
  appeal_type: "Appeal",
  appeal_id: 2897>,
 #<AdvanceOnDocketMotion:0x000000000a78b590
  id: 1800,
  person_id: 1503,
  user_id: 2122,
  reason: "financial_distress",
  created_at: Mon, 14 Sep 2020 22:12:09 UTC +00:00,
  updated_at: Mon, 14 Sep 2020 22:12:09 UTC +00:00,
  granted: false,
  appeal_type: "Appeal",
  appeal_id: 1849>]

motion_id_to_multiple_appeal_ids.each do |motion_id, appeal_ids|
  motion = AdvanceOnDocketMotion.find(motion_id)
  motion.update!(appeal_id: appeal_ids.shift, appeal_type: Appeal.name)
  appeal_ids.each { |appeal_id| motion.dup.tap { |dupe| dupe.update!(appeal_id: appeal_id) } }
end

AdvanceOnDocketMotion.where(appeal_id: nil).count
=> 3

leftover_motions = AdvanceOnDocketMotion.where(appeal_id: nil)
leftover_motions.count
=> 3

motion = leftover_motions.first
person = motion.person
claimants = Claimant.where(participant_id: person.participant_id)
=> #<ActiveRecord::Relation []>

motion = leftover_motions.second
person = motion.person
claimants = Claimant.where(participant_id: person.participant_id)
=> #<ActiveRecord::Relation [#<..., decision_review_type: "SupplementalClaim", ...>]

motion = leftover_motions.third
=> #<..., person_id: nil, ...>

Down to 3 without an associated appeal. Open to deleting these as they will not affect any appeals' aod status.

@yoomlam
Copy link
Contributor

yoomlam commented Sep 14, 2020

I concur. They can be deleted since their reasons are all nil and they don't have any affect:

leftover_motions.pluck(:id, :reason, :granted)
=> [[93, nil, true], [94, nil, true], [1290, nil, nil]]

va-bot pushed a commit that referenced this issue Sep 15, 2020
Resolves #14085

### Description
Remove old check that allowed a motion to be associated with an appeal because the motion was created after the appeal's receipt date. We have now [associated every motion with an appeal](#14085 (comment)) and this incorrect check should be removed.

### Acceptance Criteria
Appeals are only considered aod due to motion if there is an 
- [ ] age related motion that applies to any appeal with the same claimant
- [ ] any other reason related motion that applies to that exact appeal

### Testing Plan
1. Sign in as AOD_USER and find any non aod ama case
```ruby
appeal = Appeal.find_by(uuid: "173b6ce2-070c-4eec-a463-301f8f18c70e")
appeal.aod?
=> false
```
2. Find the "Edit" link next to the appeal stream type
1. Grant an AOD motion for any reason other than age
```ruby
appeal.aod?
=> true
```
4. Remove the appeal from the aod motion
```ruby
motion = AdvanceOnDocketMotion.find_by(appeal: appeal)
motion.update_attribute('appeal_id', nil)
AdvanceOnDocketMotion.find_by(appeal: appeal)
=> nil
appeal.aod?
=> false
AdvanceOnDocketMotion.first.created_at > appeal.receipt_date
=> true
```
5. Ensure aod does not show up in the ui by reloading case details
@hschallhorn
Copy link
Contributor

Noticed we have some dupes. Investigating

dupe_appeal_ids = AdvanceOnDocketMotion.having("COUNT(appeal_id) > 1").group(:appeal_id).count.keys
dupe_appeal_ids.count
=> 27

id_and_motions = dupe_appeal_ids.map { |id| [id, AdvanceOnDocketMotion.where(appeal_id: id)] }
id_and_motion_attrs =  id_and_motions.map { |id, motions| [id, motions.pluck(:person_id, :granted, :reason)] }
id_and_uniq_motions =  id_and_motion_attrs.map { |id, motion_attrs| [id, motion_attrs.uniq.count] }.sort_by(&:second).to_h
{31548=>1,
 34934=>1,
 43588=>1,
 24833=>1,
 53223=>1,
 4184=>1,
 8530=>1,
 7592=>1,
 17852=>1,
 8932=>1,
 6392=>1,
 34344=>1,
 6829=>1,
 29421=>1,
 54563=>1,
 72484=>1,
 17984=>2,
 9977=>2,
 18821=>2,
 7994=>2,
 872=>2,
 8002=>2,
 9036=>2,
 8007=>2,
 883=>2,
 2958=>2,
 27541=>2}

# Let's delete dupes with the same attrs
uniq_motions_appeal_ids = id_and_uniq_motions.select { |_, uniq_motions_count| uniq_motions_count == 1 }.to_h.keys
uniq_motions_appeal_ids.each { |id| AdvanceOnDocketMotion.where(appeal_id: id).last.destroy! }
AdvanceOnDocketMotion.where(appeal_id: uniq_motions_appeal_ids).having("COUNT(appeal_id) > 1").group(:appeal_id).count.count
=> 0

# Lets see if these fit into the two following scenarios
# 1. One of the motions is denied while the other is granted -> Should keep the newest motion
# 2. Both of the motions are granted for the same person -> Should remove one of the motions
# 3. One of the motions is age based -> Should keep both motions as age will apply to all appeals
# 4. One of the motions is for another person -> Should keep both
dupe_appeal_ids = AdvanceOnDocketMotion.having("COUNT(appeal_id) > 1").group(:appeal_id).count.keys
dupe_appeal_ids.count
=> 11

id_and_motions = dupe_appeal_ids.map { |id| [id, AdvanceOnDocketMotion.where(appeal_id: id)] }
id_and_motion_attrs =  id_and_motions.map { |id, motions| [id, motions.pluck(:person_id, :granted, :reason)] }
id_and_motion_attrs = id_and_motion_attrs.reject { |_, motions| motions.map(&:third).any? { |reason| reason == "age" } }
id_and_uniq_motions =  id_and_motion_attrs.map { |id, motion_attrs| [id, motion_attrs.uniq.count] }.sort_by(&:second).to_h
=> {17984=>2, 7994=>2, 872=>2, 8002=>2, 8007=>2, 883=>2, 2958=>2, 27541=>2}

# 1. One of the motions is denied while the other is granted -> Should keep the newest motion
# Note, both of these went from denied -> granted so the appeals will both retain their aod status
appeals_with_deny_and_grant = id_and_motion_attrs.select { |_, motion_attrs| motion_attrs.first.first == motion_attrs.last.first && motion_attrs.first.second != motion_attrs.last.second }.to_h.keys
appeals_with_deny_and_grant.each { |id| AdvanceOnDocketMotion.order(:id).where(appeal_id: id).first.destroy! }
Appeal.where(id:  appeals_with_deny_and_grant).map(&:aod?).uniq
=> [true]

# 2. Both of the motions are granted for the same person -> Should remove all but one of the motions
appeals_with_both_granted = appeals_with_all_granted = id_and_motion_attrs.select { |_, motion_attrs| motion_attrs.map(&:first).uniq.count == 1 && motion_attrs.map(&:second).uniq.count == 1 }.to_h.keys
appeals_with_both_granted_with_motions = id_and_motions.select { |id, _| appeals_with_both_granted.include? id }
appeals_with_both_granted_with_motions.each do |id, motions|
  motions = motions.to_a
  motions.pop
  motions.each(&:destroy!)
end

dupe_appeal_ids = AdvanceOnDocketMotion.having("COUNT(appeal_id) > 1").group(:appeal_id).count.keys
dupe_appeal_ids.count
=> 1
id_and_motions = dupe_appeal_ids.map { |id| [id, AdvanceOnDocketMotion.where(appeal_id: id)] }
pp  id_and_motions.map { |id, motions| [id, motions.pluck(:person_id, :granted, :reason)] }
=> [[18821, [[117375, false, "other"], [117375, false, "age"]]]]

# 3. One of the motions is age based -> Should keep both motions as age will apply to all appeals
# Nothing to do!

sahalliburton added a commit that referenced this issue Sep 16, 2020
* add diagnostic code for 7632 (#15144)

Resolves the issue described here: https://dsva.slack.com/archives/CHX8FMP28/p1599047514117800

### Description

Add diagnostic code for 7632

Found diagnostic code description by doing the following:

```
> codes = BGSService.new.client.share_standard_data.find_diagnostic_codes
> codes[:return][:types].select { |c| c[:code] == '7632' }
```

* PRs alert when we touch a Service integration (#15133)

* PRs alert when we touch a Service integration

* Better wording!

Co-authored-by: Tomas Apodaca <[email protected]>

Co-authored-by: Tomas Apodaca <[email protected]>
Co-authored-by: va-bot <[email protected]>

* Drops the unused contentions from the Legacy Appeal (#15146)

Connects #14717

### Description
Drops the unused contentions from the Legacy Appeal

### Acceptance Criteria
- [ ] Code compiles correctly
- [ ] Tests pass

### Testing Plan
1. n/a

### Database Changes
*Only for Schema Changes*

* [ ] ~Timestamps (created_at, updated_at) for new tables~
* [ ] ~Column comments updated~
* [x] Verify that `migrate:rollback` works as desired ([`change` supported functions](https://edgeguides.rubyonrails.org/active_record_migrations.html#using-the-change-method))
* [ ] ~Query profiling performed (eyeball Rails log, check bullet and fasterer output)~
* [ ] ~Appropriate indexes added (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)~
* [x] DB schema docs updated with `make docs` (after running `make migrate`)
* [x] #appeals-schema notified with summary and link to this PR

* Prioritize AOD and CAVC cases during Bulk Assignment (#15125)

Resolves #14781

### Description
Prioritize associated cases before bulk assigning tasks.

### Acceptance Criteria
- [ ] Code compiles correctly

Cases are prioritized in the following order for Bulk Assign: 
1. CAVC AOD Cases
2. AOD Cases
3. CAVC Cases
4. Regular appeal stream

### Testing Plan
(See #14501, #14510, and #14523 for reference.)
1. Make BVATWARNER an admin so that the bulk "Assign tasks" button appears
   ```ruby
   OrganizationsUser.make_user_admin(User.find_by(css_id: "BVATWARNER"), HearingsManagement.singleton)
   ```
1. Sign in as BVATWARNER and go to `/organizations/hearings-management`
1. Make some cases AOD or CAVC
   * grant AOD Motion per case -- do [this](#14085 (comment)) as AOD_USER (in an incognito window to avoid logging out BVATWARNER)
   * create a CAVC case (is there a better way?):
      ```ruby
      corres=FactoryBot.create(:correspondent, stafkey:"777");
      folder=FactoryBot.create(:folder, ticknum: "000100777");
      vcase= FactoryBot.create(:case, :type_cavc_remand, :assigned, bfkey: "77777", user: User.find_by(css_id: "BVATWARNER"), correspondent: corres, folder: folder);
      appeal=FactoryBot.create(:legacy_appeal, vacols_case: vcase);

      ht=FactoryBot.create(:hearing_task, appeal: appeal, assigned_by: nil);
      ahdt=FactoryBot.create(:assign_hearing_disposition_task, parent: ht, assigned_by: nil);
      FactoryBot.create(:no_show_hearing_task, parent: ahdt, assigned_by: nil);

      UpdateCachedAppealsAttributesJob.perform_now
      ```
   * create AOD CAVC case (by combining the procedures above)
1. As BVATWARNER, refresh the `/organizations/hearings-management` page to see AOD and CAVC cases
1. Perform bulk "Assign tasks" with "No Show Hearing Task" type and ensure priority cases are assigned first (see the "Assigned" tab)

* Properly check feature toggle for backlog bust (#15151)

Feature toggles 🙄 

- [ ]  tests pass

* Removes ignore columns from LegacyAppeal Model (#15147)

Resolves #14714 

### Description
Columns are dropped in #15146 so this PR cleans up the ignore columns

### Acceptance Criteria
- [ ] Code compiles correctly
- [ ] Tests Pass

* Team management page updates (#14926)

* Team management page updates

* Order orgs by name

* Remove url for non vsos

* Remove url heading

* Pull changes up

* Fix merge

* Show dvc full name

* Missing admin path!

* Allow DVCs to view the team management page (#14928)

* Allow but restrict team management page for DVCs

* Fix logic to handle dvcs on the bva team

* Testing

* remove focus

* Feature tests

* tests

* Code climate maybe

* Method naming

* Code climate

* Fix tests

* check dvc team permissions

* Fix todo

* Fix todos

* fix tests

* Fix tests

* Allow DVCs to toggle accepts_priority_pushed_cases from the front end (#14932)

* Allow DVCs to toggle priority push cases for judge teams

* Add test for bva admin

* Wait for toggle to be checked

* Better matcher

* Alignment!

* Code climate?

* Code climate

* Fix todos

* Fix tests

* Fix tests

* update hearing room labels (#15149)

Resolves #15143

### Description
Updates the hearing room labels with room number, replacing the temporary names we'd been using.

* should be method on Raven (#15174)

From production:

```
NoMethodError (undefined method `capture_exception' for #<LegacyHearing...>)
app/models/legacy_hearing.rb:318:in `rescue in vacols_hearing_exists?'
```

### Description

Use `Raven.capture_exception`

* Updates to EditContentionTitle (#15152)

Connects #14994

### Description
This rewrites `EditContentionTitle` as a functional component, and adds Jest tests and Storybook stories. This rewrite also fixes the issue whereby state would not get updated even if the issue prop did, which meant that the initial value displayed in the textarea would sometimes not match the issue with which it was associated (if another issue had been removed).

### Acceptance Criteria
- [ ] Code compiles correctly
- [ ] Value in textarea is set correctly when opened, even if other issues in list have been removed

### Testing Plan
1. Add `binding.pry` to line 1594 of spec/feature/intake/higher_level_review/edit_spec.rb
2. ```bundle exec rspec spec/feature/intake/higher_level_review/edit_spec.rb:1594```
3. Add another issue (either one, and say "Yes" to request extension)
4. Click "Edit Contention Title" on the new issue you added
5. Verify the value in `textarea` is correct
6. Remove one of the two (noneditable) apportionment ratings up above
7. Edit the new issue again
  - on master the `textarea` will have value of the other editable issue ("Right Knee")
  - with this fix, that should show the correct value

* Bump dompurify from 2.0.3 to 2.0.7 in /client (#15177)

Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.0.3 to 2.0.7.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](cure53/DOMPurify@2.0.3...2.0.7)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump node-sass from 4.13.0 to 4.13.1 in /client (#15176)

Bumps [node-sass](https://github.com/sass/node-sass) from 4.13.0 to 4.13.1.
- [Release notes](https://github.com/sass/node-sass/releases)
- [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md)
- [Commits](sass/node-sass@v4.13.0...v4.13.1)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alisa Nguyen <[email protected]>

* Bug | Fix code for cancelling an EP in BGS (#15093)

Connects #14912
### Description
When cancelling a claim, the ruby-bgs method has hardcoded values for the payee_code and benefit_type arguments.  This is causing an error when cancelling a claim if the values for the claim don't match the hardcoded values.

### Acceptance Criteria
- [x] Update ruby-bgs repo to accept arguments for these fields, and set the current data as the default value
  - [x] payee_code: "00"
  - [x] benefit_type: "1"
- [x] Update `BGSService.cancel_end_product to accept these arguments`
- [x] Update the EndProductEstablishment model to send these arguments based on the EPEs data in the `cancel!` method.
- [x] Add a test that we're sending these arguments to BGSService

* Add comment to special_issue_lists table (#15178)

### Description
Add comment to `special_issue_lists` table to explain why we have Special Issues boolean columns in both the `legacy_appeals` and `special_issue_lists` tables.

### Acceptance Criteria
- [x] Code compiles correctly

### Database Changes
*Only for Schema Changes*

* [x] Column comments updated
* [x] Verify that `migrate:rollback` works as desired ([`change` supported functions](https://edgeguides.rubyonrails.org/active_record_migrations.html#using-the-change-method))
* [x] DB schema docs updated with `make docs` (after running `make migrate`)
* [x] #appeals-schema notified with summary and link to this PR

Not needed:
* [ ] Timestamps (created_at, updated_at) for new tables
* [ ] Query profiling performed (eyeball Rails log, check bullet and fasterer output)
* [ ] Appropriate indexes added (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)

* Update Appeal type label on claim details page (#15153)

Resolves #15020

### Description
Update appeal type label in COPY.json 

### Acceptance Criteria
- [ ] Code compiles correctly
- [ ] Type label for appeal type says 'Appeal Stream Type' on Claim Details page 

### Testing Plan
1. Choose user with edit hearing details permissions
2. Click Mail Intake tab
3. Click a hearing day 
4. Click the ID link underneath a veteran's name 
5. Verify that the case title details header now includes 'Appeal Stream Type'

### User Facing Changes
 - [ ] Screenshots of UI changes added to PR & Original Issue

 BEFORE|AFTER
 ---|---
<img width="1069" alt="Screen Shot 2020-09-02 at 3 52 00 PM" src="https://user-images.githubusercontent.com/68879427/92046341-2a7c6100-ed37-11ea-861a-8a1c96721806.png"> | <img width="1064" alt="Screen Shot 2020-09-02 at 3 53 51 PM" src="https://user-images.githubusercontent.com/68879427/92046355-2f411500-ed37-11ea-8cd3-5ce934290e6c.png">


### Storybook Story
*For Frontend (Presentationa) Components*
* [ ] Add a [Storybook](https://github.com/department-of-veterans-affairs/caseflow/wiki/Documenting-React-Components-with-Storybook) file alongside the component file (e.g. create `MyComponent.stories.js` alongside `MyComponent.jsx`)
* [ ] Give it a title that reflects the component's location within the overall Caseflow hierarchy 
* [ ] Write a separate story (within the same file) for each discrete variation of the component

* Business Line | Update Copy For Completed Tab (#15116)

* copy text updated

* copy text showing

* added spacing to copy

* circleci fixes

* lint fixes

* lint fix

* spec test and updated copy text

* fixed spec spacing

* more spec spacing changes

* requested changes

* delete dump file

* Missing Ratings | Add current rating profile endpoint to Caseflow (#15172)

Connects #14839 

### Description
This PR integrates the new current rating endpoint from ruby-bgs into Caseflow, and adds a new model for working with data returned by this endpoint.

### Acceptance Criteria
- [x] Add find_current_rating_profile_by_ptcpnt_id to BGSService
- [x] Add a CurrentRating model which can fetch the (single) current rating for a veteran
  - [x] The same "self" classes in the Rating model aren't needed, but the same instance methods are needed
- [x] Add to BGSService fakes

### Testing Plan
- New spec added: `current_rating_spec.rb`
- Testing locally
  - The fake rating store has a list of available participant IDs: `BGSService.rating_store.all_keys`
  - Use `CurrentRating.fetch_by_participant_id` to fetch an instance and play around with it
  - Check the behavior for a non-existent participant ID
- Testing in unmodified UAT (to confirm everything is safe) and prod (to see representative data)
  - Paste the contents of `current_rating.rb` into Rails console
  - Inside a `class ExternalApi::BGSService`/`end` block:
    - Paste the contents of the `def find_current_rating_profile_by_ptcpnt_id` definition
  - Use `CurrentRating.fetch_by_participant_id` with a bunch of `Veteran.participant_id`s and play around. The new test code can provide some inspiration.
  - Check the behavior for a non-existent participant ID

### Code Documentation Updates
- [x] Add or update code comments at the top of the class, module, and/or component.

* add migration inheritance requirement (#15015)

### Description
Adds requirement to the Database Changes checklist in the pull request template; that migrations inherit from the safe [`Caseflow::Migration` class](https://github.com/department-of-veterans-affairs/caseflow/blob/master/lib/caseflow/migration.rb) rather than the default `ActiveRecord::Migration` class.

* Bump http-proxy from 1.17.0 to 1.18.1 in /client (#15181)

Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.17.0 to 1.18.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md">http-proxy's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/http-party/node-http-proxy/compare/1.18.0...v1.18.1">v1.18.1</a> - 2020-05-17</h2>
<h3>Merged</h3>
<ul>
<li>Skip sending the proxyReq event when the expect header is present <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1447"><code>[#1447](https://github.com/http-party/node-http-proxy/issues/1447)</code></a></li>
<li>Remove node6 support, add node12 to build <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1397"><code>[#1397](https://github.com/http-party/node-http-proxy/issues/1397)</code></a></li>
</ul>
<h2><a href="https://github.com/http-party/node-http-proxy/compare/1.17.0...1.18.0">1.18.0</a> - 2019-09-18</h2>
<h3>Merged</h3>
<ul>
<li>Added in auto-changelog module set to keepachangelog format <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1373"><code>[#1373](https://github.com/http-party/node-http-proxy/issues/1373)</code></a></li>
<li>fix 'Modify Response' readme section to avoid unnecessary array copying <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1300"><code>[#1300](https://github.com/http-party/node-http-proxy/issues/1300)</code></a></li>
<li>Fix incorrect target name for reverse proxy example <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1135"><code>[#1135](https://github.com/http-party/node-http-proxy/issues/1135)</code></a></li>
<li>Fix modify response middleware example <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1139"><code>[#1139](https://github.com/http-party/node-http-proxy/issues/1139)</code></a></li>
<li>[dist] Update dependency async to v3 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1359"><code>[#1359](https://github.com/http-party/node-http-proxy/issues/1359)</code></a></li>
<li>Fix path to local http-proxy in examples. <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1072"><code>[#1072](https://github.com/http-party/node-http-proxy/issues/1072)</code></a></li>
<li>fix reverse-proxy example require path <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1067"><code>[#1067](https://github.com/http-party/node-http-proxy/issues/1067)</code></a></li>
<li>Update README.md <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/970"><code>[#970](https://github.com/http-party/node-http-proxy/issues/970)</code></a></li>
<li>[dist] Update dependency request to ~2.88.0 [SECURITY] <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1357"><code>[#1357](https://github.com/http-party/node-http-proxy/issues/1357)</code></a></li>
<li>[dist] Update dependency eventemitter3 to v4 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1365"><code>[#1365](https://github.com/http-party/node-http-proxy/issues/1365)</code></a></li>
<li>[dist] Update dependency colors to v1 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1360"><code>[#1360](https://github.com/http-party/node-http-proxy/issues/1360)</code></a></li>
<li>[dist] Update all non-major dependencies <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1356"><code>[#1356](https://github.com/http-party/node-http-proxy/issues/1356)</code></a></li>
<li>[dist] Update dependency agentkeepalive to v4 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1358"><code>[#1358](https://github.com/http-party/node-http-proxy/issues/1358)</code></a></li>
<li>[dist] Update dependency nyc to v14 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1367"><code>[#1367](https://github.com/http-party/node-http-proxy/issues/1367)</code></a></li>
<li>[dist] Update dependency concat-stream to v2 <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1363"><code>[#1363](https://github.com/http-party/node-http-proxy/issues/1363)</code></a></li>
<li>x-forwarded-host overwrite for mutli level proxies <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1267"><code>[#1267](https://github.com/http-party/node-http-proxy/issues/1267)</code></a></li>
<li>[refactor doc] Complete rename to http-party org. <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1362"><code>[#1362](https://github.com/http-party/node-http-proxy/issues/1362)</code></a></li>
<li>Highlight correct lines for createProxyServer <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1117"><code>[#1117](https://github.com/http-party/node-http-proxy/issues/1117)</code></a></li>
<li>Fix docs for rewrite options - 201 also handled <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1147"><code>[#1147](https://github.com/http-party/node-http-proxy/issues/1147)</code></a></li>
<li>Update .nyc_output <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1339"><code>[#1339](https://github.com/http-party/node-http-proxy/issues/1339)</code></a></li>
<li>Configure Renovate <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1355"><code>[#1355](https://github.com/http-party/node-http-proxy/issues/1355)</code></a></li>
<li>[examples] Restream body before proxying, support for Content-Type of application/x-www-form-urlencoded <a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/pull/1264"><code>[#1264](https://github.com/http-party/node-http-proxy/issues/1264)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>[dist] New test fixtures. <a href="https://github.com/http-party/node-http-proxy/commit/7e4a0e511bc30c059216860153301de2cdd1e97f"><code>7e4a0e5</code></a></li>
<li>[dist] End of an era. <a href="https://github.com/http-party/node-http-proxy/commit/a9b09cce43f072db99fb5170030a05536177ccb7"><code>a9b09cc</code></a></li>
<li>[dist] Version bump. 1.18.0 <a href="https://github.com/http-party/node-http-proxy/commit/9bbe486c5efcc356fb4d189ef38eee275bbde345"><code>9bbe486</code></a></li>
<li>[fix] Latest versions. <a href="https://github.com/http-party/node-http-proxy/commit/59c4403e9dc15ab9b19ee2a3f4aecbfc6c3d94c4"><code>59c4403</code></a></li>
<li>[fix test] Update tests. <a href="https://github.com/http-party/node-http-proxy/commit/dd1d08b6319d1def729554446a5b0176978a8dad"><code>dd1d08b</code></a></li>
<li>[dist] Update dependency ws to v3 [SECURITY] <a href="https://github.com/http-party/node-http-proxy/commit/b00911c93740a00c5cfbacbb91565cb6912ed255"><code>b00911c</code></a></li>
<li>[dist] .gitattributes all the things. <a href="https://github.com/http-party/node-http-proxy/commit/fc93520d741ec80be8ae31ca005f3e9c199e330e"><code>fc93520</code></a></li>
<li>[dist] Regenerate package-lock.json. <a href="https://github.com/http-party/node-http-proxy/commit/16d4f8a95162b2e2e4ee6657c500f1208c044b2d"><code>16d4f8a</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/http-party/node-http-proxy/commit/9b96cd725127a024dabebec6c7ea8c807272223d"><code>9b96cd7</code></a> 1.18.1</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/335aeeba2f0c286dc89c402eeb76af47834c89a3"><code>335aeeb</code></a> Skip sending the proxyReq event when the expect header is present (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1447">#1447</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/dba39668ba4c9ad461316e834b2d64b77e1ca88e"><code>dba3966</code></a> Remove node6 support, add node12 to build (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1397">#1397</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/9bbe486c5efcc356fb4d189ef38eee275bbde345"><code>9bbe486</code></a> [dist] Version bump. 1.18.0</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/6e4bef4d1cd96e7a284717941e0fc274acbd3712"><code>6e4bef4</code></a> Added in auto-changelog module set to keepachangelog format (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1373">#1373</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/d05624167ce75e860770c13afeacec2ce0f67add"><code>d056241</code></a> fix 'Modify Response' readme section to avoid unnecessary array copying (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1300">#1300</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/244303b994525684e1ec8dff2e8055f89b62b1ee"><code>244303b</code></a> Fix incorrect target name for reverse proxy example (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1135">#1135</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/b4028ba78bc4616e6969e0e66b0fe4634849b68b"><code>b4028ba</code></a> Fix modify response middleware example (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1139">#1139</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/77a98159d2da0f20a03e2819c79662f36069f234"><code>77a9815</code></a> [dist] Update dependency async to v3 (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1359">#1359</a>)</li>
<li><a href="https://github.com/http-party/node-http-proxy/commit/c662f9ebcd8d623db374dbc7bef231b2b0af0c3a"><code>c662f9e</code></a> Fix path to local http-proxy in examples. (<a href="https://github-redirect.dependabot.com/http-party/node-http-proxy/issues/1072">#1072</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/http-party/node-http-proxy/compare/1.17.0...1.18.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=http-proxy&package-manager=npm_and_yarn&previous-version=1.17.0&new-version=1.18.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/configuring-github-dependabot-security-updates)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/department-of-veterans-affairs/caseflow/network/alerts).

</details>

* Capitalize Veteran in add claimant modal (#15139)

* Tech spec for recording hearing request type (#15045)

Resolves #14941 

### Description
This tech spec describes the back end changes necessary to "convert" requests for Travel Board hearings in VACOLS into requests for video or virtual hearings in Caseflow.

* Display hearing type on case details (#15145)

Resolves #15021

### Description
- create a new method `readable_hearing_request_type` on `Appeal` and `LegacyAppeal` which returns `Central`, `Video`, `Travel` or `nil` and serialize the method
- display the type on case details page depending on the docket type
- create a basic story for `CaseTitleDetails` component
- write unit tests in `appeal_spec` and feature tests in `case_details_spec`

### Acceptance Criteria
- [x] the hearing type displays for ama and legacy appeals in the hearing docket
- [x] update (or create) a storybook component for the CaseTitleDetails component
- [x] update (or create) a feature test for the correct values in the new section

### User Facing Changes
 - [x] Screenshots of UI changes added to PR & Original Issue

 BEFORE|AFTER
 ---|---
<img width="626" alt="Screen Shot 2020-09-03 at 7 37 25 PM" src="https://user-images.githubusercontent.com/20735998/92183642-02672d80-ee1d-11ea-923c-a9a80c09fbd7.png">| <img width="662" alt="Screen Shot 2020-09-03 at 7 36 37 PM" src="https://user-images.githubusercontent.com/20735998/92183641-02672d80-ee1d-11ea-937f-6f3ff3ced9e5.png">

### Storybook Story
*For Frontend (Presentationa) Components*
* [x] Add a [Storybook](https://github.com/department-of-veterans-affairs/caseflow/wiki/Documenting-React-Components-with-Storybook) file alongside the component file (e.g. create `MyComponent.stories.js` alongside `MyComponent.jsx`)
* [x] Give it a title that reflects the component's location within the overall Caseflow hierarchy 
* [x] Write a separate story (within the same file) for each discrete variation of the component

### Testing Plan
- Login as `BVASYELLOW` or `BVAAABSHIRE`
- Go to `/queue` and pick any cases to look at the case details page

* Show all attorneys in MTV dropdown for judges with no team (#15185)

* Show all attorneys in MTV dropdown

* Only show all attorneys for judges with no team

* Attorney Fees | Add Clearable prop to searchable dropdown (#15165)

* isClearable prop switched to true

* jest tests updated

* updated defined prop

* corrected jest test

* set isClearable prop to only be true on AddClaimantModal

* updated jest test

* Write hearing type to VACOLS when converting legacy hearings (#15184)

Resolves #15065

### Description
Support for writing request type (or HEARSCHED.HEARING_TYPE) to VACOLS when converting legacy hearings to and from virtual.

### Database Changes

* [x] Column comments updated
* [x] Have your migration classes inherit from `Caseflow::Migration`, especially when adding indexes (use `add_safe_index`)
* [x] Verify that `migrate:rollback` works as desired ([`change` supported functions](https://edgeguides.rubyonrails.org/active_record_migrations.html#using-the-change-method))
* [x] Query profiling performed (eyeball Rails log, check bullet and fasterer output)
* [x] Appropriate indexes added (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)
* [x] DB schema docs updated with `make docs` (after running `make migrate`)
* [x] #appeals-schema notified with summary and link to this PR

* Fix contested typo in Issue Category Dropdown (#15182)

* Fix contested typo in issue categories

* Fix contested typo in issue categories

* Remove focus true

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

Connects #14911

### Description
- change the flow in `create_change_hearing_disposition_task` of `ScheduleHearingTask` so that it does not trigger a location change for legacy appeals
- write tests

### Acceptance Criteria
- [x]  Refactor this flow so that the appeal's VACOLS location isn't changed from CASEFLOW if we intend to add new open tasks.

### Testing Plan
1. Run test file `spec/tasks/schedule_hearing_task_spec.rb`

* Add Sentry ID from Raven to data integrity job Slack message (#15192)

### Description
Inspired by [this](https://dsva.slack.com/archives/CN3FQR4A1/p1599647433017300) exceptionally uninformative Slack message about some error with LegacyAppealsWithNoVacolsCase.

Modeled after #14536.

* Updated frontend jest tests

* upgrade rails to 5.2.4.4 (#15199)

Resolves this alert:

```
Name: actionview
Version: 5.2.4.3
Advisory: CVE-2020-15169
Criticality: Unknown
URL: https://groups.google.com/g/rubyonrails-security/c/b-C9kSGXYrc
Title: Potential XSS vulnerability in Action View
Solution: upgrade to >= 5.2.4.4, ~> 5.2.4, >= 6.0.3.3
```

* Create "Clerk of the Board" org (#15191)

Connects #15135 

### Description
This creates the Clerk of the Board organization (`ClerkOfTheBoard` model, inheriting from `Organization`)

### Acceptance Criteria
- [x] Code compiles correctly
- [x] `ClerkOfTheBoard.singleton` creates org if it doesn't already exists, otherwise returns existing
- [ ] Members have access to create mail tasks

* Ensure props change when navigating to a new page from the nav bar (#15188)

Resolves #15014

### Description
The navigation bar is a [pure component](https://reactjs.org/docs/react-api.html#reactpurecomponent), which will not update if it's props have not changed. 

> React.PureComponent’s shouldComponentUpdate() only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
> Furthermore, React.PureComponent’s shouldComponentUpdate() skips prop updates for the whole component subtree. Make sure all the children components are also “pure”.

This causes it's child QueueLoadingScreen and LoadingDataDisplay to not mount again and grab new data when navigating from a judge's assign queue to their normal queue when navigating via the CaseflowNavigationBar.

This change overrides the shallow comparison of props and explicitly checks to see if we are navigating to a new URL.

### Acceptance Criteria
- [x] Judges can navigate from their assign queue to their normal queue via the navigation bar without getting a white screen of death

### Testing Plan
1. Log in as BVAAABSHIRE
1. Navigate to http://localhost:3000/queue/BVAAABSHIRE/assign
1. Click "Caseflow Queue" at the top of the page
1. Notice page now shows loading icon and queue loads correctly
1. Click "Caseflow Queue" at the top of the page
1. Notice no loading icon

* Add integrations UAT testing to PR template (#15168)

Action from the [pay grade validation post-mortem](https://github.com/department-of-veterans-affairs/appeals-deployment/blob/master/docs/post-mortems/2020-09-01-bgs-pay-grade-outage.md)

### Description
Updated PR template to include UAT testing for integrations and other guidance.

* Add changed hearing request type column to legacy hearings (#15189)

Resolves #14898

### Description

- Add `changed_request_type` field
- Update logic in `sanitized_hearing_request_type` to consider `changed_request_type`
- Update places in code where `sanitized_hearing_request_type` is used or should be used
- Add tests for validation and `sanitized_hearing_request_type`

### Acceptance Criteria

- [x] A video or virtual hearing request type can be recorded for an individual hearing


### Database Changes
*Only for Schema Changes*

* [x] Timestamps (created_at, updated_at) for new tables
* [x] Column comments updated
* [x] Have your migration classes inherit from `Caseflow::Migration`, especially when adding indexes (use `add_safe_index`)
* [x] Verify that `migrate:rollback` works as desired ([`change` supported functions](https://edgeguides.rubyonrails.org/active_record_migrations.html#using-the-change-method))
* [ ] Query profiling performed (eyeball Rails log, check bullet and fasterer output)
* [x] Appropriate indexes added (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)
* [x] DB schema docs updated with `make docs` (after running `make migrate`)
* [ ] #appeals-schema notified with summary and link to this PR

* remove unused associated_hearing_is_video method (#15204)

### Description
The `associated_hearing_is_video` validation was removed in e8164bc but the method lived on, until now.

* update reducer to merge existing loading state to fix double request issue (#15198)

https://dsva.slack.com/archives/C3EAF3Q15/p1599684953173300

### Description

Resolves an issue where the loading state was being overwritten in the Redux state on case details

<img width="544" alt="Screen Shot 2020-09-09 at 5 14 43 PM" src="https://user-images.githubusercontent.com/1298274/92774224-41d8d100-f36b-11ea-997a-9fdab7eab036.png">

* Removed marked complete task action (#15211)

Resolves #14869 

### Description
Added new action deletion method to remove "Mark Task Complete".

### Acceptance Criteria
- [ ] BvaDispatchTasks cannot be marked complete by anyone through the caseflow task action dropdown

### Testing Plan
1. Sign in as BVADispatch user White.
2. Navigate to your queue.
3. Select a case.
4. Confirm the action is not there.
5. Sign in as BVADispatch admin Black.
6. Navigate to the team assigned queue.
7. Repeat steps 3. and 4.

* Use BGS representative in all Hearings Jobs (#15083)

Resolves #14753

### Description

Modifies all hearings jobs to use the BGS attorney instead of VACOLS, by modifying the conditional that is used in this method:

https://github.com/department-of-veterans-affairs/caseflow/blob/3f79bdf200875a11ca6de1da71afc5bbf274e63f/app/models/legacy_appeal_representative.rb#L27-L35

* Fix display of non-vet claimants on non-comp DR tasks (#15235)

Connects #11301 

### Description
This PR fixes a rare bug in displaying non-veteran claimants' relationship on decision review task pages. It occurs only when the claimant's BGS record has a `nil` relationship. The task mentioned in the original ticket, 248934, is one such instance in prod.

### Acceptance Criteria
- [x] Relationship type shows up on non-compensation queue task page

### Testing Plan
- `DecisionReviewTask.find(248934).ui_hash[:claimant]` is the expression in question
  - Running it on original code produces `{:name=>"REDACTED", :relationship=>"claimant"}`
  - Patch `WorkQueue::DecisionReviewTaskSerializer.claimant_relationship` with the diff of this PR
  - Running it on patched code produces `{:name=>"REDACTED", :relationship=>"Dependent"}`
- Alternatively, if we can find an instance of this missing data in UAT, deploying this branch to UAT should fix it.

* Non-modal form for converting travel board request type to virtual (#15217)

Resolves #15157 

### Description
- serialize regional office label
- create new component `HearingTypeConversionForm` to display form to convert hearing type to virtual
- write stories for `HearingTypeConversionForm`
- rename method `getAppellantTitleForHearing` to the more general `getAppellantTitle`
- minor changes to  components `AppellantSection` and `VirtualHearingSecion`
- write jest tests for `HearingTypeConversionForm`

### Testing Plan
1. run `make storybook`
2. go to storybook and see `HearingConversionTypeForm` 

### Storybook Story
*For Frontend (Presentationa) Components*
* [X] Add a [Storybook](https://github.com/department-of-veterans-affairs/caseflow/wiki/Documenting-React-Components-with-Storybook) file alongside the component file (e.g. create `MyComponent.stories.js` alongside `MyComponent.jsx`)
* [X] Give it a title that reflects the component's location within the overall Caseflow hierarchy
* [X] Write a separate story (within the same file) for each discrete variation of the component

* Add associations to end product establishment for effectuations (#15170)

### Description
PR to take advantage of rails associations to be able to access board grant effectuations easily on a board grant effectuation end product establishment.

* [PART 1] Create a "priority only" distribution (#14745)

* Priority distributions wip

* Fix tests

* make docs!

* Code climate

* Allow unlimited priority legacy appeals to be distributed

* Fix bug on wrong number of hearing cases distributed

* Create priority only distributions

* Suggestions

* Update to priority_push

* Update to priority_push

* Fix schema

* Code Climate

* Updates

* Updates
 to priority push

* fix specs

* Allow unlimited priority legacy appeals to be distributed

* Fix bug on wrong number of hearing cases distributed

* Create priority only distributions

* Code Climate

* Updates

* Updates
 to priority push

* fix specs

* Rename ama distribution

* Add Yoom's changes

* Fix merge

* Code climate fixes

* Return the number of appeals acutally distributed and fix cc

* Code climate

* Feedback!

* Fix tests

* feedback

* Fix tests

* Test fix

* Fix tests

* [PART 2] Job to push priority cases to judges (#14715)

* WIP with tests on priority push job

* words words words

* Add test to track number converge over time

* Distribute all cases tied to judges

* Add test for pulling all judges with ready priority cases

* Fix merge

* Fix merge

* Tests and renaming

* only distribute tied appeals to eligible judges

* Create distributions for all judges, even if they have no cases tied to them

* Fix job

* Code climate

* Update scope name

* Feedbackgit stgit stgit st!

* Better comments

* Fix test

* [PART 3] Add report on priority push job completion (#14761)

* Add reporting

* Update reporting format to be a string

* Remove redundant VACOLS::CaseDocket::

* Pretty colors

* Add priority target and previous distributions to the report

* Ordering and formatting

* Fix report

* Fix report

* Fix tests

* Code climate

* [Part 4] Create non default distribution seed data (#14802)

* Better handling of dispatch judge and atty

* Fix factories to be able to be called after resetting sequences

* Add distribution seed file

* Add a case that will error

* Integrate bug fix

* Fix job

* Fixes

* Fix report

* Fix tied to judge trait

* User random keys

* Integrate changes from fix

* Fix tests

* Code climate

* Feedback

* Update priority_distributions.rb

* Fix merge

* cc

* Tests

* cc

* Fix tests

* Nocov on seeds that do not run by default

* Remove eligible_due_to_date for aod motions (#15237)

Resolves #14085

### Description
Remove old check that allowed a motion to be associated with an appeal because the motion was created after the appeal's receipt date. We have now [associated every motion with an appeal](#14085 (comment)) and this incorrect check should be removed.

### Acceptance Criteria
Appeals are only considered aod due to motion if there is an 
- [ ] age related motion that applies to any appeal with the same claimant
- [ ] any other reason related motion that applies to that exact appeal

### Testing Plan
1. Sign in as AOD_USER and find any non aod ama case
```ruby
appeal = Appeal.find_by(uuid: "173b6ce2-070c-4eec-a463-301f8f18c70e")
appeal.aod?
=> false
```
2. Find the "Edit" link next to the appeal stream type
1. Grant an AOD motion for any reason other than age
```ruby
appeal.aod?
=> true
```
4. Remove the appeal from the aod motion
```ruby
motion = AdvanceOnDocketMotion.find_by(appeal: appeal)
motion.update_attribute('appeal_id', nil)
AdvanceOnDocketMotion.find_by(appeal: appeal)
=> nil
appeal.aod?
=> false
AdvanceOnDocketMotion.first.created_at > appeal.receipt_date
=> true
```
5. Ensure aod does not show up in the ui by reloading case details

* Clarify task_timer table comments (#15241)

### Description
Update `task_timer` table comments to aid future investigation into `TaskTimers`. 
Also added code comments at the top of the class to reference the wiki.

Based on [Hunter's investigation](https://hackmd.io/@hschallh/HJ62FbTNP); motivated by [PendingIncompleteAndUncancelledTaskTimersChecker warnings](https://dsva.slack.com/archives/CJL810329/p1599828304030800).

Prior comments were general from the perspective of `Asyncable` class. New comments provide more detail specific to `TaskTimers`.

### Acceptance Criteria
- [ ] Code compiles correctly

### Testing Plan
See Database Changes section below.

### Code Documentation Updates
- [x] Add or update code comments at the top of the class, module, and/or component.

### Database Changes
*Only for Schema Changes*

* [ ] ~Timestamps (created_at, updated_at) for new tables~
* [x] Column comments updated
* [x] Have your migration classes inherit from `Caseflow::Migration`, especially when adding indexes (use `add_safe_index`)
* [x] Verify that `migrate:rollback` works as desired ([`change` supported functions](https://edgeguides.rubyonrails.org/active_record_migrations.html#using-the-change-method))
* [ ] ~Query profiling performed (eyeball Rails log, check bullet and fasterer output)~
* [ ] ~Appropriate indexes added (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)~
* [x] DB schema docs updated with `make docs` (after running `make migrate`)
* [x] #appeals-schema notified with summary and link to this PR

* Caseflow Intake: Review page spacing consistency (#15229)

* 4 of 5 spacing changes

* fix double quotes to single quotes

* spacing fix

* final 30px spacing

* spacing fix

* feature toggle off

* Edit EP Claim Labels | Add map of end product code characteristics (#15228)

Connects #15114

### Description
Add a constants file with a hash of end product codes and their properties.

### Acceptance Criteria
- [ ] Key: End product code
- [ ] Properties:
  - [ ] "Official" label
  - [ ] Label for the UI (currently lives in END_PRODUCT_CODES.json)
  - [ ] Issue type
  - [ ] Business line (aka benefit type)
  - [ ] EP Family (030/040/930)
  - [ ] Review type
  - [ ] Disposition type (for automatically generated claims): allowed, remanded, Duty to assist error, Difference of Opinion
  - [ ] Correction type
- [ ] Codes that are not currently established by Caseflow can be excluded from the code map

* Shalliburton/14895 connect schedule veteran rspec (#15215)

* Updated and added tests to postpone hearing feature workflow

* Finished writing backend tests for direct-to-virtual workflow

* Fixed lint and jest errors

* Fixed jest snapshot errors

* Replaced router with memory router to fix location key snapshot updates

* Use request_type instead of readabale_request_type to determine RO (#15244)

### Description
#### Background
This PR fixes an issue with central dockets where [these sentrey errors](https://sentry.prod.appeals.va.gov/department-of-veterans-affairs/caseflow/issues/11573/?referrer=webhooks_plugin) started popping up because we were fetching hearing locations on daily docket with `regionalOffice=null`. This `regionalOffice` was getting set to `null` by this [logic](https://github.com/department-of-veterans-affairs/caseflow/blob/e6279de98591de6b6a5fa7657c0769c00715b963/client/app/hearings/components/dailyDocket/DailyDocket.jsx#L96) because we were using `readableRequestType` from hearingDay object which now returns `Central`, `Central, Virtual`, or `Virtual` as central hearings are being converted to virtual since the release of this feature to some hearings users ([slack request](https://dsva.slack.com/archives/C3EAF3Q15/p1599238807134300)).

#### Fix
The fix was to keep `readableRequestType` only for displaying to users and instead use `requestType` (which is currently either `C` or `V`) to  determine the `regionalOffice` for a hearing day. 

#### Reference
[Slack thread for discussion](https://dsva.slack.com/archives/C01155MJGF2/p1600128301012900)

### User Facing Changes
 - [x] Screenshots of UI changes added to PR & Original Issue

#### BEFORE
<img width="861" alt="Screen Shot 2020-09-15 at 1 29 48 PM" src="https://user-images.githubusercontent.com/20735998/93244662-13d30280-f758-11ea-85aa-742de2182485.png"> 

#### AFTER
<img width="833" alt="Screen Shot 2020-09-15 at 1 30 01 PM" src="https://user-images.githubusercontent.com/20735998/93244683-1afa1080-f758-11ea-9f3a-c3ad7a5d8727.png">



### Testing Plan
1. Enable feature toggle on rails console`FeatureToggle.enable!(:schedule_virtual_hearings_for_central, users: [User.find_by(css_id: "BVASYELLOW")])`
2. Login as `BVASYELLOW`
3. Go to http://localhost:3000/hearings/schedule and pick a central hearing day with 2 or more hearings
4. Convert a hearing to `Virtual` 
5. Go back to daily docket and notice that the hearing locations are fetched without errors

* Fixed issues with appellant section after merge

* Fixed issues with appellant section after merge

* Updated default hearings data

Co-authored-by: Rubaiyat Rashid <[email protected]>

Co-authored-by: Ferris Tseng <[email protected]>
Co-authored-by: Kat Tipton <[email protected]>
Co-authored-by: Tomas Apodaca <[email protected]>
Co-authored-by: va-bot <[email protected]>
Co-authored-by: Yoom Lam <[email protected]>
Co-authored-by: Hunter Schallhorn <[email protected]>
Co-authored-by: jcq <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alisa Nguyen <[email protected]>
Co-authored-by: Sandra Jones <[email protected]>
Co-authored-by: Meckila <[email protected]>
Co-authored-by: wdrougas-tista <[email protected]>
Co-authored-by: YANG YANG <[email protected]>
Co-authored-by: Rubaiyat Rashid <[email protected]>
Co-authored-by: Sally Maki <[email protected]>
Co-authored-by: mkerns355 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked This is blocked Feature: case-details Priority: Medium Blocking issue w/workaround, or "second in" priority for new work. Product: caseflow-queue release-notes This ticket should get release notes generated on merge Stakeholder: BVA Functionality associated with the Board of Veterans' Appeals workflows/feature requests Team: Echo 🐬 Type: Enhancement Enhancement to an existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants