Skip to content

Commit

Permalink
Rename granted substitution to appellant substitution (#16095)
Browse files Browse the repository at this point in the history
Resolves nomenclature around "granted substitution".

[Slack](https://dsva.slack.com/archives/CJL810329/p1617638837087900?thread_ts=1617635762.080200&cid=CJL810329)

Original PR: Add New Model for Granted Substitutions #16032

### Description

The Board is not granting substitutions -- they are processing them. Caseflow should not present "Granted substitution" in the UI, so let's not call it that in the database.

From Ann-Marie:
> ... the appeal is not intaken if not granted by the AOJ so the substitution is granted, but not by the Board themselves
> They don't want users in Caseflow to think they are granting the substitution which is why they do not want it reflected that way
> Board policy is that the attorneys/VLJs cannot wait for substitution to be granted at the AOJ. They have to process a Death Dismissal even if substitution is pending at the AOJ.
> The only time the Board would possibly grant substitution is if the substitution itself is appealed to the Board (type of contested claim)

### Acceptance Criteria
- [ ] Code compiles correctly

### 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`)
* [x] #appeals-schema notified with summary and link to this PR
* [ ] ~Any non-obvious semantics or logic useful for interpreting database data is documented at [Caseflow Data Model and Dictionary](https://github.com/department-of-veterans-affairs/caseflow/wiki/Caseflow-Data-Model-and-Dictionary)~
  • Loading branch information
yoomlam authored Apr 7, 2021
1 parent 2a7f1b4 commit 878b773
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 75 deletions.
2 changes: 2 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ plugins:
ruby:
javascript:
mass_threshold: 50
exclude_patterns:
- 'db/migrate/*'
eslint:
enabled: true
fixme:
Expand Down
20 changes: 17 additions & 3 deletions app/models/advance_on_docket_motion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,32 @@ def create_or_update_by_appeal(appeal, attrs)
end
end

# Copies granted AODMotions for only persons that appear in both appeals
def copy_granted_motions_to_appeal(src_appeal, dst_appeal)
person = src_appeal.claimant.person
fail "Claimants on appeals are expected to be the same" unless person == dst_appeal.claimant.person
src_person_ids = [src_appeal.veteran.person, src_appeal.claimants.map(&:person)].flatten.map(&:id)
dst_person_ids = [dst_appeal.veteran.person, dst_appeal.claimants.map(&:person)].flatten.map(&:id)
where(person_id: src_person_ids, appeal: src_appeal).granted.map do |aod_motion|
next unless dst_person_ids.include?(aod_motion.person_id)

where(person_id: person, appeal: src_appeal).granted.map do |aod_motion|
aod_motion.dup.tap do |motion_copy|
motion_copy.appeal_id = dst_appeal.id
motion_copy.save!
end
end
end

# Transfers all granted AODMotions to target_person and dst_appeal, regardless of original person on AODMotion
def transfer_granted_motions_to_person(src_appeal, dst_appeal, target_person)
src_person_ids = [src_appeal.veteran.person, src_appeal.claimants.map(&:person)].flatten.map(&:id)
where(person_id: src_person_ids, appeal: src_appeal).granted.map do |aod_motion|
aod_motion.dup.tap do |motion_copy|
motion_copy.person_id = target_person.id
motion_copy.appeal_id = dst_appeal.id
motion_copy.save!
end
end
end

private

def reason_is_not_age(reason)
Expand Down
14 changes: 11 additions & 3 deletions app/models/appeal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This is the type of appeal created by the Veterans Appeals Improvement and Modernization Act (AMA),
# which went into effect Feb 19, 2019.

# rubocop:disable Metrics/ClassLength
class Appeal < DecisionReview
include AppealConcern
include BgsService
Expand Down Expand Up @@ -45,7 +46,7 @@ class Appeal < DecisionReview
Constants.AMA_STREAM_TYPES.vacate.to_sym => Constants.AMA_STREAM_TYPES.vacate,
Constants.AMA_STREAM_TYPES.de_novo.to_sym => Constants.AMA_STREAM_TYPES.de_novo,
Constants.AMA_STREAM_TYPES.court_remand.to_sym => Constants.AMA_STREAM_TYPES.court_remand,
Constants.AMA_STREAM_TYPES.granted_substitution.to_sym => Constants.AMA_STREAM_TYPES.granted_substitution
Constants.AMA_STREAM_TYPES.substitution.to_sym => Constants.AMA_STREAM_TYPES.substitution
}

after_create :conditionally_set_aod_based_on_age
Expand Down Expand Up @@ -103,7 +104,8 @@ def type
stream_type&.titlecase || "Original"
end

def create_stream(stream_type)
# rubocop:disable Metrics/MethodLength
def create_stream(stream_type, new_claimants: nil)
ActiveRecord::Base.transaction do
Appeal.create!(slice(
:aod_based_on_age,
Expand All @@ -118,11 +120,16 @@ def create_stream(stream_type)
stream_docket_number: docket_number,
established_at: Time.zone.now
)).tap do |stream|
stream.copy_claimants!(claimants)
if new_claimants
new_claimants.each { |claimant| claimant.update(decision_review: stream) }
else
stream.copy_claimants!(claimants)
end
stream.reload # so that stream.claimants returns updated list
end
end
end
# rubocop:enable Metrics/MethodLength

def vacate_type
return nil unless vacate?
Expand Down Expand Up @@ -573,3 +580,4 @@ def default_docket_number_from_receipt_date
"#{receipt_date.strftime('%y%m%d')}-#{id}"
end
end
# rubocop:enable Metrics/ClassLength
48 changes: 48 additions & 0 deletions app/models/appellant_substitution.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

# Model to store Appellant Substitution information captured from the Granted Substitution creation process

class AppellantSubstitution < CaseflowRecord
belongs_to :created_by, class_name: "User"
belongs_to :source_appeal, class_name: "Appeal"
belongs_to :target_appeal, class_name: "Appeal"

validates :created_by, :source_appeal, :substitution_date,
:claimant_type, :substitute_participant_id,
:poa_participant_id,
presence: true

before_save :establish_appeal_stream

attr_accessor :claimant_type

def substitute_claimant
Claimant.find_by(participant_id: substitute_participant_id)
end

def substitute_person
Person.find_by(participant_id: substitute_participant_id)
end

def power_of_attorney
BgsPowerOfAttorney.find_by(poa_participant_id: poa_participant_id)
end

private

def establish_appeal_stream
Claimant.create_without_intake!(participant_id: substitute_participant_id, payee_code: nil, type: claimant_type)
unassociated_claimants = Claimant.where(participant_id: substitute_participant_id, decision_review: nil)
self.target_appeal ||= source_appeal.create_stream(:substitution, new_claimants: unassociated_claimants)
.tap do |target_appeal|
# AOD Status: If the deceased appellant’s appeal was AOD, the substitute appellant will also receive
# the benefit of the AOD status. This is the case for both situations where a case is returned to
# the Board following the grant of a substitution request AND/OR pursuant to an appeal of a denial
# of a substitution request. See 38 C.F.R. § 20.800(f).
subtitute_person = target_appeal.claimant.person
AdvanceOnDocketMotion.transfer_granted_motions_to_person(source_appeal, target_appeal, subtitute_person)

InitialTasksFactory.new(target_appeal).create_root_and_sub_tasks!
end
end
end
4 changes: 4 additions & 0 deletions app/models/cavc_remand.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def mandate_not_required?
def establish_appeal_stream
self.remand_appeal ||= source_appeal.create_stream(:court_remand).tap do |cavc_appeal|
update_request_issues(cavc_appeal, add: decision_issue_ids)

person = source_appeal.claimant.person
fail "Claimants on appeals are expected to be the same" unless person == cavc_appeal.claimant.person

AdvanceOnDocketMotion.copy_granted_motions_to_appeal(source_appeal, cavc_appeal)
end
end
Expand Down
23 changes: 0 additions & 23 deletions app/models/granted_substitution.rb

This file was deleted.

2 changes: 1 addition & 1 deletion client/constants/AMA_STREAM_TYPES.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"vacate": "vacate",
"de_novo": "de_novo",
"court_remand": "court_remand",
"granted_substitution": "granted_substitution"
"substitution": "substitution"
}
31 changes: 31 additions & 0 deletions db/migrate/20210406122353_rename_granted_substitutions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class RenameGrantedSubstitutions < Caseflow::Migration
def up
create_table :appellant_substitutions, comment: "Store appellant substitution form data" do |t|
t.date "substitution_date", null: false, comment: "Date of substitution"
t.string "substitute_participant_id", null: false, comment: "Participant ID of substitute appellant"
t.string "poa_participant_id", null: false, comment: "Identifier of the appellant's POA, if they have a CorpDB participant_id"

t.references :source_appeal, null: false, foreign_key: { to_table: :appeals }, comment: "The relevant source appeal for this substitution"
t.references :target_appeal, null: false, foreign_key: { to_table: :appeals }, comment: "The new appeal resulting from this substitution"
t.references :created_by, index: false, references: :users, null: false, foreign_key: { to_table: :users }, comment: "User that created this record"
t.timestamps null: false, comment: "Standard created_at/updated_at timestamps"
end

drop_table :granted_substitutions
end

def down
create_table :granted_substitutions, comment: "Store Granted Substitution form data" do |t|
t.date "substitution_date", null: false, comment: "Date of granted substitution"
t.references :substitute, index: false, references: :claimants, null: false, foreign_key: { to_table: :claimants }, comment: "References claimants table"
t.string "poa_participant_id", null: false, comment: "Identifier of the appellant's POA, if they have a CorpDB participant_id"

t.references :source_appeal, null: false, foreign_key: { to_table: :appeals }, comment: "The relevant source appeal for this substitution"
t.references :target_appeal, null: false, foreign_key: { to_table: :appeals }, comment: "The new appeal resulting from this granted substitution"
t.references :created_by, index: false, references: :users, null: false, foreign_key: { to_table: :users }, comment: "User that created this record"
t.timestamps null: false, comment: "Standard created_at/updated_at timestamps"
end

drop_table :appellant_substitutions
end
end
35 changes: 17 additions & 18 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2021_03_24_184415) do
ActiveRecord::Schema.define(version: 2021_04_06_122353) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -125,6 +125,19 @@
t.index ["veteran_file_number"], name: "index_appeals_on_veteran_file_number"
end

create_table "appellant_substitutions", comment: "Store appellant substitution form data", force: :cascade do |t|
t.datetime "created_at", null: false, comment: "Standard created_at/updated_at timestamps"
t.bigint "created_by_id", null: false, comment: "User that created this record"
t.string "poa_participant_id", null: false, comment: "Identifier of the appellant's POA, if they have a CorpDB participant_id"
t.bigint "source_appeal_id", null: false, comment: "The relevant source appeal for this substitution"
t.string "substitute_participant_id", null: false, comment: "Participant ID of substitute appellant"
t.date "substitution_date", null: false, comment: "Date of substitution"
t.bigint "target_appeal_id", null: false, comment: "The new appeal resulting from this substitution"
t.datetime "updated_at", null: false, comment: "Standard created_at/updated_at timestamps"
t.index ["source_appeal_id"], name: "index_appellant_substitutions_on_source_appeal_id"
t.index ["target_appeal_id"], name: "index_appellant_substitutions_on_target_appeal_id"
end

create_table "attorney_case_reviews", id: :serial, force: :cascade do |t|
t.integer "attorney_id"
t.datetime "created_at", null: false
Expand Down Expand Up @@ -691,19 +704,6 @@
t.index ["updated_at"], name: "index_global_admin_logins_on_updated_at"
end

create_table "granted_substitutions", comment: "Store Granted Substitution form data", force: :cascade do |t|
t.datetime "created_at", null: false, comment: "Standard created_at/updated_at timestamps"
t.bigint "created_by_id", null: false, comment: "User that created this record"
t.string "poa_participant_id", null: false, comment: "Identifier of the appellant's POA, if they have a CorpDB participant_id"
t.bigint "source_appeal_id", null: false, comment: "The relevant source appeal for this substitution"
t.bigint "substitute_id", null: false, comment: "References claimants table"
t.date "substitution_date", null: false, comment: "Date of granted substitution"
t.bigint "target_appeal_id", null: false, comment: "The new appeal resulting from this granted substitution"
t.datetime "updated_at", null: false, comment: "Standard created_at/updated_at timestamps"
t.index ["source_appeal_id"], name: "index_granted_substitutions_on_source_appeal_id"
t.index ["target_appeal_id"], name: "index_granted_substitutions_on_target_appeal_id"
end

create_table "hearing_appeal_stream_snapshots", id: false, force: :cascade do |t|
t.integer "appeal_id", comment: "LegacyAppeal ID; use as FK to legacy_appeals"
t.datetime "created_at", null: false, comment: "Automatic timestamp of when snapshot was created"
Expand Down Expand Up @@ -1632,6 +1632,9 @@
add_foreign_key "annotations", "users"
add_foreign_key "api_views", "api_keys"
add_foreign_key "appeal_views", "users"
add_foreign_key "appellant_substitutions", "appeals", column: "source_appeal_id"
add_foreign_key "appellant_substitutions", "appeals", column: "target_appeal_id"
add_foreign_key "appellant_substitutions", "users", column: "created_by_id"
add_foreign_key "cavc_remands", "users", column: "created_by_id"
add_foreign_key "cavc_remands", "users", column: "updated_by_id"
add_foreign_key "certifications", "users"
Expand All @@ -1645,10 +1648,6 @@
add_foreign_key "end_product_establishments", "users"
add_foreign_key "end_product_updates", "end_product_establishments"
add_foreign_key "end_product_updates", "users"
add_foreign_key "granted_substitutions", "appeals", column: "source_appeal_id"
add_foreign_key "granted_substitutions", "appeals", column: "target_appeal_id"
add_foreign_key "granted_substitutions", "claimants", column: "substitute_id"
add_foreign_key "granted_substitutions", "users", column: "created_by_id"
add_foreign_key "hearing_days", "users", column: "created_by_id"
add_foreign_key "hearing_days", "users", column: "judge_id"
add_foreign_key "hearing_days", "users", column: "updated_by_id"
Expand Down
20 changes: 10 additions & 10 deletions docs/schema/caseflow.csv
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ appeal_views,id,integer PK,x,x,,,,
appeal_views,last_viewed_at,datetime,,,,,,
appeal_views,updated_at,datetime ∗,x,,,,,
appeal_views,user_id,integer ∗ FK,x,,x,,x,
appellant_substitutions,,,,,,,,Store appellant substitution form data
appellant_substitutions,created_at,datetime ∗,x,,,,,Standard created_at/updated_at timestamps
appellant_substitutions,created_by_id,integer (8) ∗ FK,x,,x,,,User that created this record
appellant_substitutions,id,integer (8) PK,x,x,,,,
appellant_substitutions,poa_participant_id,string ∗,x,,,,,"Identifier of the appellant's POA, if they have a CorpDB participant_id"
appellant_substitutions,source_appeal_id,integer (8) ∗ FK,x,,x,,x,The relevant source appeal for this substitution
appellant_substitutions,substitute_participant_id,string ∗,x,,,,,Participant ID of substitute appellant
appellant_substitutions,substitution_date,date ∗,x,,,,,Date of substitution
appellant_substitutions,target_appeal_id,integer (8) ∗ FK,x,,x,,x,The new appeal resulting from this substitution
appellant_substitutions,updated_at,datetime ∗,x,,,,,Standard created_at/updated_at timestamps
attorney_case_reviews,,,,,,,,
attorney_case_reviews,attorney_id,integer FK,,,x,,,
attorney_case_reviews,created_at,datetime ∗,x,,,,,
Expand Down Expand Up @@ -532,16 +542,6 @@ global_admin_logins,id,integer PK,x,x,,,,
global_admin_logins,target_css_id,string,,,,,,
global_admin_logins,target_station_id,string,,,,,,
global_admin_logins,updated_at,datetime,,,,,x,
granted_substitutions,,,,,,,,Store Granted Substitution form data
granted_substitutions,created_at,datetime ∗,x,,,,,Standard created_at/updated_at timestamps
granted_substitutions,created_by_id,integer (8) ∗ FK,x,,x,,,User that created this record
granted_substitutions,id,integer (8) PK,x,x,,,,
granted_substitutions,poa_participant_id,string ∗,x,,,,,"Identifier of the appellant's POA, if they have a CorpDB participant_id"
granted_substitutions,source_appeal_id,integer (8) ∗ FK,x,,x,,x,The relevant source appeal for this substitution
granted_substitutions,substitute_id,integer (8) ∗ FK,x,,x,,,References claimants table
granted_substitutions,substitution_date,date ∗,x,,,,,Date of granted substitution
granted_substitutions,target_appeal_id,integer (8) ∗ FK,x,,x,,x,The new appeal resulting from this granted substitution
granted_substitutions,updated_at,datetime ∗,x,,,,,Standard created_at/updated_at timestamps
hearings,,,,,,,,
hearings,appeal_id,integer ∗ FK,x,,x,,,Appeal ID; use as FK to appeals
hearings,bva_poc,string,,,,,,Hearing coordinator full name
Expand Down
Loading

0 comments on commit 878b773

Please sign in to comment.