From 48767e7ffef718fb1612b6530f31fd2fd72d8523 Mon Sep 17 00:00:00 2001 From: Craig Reese <109101548+craigrva@users.noreply.github.com> Date: Fri, 2 Aug 2024 08:30:10 -0500 Subject: [PATCH] Feature/appeals 43179 (#21665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Calvin/APPEALS-43852-cavc-levers (#21441) * enabled cavc affinity levers in UI * updated rspec * [APPEALS-43849]Update CAVC Affinity Implementation for AMA Dockets to… (#21456) * [APPEALS-43849]Update CAVC Affinity Implementation for AMA Dockets to Account for Omit/Infinity * Affinity rules applied to non genpop * Addressed comments * Addressed comments * fixed rubocop issues + added clarity to where clause --------- Co-authored-by: Calvin * APPEALS-44956: Add AppealAffinity model and database table (#21526) * add migration for appeal_affinities * add AppealAffinity model and associations, update migration for new column * update index to be unique * add factory, add tests * add factory traits to appeal and case for appeal affinities * add combination trait to appeal factory * add appeal_affinity to skipped associations in ETL reporting * add a validation, test * Craig/appeals 44958 (#21564) * add new job, update affinity model validation and after save hook * add update from push job * fix job extending distribution scopes * add with appeal affinities to distribution scopes * typo * add error handling, add test file * add distributed case factory, refactor naming in job * fix factories, added tests * fix migration for null affinity start date column * fixes, added tests * more test updates * add return in job if no query results, tests for no query results * add test for after_save hook adding dist task instructions * set start dist job to queue affinity job after running * fix update job and start dist job spec * queue affinity update job from push job * code clarity * fix judge in seed file * remove comment, fix hearing factory, disable some seeds for testing * add more tests * test refactor * update appeals for dist query to add affinity start, add seed file, fix hearing factory, add stat to dist factory * disable new seed on reset * update seed file with vet names, add another seed category * fix distirbuted case factory? * actually fix GHA runs * lint, test fixes * change constants in new job * [Appeals 43850] Update Legacy Docket Queries to Account for the Previous Decision Judge and Type Action (#21556) * test changes for seans ticket * test changes * added joins to all required methods * fixed lint * fixed column ambiguity errors * cleaned up naming scheme * Documentation for JOIN_PREVIOUS_APPEALS constant --------- Co-authored-by: Calvin * APPEALS-44959: Modify affinity date checks to use appeal_affinity (#21611) * swap distribution queries from distribution_task to appeal_affinities * update seed files to use appeal affinities instead of distribution task * clean up seed file method names * add missing Timecop.return in ama affinity case seed * fix name of a method in a seed file * remove references to distribution task in distribution scopes * fix push priority job tests * fix naming of args in one of the seed files * fix user seed, fix date format in distribution task instructions * fix tests for date format update * APPEALS-44187: Factory Bot Additions (#21438) * AC1: values for bfddec and bfmpro * AC2: case issues updated to '3' * AC3-4: attorney and judge additions * ac 5: bfdpdcn addition * AC6: case type action addition * ac7: new folder match to original * ac8: case issues set to original * AC 3/4: added associations to original * ac3/4: updated logic to handle no args * ac3/4: return sattyid * ac7:updating folder assignment * ac7: added bfkey to except block * ac7/8: update to case issue list and validations dismissed * removed byebug * ac7: added 'ticknum' to except * lint fixes * lint fixes * lint fixes * lint fixes * nested trait into form_9 factory * new addtions * added .save to case issues * resolving correspondent and titrnum associations * fixed bfdc typo * factory additions * added ssn to associated corr. * removed transient and added .save * added after create to corr factory * veteran lookup check prior to create * committing missed 'end' * moved over veteran create to case fact. * move corr. association field to case fact. * lint issues + corres. save * Calvin/APPEALS-44957-rake-affinity (#21577) * grabbed receipt dates from distributed cases * refactored for functionality + added method to grab appeals that match * using receipt date, get all related appeals * added update/creation plus cleaned prior imple. * gets most recent distributed case receipt_date * skips if receipt_date is nil for performance * if appeal affinity is nil, it will now be updated * created spec file * fixed non ready appeals * updated query to match new AC * removing comment * testing for each docket * updated spec file * added new tests to rspec * updated start date to receipt date instead of Time.now * fixed date/time rspec errors * added rails logger to know when rake task has finished * added tag for rails log * removed nonpriority dockets for direct_review and evidence_submission * fixed lint issue * fixed flaky spec test * limits distributed cases query to within the last week * APPEALS-46016: Add Affinity Start Date to the Explain Page (#21660) * add affinity start date to explain page * add feature test to verify dates display * Sudhir/appeals 43851 (#21613) * Implement CAVC + AOD Affinity Lever for AMA Dockets * addressed comments * addressed comments * Addressed comments * added cavc_aod_affinity in case distribution lever model * addressed comments * addressed comments * updated specs * Updated specs * specs changes reverted * ama_aod and ama_non_aod queries updated * change the assertion in docket spec * Craig/appeals 46196 (#21689) * fix query, tested locally * add basic test to verify csv downloads aren't broken * APPEALS-43851: Add test to validate CAVC+AOD behavior on hearing docket appeals affinities (#21678) * add test to validate cavc+aod on hearing docket appeals * lint, test case_docket_spec fix * modify case_docket_spec again * more test fix testing * attempt to fix test again * test removing prev appeals from nonpriority queries * more test tests * feature toggle change in test * reorder new portions of query * remove unused portions of queries in case_docket * revert unneeded change to query order * revert unneeded change to query order * update rake task and spec (#21731) * APPEALS-46325: Add Seeds for AOD Appeals and Update Dates to Match CAVC (#21730) * add aod hearing cases to ama affinity cases seed * fix lever spec * APPEALS-45148: Hook to clear saved affinity date (#21623) * initial imp. idea * AC1: check for affinity_start_date on assignment * AC2/3: update affinity start date w/ instr. * updates to naming, instructions, and hook logic * updates after review * rspec coverage and addtional condition * removed unused identifier * removed reduntant 'self's * added update on actual AA record * updated to save aa record and addtional rspec * added change to assignment on no record test * check for assignment * addd update to 'on_hold' status * public method to handle legacy affinity appeals * added .reload to :with_affinity_appeal * added .reload to :ready_for_distribution * updates to pass explain_spec * switched boolean values * typo * readujsted order on :create for affinity appeal * removed after(:create) * testing rspec by readding after :create * reloading in assertation * addressing lint errors * fix seeds/users_spec * add case dist lever to new tests (#21776) * fix tests, add lever to factory, fix dist scopes (#21779) * fix rubocop warning * Acd/appeals 43853 43854 (#21971) * Calvin/appeals 43853 (#21723) * initial updates * removing unnecessary variable * focused in on priority * removing non priority stuff * added general comments * added BFAC and AOD to cavc aod lever query * adding judge vacols id to query * aod affinity_start_date filter initial changes * fixed sorting * fixed rubocop issues * updated filter method * error handling * added ineligibility to queries for PREV_DECIDING_JUDGE * fixed SQL query + added comments * added exclude from affinity check into the case docket queries * error handling + fixing sql queries * rejects appeals without affinity_start_dates and nonmatching judges * fixing rubocop offenses * fixed inconsistencies between methods * fixed conditions for rejecting appeals * refactored cavc aod affinity filter to make it much easier to read * refactored code to account for AC6 * error handling for empty exclude from affinity * reverted next if block to old logic to ensure it works * added PREV_DEC_JUDGE is not null * case.rb factory changes * added more options to legacy_cavc_appeal creation * cleaned up code for simpler reading * fix for aod legacy cavc creation * added tied to option to legacy cavc appeal factory * limits are now handled correctly in query * replaced return false to next if, as return false was causing unexpected behavior * fix rspecs + one edge case * added cavc aod lever creation to rspecs * removed bfac and aod from nonpriority query * cavc aod appeals w/excluded judges are now properly being filtered * refactored excluded judges check * added to old query to fix rspec errors * modified case factory bot * query now handles when prev_deciding_judge is nil * removed unnecessary condition * fixed case factory to now have tied_to attatched to orig appeal * fixed next if block within filter * handles omit scenarios + correctly rejects with next * working on rspec (still failing) * fix for ineligble VLJ when infinite * fixed rspec suite for cavc aod filters * fixed omit scenario in cavc aod affinity filter * consolidation & readability refactor * rubocop fixes * fixed spec error * Implement CAVC Affinity for Legacy Docket (#21706) * Implement CAVC Affinity for Legacy Docket * addressed comments * Added BFAC in the query * code changes for affinitty date * Added affinity code * code refactor and removed non priority code changes * fixed syntax change * Addressed comments * refactor cavc affinity filter * refactored code * code refactor * code refactor * Updated existing specs * code refactor * Added new rspecs * code refactor and added test cases * code refactor * added test cases * fixes push_priority_spec * fixed rubocop issues * rubocop issue fixed * refactored code to make it easier to understand * refactored + fixed rspec and lint errors --------- Co-authored-by: Calvin Co-authored-by: calvincostaBAH <108481161+calvincostaBAH@users.noreply.github.com> * basic creation of legacy affinity cases seed data * bug fixes, added bfcorlid with veterans, fully runs now * added new appeals for affinity_and_tied_to_judge * made data have realistic bfcorlids * changes document sequence to use less digits * added new file numbers for tied_to cases to make them easier to identify --------- Co-authored-by: samasudhirreddy <108430298+samasudhirreddy@users.noreply.github.com> * APPEALS-50692: Update Appeals Ready to Distribute CSV to include CAVC remand original judge (#22070) * CSV download functional * add tests, fix CSV query in CaseDocket * fix lint * Calvin/appeals 44313 (#22119) * initial seed data file * added legacy cavc and cavc aod affinity cases * update * fixed tied to for legacy appeals * added AOD versions of appeals * small lint fixes * ensured AOD cases for legacy hearings with exluded or ineligible judge * added vacols staff record creation for users without it * APPEALS-47741: Update the UpdateAppealAffinityDatesJob to add appeal_affinity records for Legacy Appeals (#22023) * AC1: changes and respective tests * adjustements after refactoring * identifier mismatch * name update * name update * added appeal affinity filter * updated comment * remove byebug * update rspec to handle hash input * added no start date test case * updated process method test * removed 'todo' comment * dried up query string * aligned conditions * update to hash quotations * update to hash quotations * added legacy to priority receipt dates from dist. * moved append to resulting list * added legacy receipt date to push job hash * uncomment call to legacy * updated dist.id to @dist_id * uncomment call to process legacy appeals * handling update to legacy docket type * current rspec status * fixed typo * fix rspec * legacy spec additions * legacy spec additions * added legacy dist. case factory * removed vacols_judge ref * updates for spec * final review * removed comment * rubocop fixes * fix rubocop warnings (#22225) * Fix rubocop and tests (#22231) * Calvin/appeals 52551 (#22293) * age_of_n_oldest_priority_appeals_available_to_judge time out changes * fixed timeout issue for distribute_priority_appeals * fixed lint errors * Craig/case docket optimization (#22294) * age_of_n_oldest_priority_appeals_available_to_judge time out changes * fixed timeout issue for distribute_priority_appeals * optimize case docket priority distribution methods * fix das deprecation distribution spec --------- Co-authored-by: Calvin * Update admin_ui_spec.rb for CAVC levers being enabled --------- Co-authored-by: calvincostaBAH <108481161+calvincostaBAH@users.noreply.github.com> Co-authored-by: samasudhirreddy <108430298+samasudhirreddy@users.noreply.github.com> Co-authored-by: Calvin Co-authored-by: seanrpa <155660052+seanrpa@users.noreply.github.com> Co-authored-by: Isaiah Saucedo --- ...se_distribution_levers_tests_controller.rb | 1 + app/jobs/update_appeal_affinity_dates_job.rb | 89 +- app/models/case_distribution_lever.rb | 2 + app/models/concerns/distribution_scopes.rb | 135 ++- app/models/docket.rb | 2 +- app/models/vacols/case_docket.rb | 428 ++++++-- app/queries/appeals_ready_for_distribution.rb | 21 +- .../hearing_request_distribution_query.rb | 16 +- db/seeds/case_distribution_levers.rb | 4 +- db/seeds/cavc_affinity_levers_test_data.rb | 933 ++++++++++++++++++ db/seeds/legacy_affinity_cases.rb | 310 ++++++ ...se_distribution_levers_tests_controller.rb | 26 + spec/factories/distributed_case.rb | 15 +- spec/factories/document.rb | 2 +- spec/factories/user.rb | 12 + spec/factories/vacols/case.rb | 162 ++- .../case_distribution_levers/admin_ui_spec.rb | 6 +- .../jobs/incomplete_distributions_job_spec.rb | 1 + ...ush_priority_appeals_to_judges_job_spec.rb | 3 +- .../update_appeal_affinity_dates_job_spec.rb | 73 +- spec/models/case_distribution_lever_spec.rb | 2 + .../by_docket_date_distribution_spec.rb | 2 + spec/models/distribution_spec.rb | 1 + spec/models/docket_spec.rb | 8 +- .../dockets/hearing_request_docket_spec.rb | 59 +- spec/models/dockets/legacy_docket_spec.rb | 2 + spec/models/vacols/case_docket_spec.rb | 335 ++++++- .../queries/appeals_ready_for_distribution.rb | 142 +++ .../das_deprecation/case_distribution_spec.rb | 2 + 29 files changed, 2657 insertions(+), 137 deletions(-) create mode 100644 db/seeds/cavc_affinity_levers_test_data.rb create mode 100644 db/seeds/legacy_affinity_cases.rb create mode 100644 spec/controllers/case_distribution_levers_tests_controller.rb create mode 100644 spec/queries/appeals_ready_for_distribution.rb diff --git a/app/controllers/case_distribution_levers_tests_controller.rb b/app/controllers/case_distribution_levers_tests_controller.rb index b13763b071d..11ccd90e0c8 100644 --- a/app/controllers/case_distribution_levers_tests_controller.rb +++ b/app/controllers/case_distribution_levers_tests_controller.rb @@ -98,6 +98,7 @@ def ineligible_judge_list def check_environment return true if Rails.env.development? + return true if Rails.env.test? return true if Rails.deploy_env?(:demo) redirect_to "/unauthorized" diff --git a/app/jobs/update_appeal_affinity_dates_job.rb b/app/jobs/update_appeal_affinity_dates_job.rb index a2875f2823c..6af56da9621 100644 --- a/app/jobs/update_appeal_affinity_dates_job.rb +++ b/app/jobs/update_appeal_affinity_dates_job.rb @@ -29,8 +29,7 @@ def update_from_requested_distribution return if receipt_date_hashes_array.empty? process_ama_appeals_which_need_affinity_updates(receipt_date_hashes_array) - # Uncomment this while implementing legacy appeal affinities - # process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array) + process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array) end def update_from_push_priority_appeals_job @@ -38,8 +37,7 @@ def update_from_push_priority_appeals_job return if receipt_date_hashes_array.empty? process_ama_appeals_which_need_affinity_updates(receipt_date_hashes_array) - # Uncomment this while implementing legacy appeal affinities - # process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array) + process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array) end def latest_receipt_dates_from_distribution @@ -50,9 +48,24 @@ def latest_receipt_dates_from_distribution .group("docket", "priority") .maximum("receipt_date") - format_distributed_case_hash(distributed_cases_hash) + legacy_nonpriority_receipt_date = + DistributedCase.where(docket: "legacy", priority: false, distribution_id: @distribution_id) + .map { |c| VACOLS::Case.find_by(bfkey: c.case_id).bfd19 }.max + + legacy_priority_receipt_date = + DistributedCase.where(docket: "legacy", priority: true, distribution_id: @distribution_id) + .map { |c| VACOLS::Case.find_by(bfkey: c.case_id).bfd19 }.max + + legacy_nonpriority_hash = { docket: "legacy", priority: false, receipt_date: legacy_nonpriority_receipt_date } + legacy_priority_hash = { docket: "legacy", priority: true, receipt_date: legacy_priority_receipt_date } + + result = format_distributed_case_hash(distributed_cases_hash) + result << legacy_nonpriority_hash unless legacy_nonpriority_receipt_date.nil? + result << legacy_priority_hash unless legacy_priority_receipt_date.nil? + result end + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def latest_receipt_dates_from_push_job distributed_cases_hash = DistributedCase @@ -62,8 +75,31 @@ def latest_receipt_dates_from_push_job .group("docket", "priority") .maximum("receipt_date") - format_distributed_case_hash(distributed_cases_hash) + legacy_nonpriority_receipt_date = + DistributedCase + .includes(:distribution) + .where(docket: "legacy", + priority: false, + distributions: { priority_push: true, completed_at: Time.zone.today.midnight..Time.zone.now }) + .map { |c| VACOLS::Case.find_by(bfkey: c.case_id).bfd19 }.max + + legacy_priority_receipt_date = + DistributedCase + .includes(:distribution) + .where(docket: "legacy", + priority: true, + distributions: { priority_push: true, completed_at: Time.zone.today.midnight..Time.zone.now }) + .map { |c| VACOLS::Case.find_by(bfkey: c.case_id).bfd19 }.max + + legacy_nonpriority_hash = { docket: "legacy", priority: false, receipt_date: legacy_nonpriority_receipt_date } + legacy_priority_hash = { docket: "legacy", priority: true, receipt_date: legacy_priority_receipt_date } + + result = format_distributed_case_hash(distributed_cases_hash) + result << legacy_nonpriority_hash unless legacy_nonpriority_receipt_date.nil? + result << legacy_priority_hash unless legacy_priority_receipt_date.nil? + result end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def format_distributed_case_hash(distributed_cases_hash) # If there isn't a held hearing and it isn't a CAVC remand (priority), then there will never be an affinity @@ -94,13 +130,37 @@ def process_ama_appeals_which_need_affinity_updates(receipt_date_hashes_array) else base_appeals_to_update.nonpriority end - create_or_update_appeal_affinities(appeals_to_update_adjusted_for_priority, receipt_date_hash[:priority]) end end - # To be implemented in future work - def process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array); end + # Returns only legacy appeals with no affinity record or affinity start date + def legacy_appeals_with_no_appeal_affinities(appeals_hash) + appeals_with_no_affinities = [] + + appeals_hash.each do |appeal| + key = appeal["bfkey"] + appeal_record = VACOLS::Case.find_by(bfkey: key) + + if appeal_record && + (appeal_record.appeal_affinity.blank? || appeal_record.appeal_affinity.affinity_start_date.blank?) + appeals_with_no_affinities << appeal_record + end + end + + appeals_with_no_affinities + end + + def process_legacy_appeals_which_need_affinity_updates(receipt_date_hashes_array) + receipt_date_hashes_array.map do |receipt_date_hash| + next unless receipt_date_hash[:docket] == LegacyDocket.docket_type + + legacy_appeals_hash = VACOLS::CaseDocket.update_appeal_affinity_dates_query(receipt_date_hash[:priority], + receipt_date_hash[:receipt_date]) + legacy_appeals_to_update_adjusted_for_affinity = legacy_appeals_with_no_appeal_affinities(legacy_appeals_hash) + create_or_update_appeal_affinities(legacy_appeals_to_update_adjusted_for_affinity, receipt_date_hash[:priority]) + end + end # The appeals arg can be an array of VACOLS::Case objects, they have the same affinity associations as Appeal objects def create_or_update_appeal_affinities(appeals, priority) @@ -110,13 +170,12 @@ def create_or_update_appeal_affinities(appeals, priority) if existing_affinity existing_affinity.update!(affinity_start_date: Time.zone.now, distribution_id: @distribution_id) existing_affinity + elsif appeal.is_a?(VACOLS::Case) + appeal.create_appeal_affinity!(docket: LegacyDocket.docket_type, priority: priority, + affinity_start_date: Time.zone.now, distribution_id: @distribution_id) else - appeal.create_appeal_affinity!( - docket: appeal.docket_type, - priority: priority, - affinity_start_date: Time.zone.now, - distribution_id: @distribution_id - ) + appeal.create_appeal_affinity!(docket: appeal.docket_type, priority: priority, + affinity_start_date: Time.zone.now, distribution_id: @distribution_id) end end end diff --git a/app/models/case_distribution_lever.rb b/app/models/case_distribution_lever.rb index 6db4b0cbd8e..54d9c59ae1e 100644 --- a/app/models/case_distribution_lever.rb +++ b/app/models/case_distribution_lever.rb @@ -21,6 +21,8 @@ class CaseDistributionLever < ApplicationRecord #{Constants.DISTRIBUTION.ama_hearing_case_affinity_days} #{Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days} #{Constants.DISTRIBUTION.cavc_affinity_days} + #{Constants.DISTRIBUTION.cavc_aod_affinity_days} + #{Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days} #{Constants.DISTRIBUTION.ama_evidence_submission_docket_time_goals} #{Constants.DISTRIBUTION.ama_hearing_docket_time_goals} #{Constants.DISTRIBUTION.ama_hearing_start_distribution_prior_to_goals} diff --git a/app/models/concerns/distribution_scopes.rb b/app/models/concerns/distribution_scopes.rb index f256c7cbc08..2398b197ae0 100644 --- a/app/models/concerns/distribution_scopes.rb +++ b/app/models/concerns/distribution_scopes.rb @@ -45,9 +45,112 @@ def ready_for_distribution .where(tasks: { type: DistributionTask.name, status: Constants.TASK_STATUSES.assigned }) end - def genpop + def genpop_base_query with_appeal_affinities .with_original_appeal_and_judge_task + .include_aod_motions + end + + def genpop_with_case_distribution_lever + genpop_cavc_affinity_days_query = generate_genpop_cavc_affinity_days_lever_query + genpop_cavc_aod_affinity_days_query = generate_genpop_cavc_aod_affinity_days_lever_query.group("appeals.id") + + result = genpop_cavc_affinity_days_query.or(genpop_cavc_aod_affinity_days_query) + + if FeatureToggle.enabled?(:acd_cases_tied_to_judges_no_longer_with_board) + result = result.or( + genpop_base_query + .where("original_judge_task.assigned_to_id in (?)", HearingRequestDistributionQuery.ineligible_judges_id_cache) + .group("appeals.id") + ) + end + + if FeatureToggle.enabled?(:acd_exclude_from_affinity) + result = result.or( + genpop_base_query + .where("original_judge_task.assigned_to_id in (?)", JudgeTeam.judges_with_exclude_appeals_from_affinity) + .group("appeals.id") + ) + end + + result + end + + def generate_genpop_cavc_affinity_days_lever_query + if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.cavc_affinity_days) + genpop_base_query + .ama_non_aod_appeals + .where( + "appeals.stream_type != ? OR appeal_affinities.affinity_start_date <= ?", + Constants.AMA_STREAM_TYPES.court_remand, + CaseDistributionLever.cavc_affinity_days.days.ago + ) + elsif CaseDistributionLever.cavc_affinity_days == Constants.ACD_LEVERS.infinite + genpop_base_query + .ama_non_aod_appeals + .where("appeals.stream_type != ?", Constants.AMA_STREAM_TYPES.court_remand) + elsif CaseDistributionLever.cavc_affinity_days == Constants.ACD_LEVERS.omit + genpop_base_query + .ama_non_aod_appeals + end + end + + def generate_genpop_cavc_aod_affinity_days_lever_query + if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.cavc_aod_affinity_days) + genpop_base_query + .ama_aod_appeals + .where( + "appeals.stream_type != ? OR appeal_affinities.affinity_start_date < ?", + Constants.AMA_STREAM_TYPES.court_remand, + CaseDistributionLever.cavc_aod_affinity_days.days.ago + ) + elsif CaseDistributionLever.cavc_aod_affinity_days == Constants.ACD_LEVERS.infinite + genpop_base_query + .ama_aod_appeals + .where("appeals.stream_type != ?", Constants.AMA_STREAM_TYPES.court_remand) + elsif CaseDistributionLever.cavc_aod_affinity_days == Constants.ACD_LEVERS.omit + genpop_base_query + .ama_aod_appeals + end + end + + def non_genpop_with_case_distribution_lever(judge) + non_genpop_cavc_affinity_days_query = generate_non_genpop_cavc_affinity_days_lever_query(judge) + non_genpop_cavc_aod_affinity_days_query = generate_non_genpop_cavc_aod_affinity_days_lever_query(judge) + + non_genpop_cavc_affinity_days_query.or(non_genpop_cavc_aod_affinity_days_query) + end + + def generate_non_genpop_cavc_affinity_days_lever_query(judge) + if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.cavc_affinity_days) + non_genpop_for_judge(judge) + .ama_non_aod_appeals + elsif CaseDistributionLever.cavc_affinity_days == Constants.ACD_LEVERS.infinite + genpop_base_query + .ama_non_aod_appeals + .where(original_judge_task: { assigned_to_id: judge&.id }, + appeals: { stream_type: Constants.AMA_STREAM_TYPES.court_remand }) + elsif CaseDistributionLever.cavc_affinity_days == Constants.ACD_LEVERS.omit + genpop_base_query.ama_non_aod_appeals.none + end + end + + def generate_non_genpop_cavc_aod_affinity_days_lever_query(judge) + if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.cavc_aod_affinity_days) + non_genpop_for_judge(judge, CaseDistributionLever.cavc_aod_affinity_days) + .ama_non_aod_appeals + elsif CaseDistributionLever.cavc_aod_affinity_days == Constants.ACD_LEVERS.infinite + genpop_base_query + .ama_non_aod_appeals + .where(original_judge_task: { assigned_to_id: judge&.id }, + appeals: { stream_type: Constants.AMA_STREAM_TYPES.court_remand }) + elsif CaseDistributionLever.cavc_aod_affinity_days == Constants.ACD_LEVERS.omit + genpop_base_query.ama_non_aod_appeals.none + end + end + + def genpop + genpop_base_query .where( "appeals.stream_type != ? OR appeal_affinities.affinity_start_date <= ? @@ -58,13 +161,16 @@ def genpop ) end - def ama_non_aod_hearing_appeals - where("advance_on_docket_motions.person_id IS NULL") - .where("people.date_of_birth > ?", 75.years.ago) + def ama_non_aod_appeals + where("people.date_of_birth > ? or people.date_of_birth is null", 75.years.ago) + .group("appeals.id") + .having("count(case when advance_on_docket_motions.granted "\ + "\n and advance_on_docket_motions.created_at > appeals.established_at then 1 end) = ?", 0) end - def ama_aod_hearing_appeals - where("advance_on_docket_motions.person_id IS NOT NULL") + def ama_aod_appeals + where("advance_on_docket_motions.created_at > appeals.established_at") + .where("advance_on_docket_motions.granted = ?", true) .or(where("people.date_of_birth <= ?", 75.years.ago)) end @@ -81,11 +187,10 @@ def with_original_appeal_and_judge_task # docket.rb # Within the first 21 days, the appeal should be distributed only to the issuing judge. - def non_genpop_for_judge(judge) - with_appeal_affinities - .with_original_appeal_and_judge_task + def non_genpop_for_judge(judge, lever_days = CaseDistributionLever.cavc_affinity_days) + genpop_base_query .where("appeal_affinities.affinity_start_date > ? or appeal_affinities.affinity_start_date is null", - CaseDistributionLever.cavc_affinity_days.days.ago) + lever_days.days.ago) .where(original_judge_task: { assigned_to_id: judge&.id }) end @@ -176,4 +281,14 @@ def case_affinity_days_lever_value_is_selected?(lever_value) true end + + def exclude_affinity_and_ineligible_judge_ids + judge_ids = JudgeTeam.judges_with_exclude_appeals_from_affinity + + if FeatureToggle.enabled?(:acd_cases_tied_to_judges_no_longer_with_board) + judge_ids.push(*HearingRequestDistributionQuery.ineligible_judges_id_cache) + end + + judge_ids + end end diff --git a/app/models/docket.rb b/app/models/docket.rb index dcc314580af..8306ab0442f 100644 --- a/app/models/docket.rb +++ b/app/models/docket.rb @@ -187,7 +187,7 @@ def adjust_for_genpop(scope, genpop, judge) end def adjust_for_affinity(scope, judge) - scope.genpop.or(scope.non_genpop_for_judge(judge)) + scope.genpop_with_case_distribution_lever.or(scope.non_genpop_with_case_distribution_lever(judge)) end def scoped_for_priority(scope) diff --git a/app/models/vacols/case_docket.rb b/app/models/vacols/case_docket.rb index 02c0062f55d..c73331de951 100644 --- a/app/models/vacols/case_docket.rb +++ b/app/models/vacols/case_docket.rb @@ -78,13 +78,15 @@ class DocketNumberCentennialLoop < StandardError; end " SELECT_READY_APPEALS = " - select BFKEY, BFD19, BFDLOOUT, BFMPRO, BFCURLOC, BFAC, BFHINES, TINUM, TITRNUM, AOD + select BFKEY, BFD19, BFCORLID, BFDLOOUT, BFMPRO, BFCURLOC, BFAC, BFHINES, TINUM, TITRNUM, AOD, + BFMEMID, BFDPDCN #{FROM_READY_APPEALS} " # this version of the query should not be used during distribution it is only intended for reporting usage SELECT_READY_APPEALS_ADDITIONAL_COLS = " - select BFKEY, BFD19, BFDLOOUT, BFMPRO, BFCURLOC, BFAC, BFHINES, TINUM, TITRNUM, AOD, BFCORKEY, BFCORLID + select BFKEY, BFD19, BFDLOOUT, BFMPRO, BFCURLOC, BFAC, BFHINES, TINUM, TITRNUM, AOD, BFMEMID, BFDPDCN, + BFCORKEY, BFCORLID #{FROM_READY_APPEALS} " @@ -103,31 +105,52 @@ class DocketNumberCentennialLoop < StandardError; end and (VLJ_HEARINGS.TINUM is null or VLJ_HEARINGS.TINUM = BRIEFF.TINUM) " + # Provide access to legacy appeal decisions for more complete appeals history queries + JOIN_PREVIOUS_APPEALS = " + left join ( + select B.BFKEY as PREV_BFKEY, B.BFCORLID as PREV_BFCORLID, B.BFDDEC as PREV_BFDDEC, + B.BFMEMID as PREV_DECIDING_JUDGE, B.BFAC as PREV_TYPE_ACTION, F.TINUM as PREV_TINUM, + F.TITRNUM as PREV_TITRNUM + from BRIEFF B + inner join FOLDER F on F.TICKNUM = B.BFKEY + + where B.BFMPRO = 'HIS' and B.BFMEMID not in ('000', '888', '999') and B.BFATTID is not null + ) PREV_APPEAL + on PREV_APPEAL.PREV_BFKEY != BRIEFF.BFKEY and PREV_APPEAL.PREV_BFCORLID = BRIEFF.BFCORLID + and PREV_APPEAL.PREV_TINUM = BRIEFF.TINUM and PREV_APPEAL.PREV_TITRNUM = BRIEFF.TITRNUM + and PREV_APPEAL.PREV_BFDDEC = BRIEFF.BFDPDCN + " + SELECT_PRIORITY_APPEALS = " - select BFKEY, BFDLOOUT, VLJ + select BFKEY, BFDLOOUT, BFAC, AOD, VLJ, PREV_TYPE_ACTION, PREV_DECIDING_JUDGE from ( - select BFKEY, BFDLOOUT, - VLJ_HEARINGS.VLJ + select BFKEY, BFDLOOUT, BFAC, AOD, + VLJ_HEARINGS.VLJ, + PREV_APPEAL.PREV_TYPE_ACTION PREV_TYPE_ACTION, + PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE from ( #{SELECT_READY_APPEALS} and (BFAC = '7' or AOD = '1') order by BFDLOOUT ) BRIEFF #{JOIN_ASSOCIATED_VLJS_BY_HEARINGS} + #{JOIN_PREVIOUS_APPEALS} ) " SELECT_PRIORITY_APPEALS_ORDER_BY_BFD19 = " - select BFKEY, BFD19, BFDLOOUT, VLJ + select BFKEY, BFD19, BFDLOOUT, BFAC, AOD, VLJ, PREV_TYPE_ACTION, PREV_DECIDING_JUDGE from ( - select BFKEY, BFD19, BFDLOOUT, - VLJ_HEARINGS.VLJ + select BFKEY, BFD19, BFDLOOUT, BFAC, AOD, + VLJ_HEARINGS.VLJ, + PREV_APPEAL.PREV_TYPE_ACTION PREV_TYPE_ACTION, + PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE from ( #{SELECT_READY_APPEALS} and (BFAC = '7' or AOD = '1') - order by BFDLOOUT ) BRIEFF #{JOIN_ASSOCIATED_VLJS_BY_HEARINGS} + #{JOIN_PREVIOUS_APPEALS} order by BFD19 ) " @@ -147,16 +170,18 @@ class DocketNumberCentennialLoop < StandardError; end " SELECT_NONPRIORITY_APPEALS_ORDER_BY_BFD19 = " - select BFKEY, BFD19, BFDLOOUT, VLJ, DOCKET_INDEX + select BFKEY, BFD19, BFDLOOUT, VLJ, BFAC, DOCKET_INDEX, PREV_TYPE_ACTION, PREV_DECIDING_JUDGE from ( - select BFKEY, BFD19, BFDLOOUT, rownum DOCKET_INDEX, - VLJ_HEARINGS.VLJ + select BFKEY, BFD19, BFDLOOUT, BFAC, rownum DOCKET_INDEX, + VLJ_HEARINGS.VLJ, + PREV_APPEAL.PREV_TYPE_ACTION PREV_TYPE_ACTION, + PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE from ( #{SELECT_READY_APPEALS} and BFAC <> '7' and AOD = '0' - order by case when substr(TINUM, 1, 2) between '00' and '29' then 1 else 0 end, TINUM ) BRIEFF #{JOIN_ASSOCIATED_VLJS_BY_HEARINGS} + #{JOIN_PREVIOUS_APPEALS} order by BFD19 ) " @@ -166,21 +191,24 @@ class DocketNumberCentennialLoop < StandardError; end select APPEALS.BFKEY, APPEALS.TINUM, APPEALS.BFD19, APPEALS.BFDLOOUT, APPEALS.AOD, APPEALS.BFCORLID, CORRES.SNAMEF, CORRES.SNAMEL, CORRES.SSN, STAFF.SNAMEF as VLJ_NAMEF, STAFF.SNAMEL as VLJ_NAMEL, - case when APPEALS.BFAC = '7' then 1 else 0 end CAVC + case when APPEALS.BFAC = '7' then 1 else 0 end CAVC, PREV_TYPE_ACTION, + PREV_DECIDING_JUDGE from ( select BFKEY, BRIEFF.TINUM, BFD19, BFDLOOUT, BFAC, BFCORKEY, AOD, BFCORLID, - VLJ_HEARINGS.VLJ + VLJ_HEARINGS.VLJ, + PREV_APPEAL.PREV_TYPE_ACTION PREV_TYPE_ACTION, + PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE from ( #{SELECT_READY_APPEALS_ADDITIONAL_COLS} ) BRIEFF #{JOIN_ASSOCIATED_VLJS_BY_HEARINGS} + #{JOIN_PREVIOUS_APPEALS} order by BFD19 ) APPEALS left join CORRES on APPEALS.BFCORKEY = CORRES.STAFKEY - left join STAFF on APPEALS.VLJ = STAFF.STAFKEY + left join STAFF on APPEALS.VLJ = STAFF.SATTYID order by BFD19 " - # rubocop:disable Metrics/MethodLength def self.counts_by_priority_and_readiness query = <<-SQL @@ -306,7 +334,7 @@ def self.age_of_n_oldest_genpop_priority_appeals(num) query = <<-SQL #{SELECT_PRIORITY_APPEALS} - where (VLJ is null or #{ineligible_judges_sattyid_cache}) and rownum <= ? + where (VLJ is null or #{ineligible_judges_sattyid_cache} or #{ineligible_judges_sattyid_cache(true)}) and rownum <= ? SQL fmtd_query = sanitize_sql_array([query, num]) @@ -315,24 +343,65 @@ def self.age_of_n_oldest_genpop_priority_appeals(num) appeals.map { |appeal| appeal["bfdloout"] } end + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize def self.age_of_n_oldest_priority_appeals_available_to_judge(judge, num) + cavc_affinity_lever_value = CaseDistributionLever.cavc_affinity_days + cavc_aod_affinity_lever_value = CaseDistributionLever.cavc_aod_affinity_days + + judge_sattyid = judge.vacols_attorney_id + excluded_judges_attorney_ids = excluded_judges_sattyids + + priority_cdl_query = generate_priority_case_distribution_lever_query(cavc_affinity_lever_value) + priority_cdl_aod_query = generate_priority_case_distribution_lever_aod_query(cavc_aod_affinity_lever_value) + conn = connection - query = <<-SQL - #{SELECT_PRIORITY_APPEALS_ORDER_BY_BFD19} - where (VLJ = ? or #{ineligible_judges_sattyid_cache} or VLJ is null) - and rownum <= ? - SQL + # {Query is broken up differently for when both levers are infinite due to a timeout caused by the large query} + query = if cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.infinite && + cavc_affinity_lever_value == Constants.ACD_LEVERS.infinite + <<-SQL + #{SELECT_PRIORITY_APPEALS_ORDER_BY_BFD19} + where (VLJ = ? or #{ineligible_judges_sattyid_cache} or VLJ is null + or ((PREV_DECIDING_JUDGE = ? or #{ineligible_judges_sattyid_cache(true)} + or #{vacols_judges_with_exclude_appeals_from_affinity(excluded_judges_attorney_ids)}) + and (#{priority_cdl_query} or #{priority_cdl_aod_query}))) + SQL + else + <<-SQL + #{SELECT_PRIORITY_APPEALS_ORDER_BY_BFD19} + where (VLJ = ? or #{ineligible_judges_sattyid_cache} or VLJ is null + or #{priority_cdl_query} or #{priority_cdl_aod_query}) + SQL + end - fmtd_query = sanitize_sql_array([ - query, - judge.vacols_attorney_id, - num - ]) + fmtd_query = if cavc_aod_affinity_lever_value != Constants.ACD_LEVERS.infinite && + cavc_affinity_lever_value != Constants.ACD_LEVERS.infinite + sanitize_sql_array([ + query, + judge_sattyid, + judge_sattyid, + judge_sattyid + ]) + else + sanitize_sql_array([ + query, + judge_sattyid, + judge_sattyid + ]) + end appeals = conn.exec_query(fmtd_query).to_a + + cavc_affinity_filter(appeals, judge_sattyid, cavc_affinity_lever_value, excluded_judges_attorney_ids) + cavc_aod_affinity_filter(appeals, judge_sattyid, cavc_aod_affinity_lever_value, excluded_judges_attorney_ids) + + appeals.sort_by { |appeal| appeal[:bfd19] } if use_by_docket_date? + + appeals = appeals.first(num) unless num.nil? # {Reestablishes the limit} + appeals.map { |appeal| appeal["bfd19"] } end + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize def self.age_of_n_oldest_nonpriority_appeals_available_to_judge(judge, num) conn = connection @@ -423,7 +492,44 @@ def self.ready_to_distribute_appeals connection.exec_query(fmtd_query).to_a end - # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/ParameterLists, Metrics/MethodLength + # rubocop:disable Metrics/MethodLength + def self.update_appeal_affinity_dates_query(priority, date) + priority_condition = if priority + "and (BFAC = '7' or AOD = '1')" + else + "and BFAC <> '7' and AOD = '0'" + end + + query = <<-SQL + select APPEALS.BFKEY, APPEALS.TINUM, APPEALS.BFD19, APPEALS.BFDLOOUT, APPEALS.AOD, APPEALS.BFCORLID, + CORRES.SNAMEF, CORRES.SNAMEL, CORRES.SSN, + STAFF.SNAMEF as VLJ_NAMEF, STAFF.SNAMEL as VLJ_NAMEL, + case when APPEALS.BFAC = '7' then 1 else 0 end CAVC, PREV_TYPE_ACTION, + PREV_DECIDING_JUDGE + from ( + select BFKEY, BRIEFF.TINUM, BFD19, BFDLOOUT, BFAC, BFCORKEY, AOD, BFCORLID, + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ, + PREV_APPEAL.PREV_TYPE_ACTION PREV_TYPE_ACTION, + PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE + from ( + #{SELECT_READY_APPEALS_ADDITIONAL_COLS} + #{priority_condition} + ) BRIEFF + #{JOIN_ASSOCIATED_VLJS_BY_HEARINGS} + #{JOIN_PREVIOUS_APPEALS} + order by BFD19 + ) APPEALS + left join CORRES on APPEALS.BFCORKEY = CORRES.STAFKEY + left join STAFF on APPEALS.VLJ = STAFF.STAFKEY + where APPEALS.BFD19 <= TO_DATE('#{date}', 'YYYY-MM-DD HH24:MI:SS') + order by BFD19 + SQL + + fmtd_query = sanitize_sql_array([query]) + connection.exec_query(fmtd_query).to_a + end + + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/ParameterLists def self.distribute_nonpriority_appeals(judge, genpop, range, limit, bust_backlog, dry_run = false) fail(DocketNumberCentennialLoop, COPY::MAX_LEGACY_DOCKET_NUMBER_ERROR_MESSAGE) if Time.zone.now.year >= 2030 @@ -432,7 +538,6 @@ def self.distribute_nonpriority_appeals(judge, genpop, range, limit, bust_backlo #{SELECT_NONPRIORITY_APPEALS_ORDER_BY_BFD19} where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) or (VLJ is null and 1 = ?)) and (DOCKET_INDEX <= ? or 1 = ?) - and rownum <= ? SQL else # Docket numbers begin with the two digit year. The Board of Veterans Appeals was created in 1930. @@ -452,7 +557,6 @@ def self.distribute_nonpriority_appeals(judge, genpop, range, limit, bust_backlo #{SELECT_NONPRIORITY_APPEALS} where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) or (VLJ is null and 1 = ?)) and (DOCKET_INDEX <= ? or 1 = ?) - and rownum <= ? SQL end @@ -462,55 +566,102 @@ def self.distribute_nonpriority_appeals(judge, genpop, range, limit, bust_backlo (genpop == "any" || genpop == "not_genpop") ? 1 : 0, (genpop == "any" || genpop == "only_genpop") ? 1 : 0, range, - range.nil? ? 1 : 0, - limit + range.nil? ? 1 : 0 ]) - distribute_appeals(fmtd_query, judge, dry_run) + distribute_appeals(fmtd_query, judge, limit, dry_run) end - # rubocop:enable Metrics/ParameterLists, Metrics/MethodLength + # rubocop:disable Metrics/AbcSize def self.distribute_priority_appeals(judge, genpop, limit, dry_run = false) - query = if use_by_docket_date? + cavc_affinity_lever_value = CaseDistributionLever.cavc_affinity_days + cavc_aod_affinity_lever_value = CaseDistributionLever.cavc_aod_affinity_days + + judge_sattyid = judge.vacols_attorney_id + excluded_judges_attorney_ids = excluded_judges_sattyids + + priority_cdl_query = generate_priority_case_distribution_lever_query(cavc_affinity_lever_value) + priority_cdl_aod_query = generate_priority_case_distribution_lever_aod_query(cavc_aod_affinity_lever_value) + + # {Query is broken up differently for when both levers are infinite due to a timeout caused by the large query} + query = if use_by_docket_date? && cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.infinite && + cavc_affinity_lever_value == Constants.ACD_LEVERS.infinite <<-SQL #{SELECT_PRIORITY_APPEALS_ORDER_BY_BFD19} - where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) or (VLJ is null and 1 = ?)) - and (rownum <= ? or 1 = ?) + where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) + or (VLJ is null and 1 = ?) + or ((PREV_DECIDING_JUDGE = ? or #{ineligible_judges_sattyid_cache(true)} + or #{vacols_judges_with_exclude_appeals_from_affinity(excluded_judges_attorney_ids)}) + and (#{priority_cdl_query} or #{priority_cdl_aod_query}))) + SQL + elsif use_by_docket_date? + <<-SQL + #{SELECT_PRIORITY_APPEALS} + where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) + or (VLJ is null and 1 = ?) or #{priority_cdl_query} or #{priority_cdl_aod_query}) SQL else <<-SQL #{SELECT_PRIORITY_APPEALS} - where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) or (VLJ is null and 1 = ?)) - and (rownum <= ? or 1 = ?) + where (((VLJ = ? or #{ineligible_judges_sattyid_cache}) and 1 = ?) + or (VLJ is null and 1 = ?) or #{priority_cdl_query} or #{priority_cdl_aod_query}) SQL end - fmtd_query = sanitize_sql_array([ - query, - judge.vacols_attorney_id, - (genpop == "any" || genpop == "not_genpop") ? 1 : 0, - (genpop == "any" || genpop == "only_genpop") ? 1 : 0, - limit, - limit.nil? ? 1 : 0 - ]) - - distribute_appeals(fmtd_query, judge, dry_run) + fmtd_query = if cavc_aod_affinity_lever_value != Constants.ACD_LEVERS.infinite && + cavc_affinity_lever_value != Constants.ACD_LEVERS.infinite + sanitize_sql_array([ + query, + judge_sattyid, + (genpop == "any" || genpop == "not_genpop") ? 1 : 0, + (genpop == "any" || genpop == "only_genpop") ? 1 : 0, + judge_sattyid, + judge_sattyid + ]) + else + sanitize_sql_array([ + query, + judge_sattyid, + (genpop == "any" || genpop == "not_genpop") ? 1 : 0, + (genpop == "any" || genpop == "only_genpop") ? 1 : 0, + judge_sattyid + ]) + end + + distribute_appeals(fmtd_query, judge, limit, dry_run) end - # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity # :nocov: - def self.distribute_appeals(query, judge, dry_run) + def self.distribute_appeals(query, judge, limit, dry_run) + cavc_affinity_lever_value = CaseDistributionLever.cavc_affinity_days + cavc_aod_affinity_lever_value = CaseDistributionLever.cavc_aod_affinity_days + excluded_judges_attorney_ids = excluded_judges_sattyids + judge_sattyid = judge.vacols_attorney_id + conn = connection conn.transaction do if dry_run - conn.exec_query(query).to_a + dry_appeals = conn.exec_query(query).to_a + + cavc_affinity_filter(dry_appeals, judge_sattyid, cavc_affinity_lever_value, excluded_judges_attorney_ids) + cavc_aod_affinity_filter(dry_appeals, judge_sattyid, cavc_aod_affinity_lever_value, + excluded_judges_attorney_ids) + + dry_appeals else conn.execute(LOCK_READY_APPEALS) unless FeatureToggle.enabled?(:acd_disable_legacy_lock_ready_appeals) appeals = conn.exec_query(query).to_a return appeals if appeals.empty? + cavc_affinity_filter(appeals, judge_sattyid, cavc_affinity_lever_value, excluded_judges_attorney_ids) + cavc_aod_affinity_filter(appeals, judge_sattyid, cavc_aod_affinity_lever_value, excluded_judges_attorney_ids) + + appeals.sort_by { |appeal| appeal[:bfd19] } if use_by_docket_date? + + appeals = appeals.first(limit) unless limit.nil? # {Reestablishes the limit} + vacols_ids = appeals.map { |appeal| appeal["bfkey"] } location = if FeatureToggle.enabled?(:legacy_das_deprecation, user: RequestStore.store[:current_user]) LegacyAppeal::LOCATION_CODES[:caseflow] @@ -522,19 +673,147 @@ def self.distribute_appeals(query, judge, dry_run) end end end + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/ParameterLists + + def self.generate_priority_case_distribution_lever_query(cavc_affinity_lever_value) + if case_affinity_days_lever_value_is_selected?(cavc_affinity_lever_value) || + cavc_affinity_lever_value == Constants.ACD_LEVERS.omit + "((PREV_DECIDING_JUDGE = ? or PREV_DECIDING_JUDGE is null or PREV_DECIDING_JUDGE is not null) + and AOD = '0' and BFAC = '7')" + elsif cavc_affinity_lever_value == Constants.ACD_LEVERS.infinite + "(AOD = '0' and BFAC = '7')" + else + "VLJ = ?" + end + end + + def self.generate_priority_case_distribution_lever_aod_query(cavc_aod_affinity_lever_value) + if case_affinity_days_lever_value_is_selected?(cavc_aod_affinity_lever_value) || + cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.omit + "((PREV_DECIDING_JUDGE = ? or PREV_DECIDING_JUDGE is null or PREV_DECIDING_JUDGE is not null) + and AOD = '1' and BFAC = '7' )" + elsif cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.infinite + "(AOD = '1' and BFAC = '7')" + else + "VLJ = ?" + end + end def self.use_by_docket_date? FeatureToggle.enabled?(:acd_distribute_by_docket_date, user: RequestStore.store[:current_user]) end - # rubocop:disable Metrics/MethodLength - def self.ineligible_judges_sattyid_cache + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + def self.cavc_affinity_filter(appeals, judge_sattyid, cavc_affinity_lever_value, excluded_judges_attorney_ids) + appeals.reject! do |appeal| + next if tied_to_or_not_cavc?(appeal, judge_sattyid) + + if not_distributing_to_tied_judge?(appeal, judge_sattyid) + next if ineligible_judges_sattyids.include?(appeal["vlj"]) + + next (appeal["vlj"] != judge_sattyid) + end + + next if ineligible_or_excluded_deciding_judge?(appeal, excluded_judges_attorney_ids) + + if case_affinity_days_lever_value_is_selected?(cavc_affinity_lever_value) + next if appeal["prev_deciding_judge"] == judge_sattyid + + reject_due_to_affinity?(appeal, cavc_affinity_lever_value) + elsif cavc_affinity_lever_value == Constants.ACD_LEVERS.infinite + next if ineligible_judges_sattyids&.include?(appeal["vlj"]) + + appeal["prev_deciding_judge"] != judge_sattyid + elsif cavc_affinity_lever_value == Constants.ACD_LEVERS.omit + appeal["prev_deciding_judge"] == appeal["vlj"] + end + end + end + + def self.cavc_aod_affinity_filter(appeals, judge_sattyid, cavc_aod_affinity_lever_value, excluded_judges_attorney_ids) + appeals.reject! do |appeal| + # {will skip if not CAVC AOD || if CAVC AOD being distributed to tied_to judge || if not tied to any judge} + next if tied_to_or_not_cavc_aod?(appeal, judge_sattyid) + + if not_distributing_to_tied_judge?(appeal, judge_sattyid) + next if ineligible_judges_sattyids&.include?(appeal["vlj"]) + + next (appeal["vlj"] != judge_sattyid) + end + + next if ineligible_or_excluded_deciding_judge?(appeal, excluded_judges_attorney_ids) + + if case_affinity_days_lever_value_is_selected?(cavc_aod_affinity_lever_value) + next if appeal["prev_deciding_judge"] == judge_sattyid + + reject_due_to_affinity?(appeal, cavc_aod_affinity_lever_value) + elsif cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.infinite + next if ineligible_judges_sattyids&.include?(appeal["vlj"]) + + appeal["prev_deciding_judge"] != judge_sattyid + elsif cavc_aod_affinity_lever_value == Constants.ACD_LEVERS.omit + appeal["prev_deciding_judge"] == appeal["vlj"] + end + end + end + + def self.tied_to_or_not_cavc?(appeal, judge_sattyid) + (appeal["bfac"] != "7" || appeal["aod"] != 0) || + (appeal["bfac"] == "7" && appeal["aod"] == 0 && + !appeal["vlj"].blank? && + (appeal["vlj"] == appeal["prev_deciding_judge"] || appeal["prev_deciding_judge"].nil?) && + appeal["vlj"] == judge_sattyid) || + (appeal["vlj"].nil? && appeal["prev_deciding_judge"].nil?) + end + + def self.tied_to_or_not_cavc_aod?(appeal, judge_sattyid) + (appeal["bfac"] != "7" || appeal["aod"] != 1) || + (appeal["bfac"] == "7" && appeal["aod"] == 1 && + !appeal["vlj"].blank? && + (appeal["vlj"] == appeal["prev_deciding_judge"] || appeal["prev_deciding_judge"].nil?) && + appeal["vlj"] == judge_sattyid) || + (appeal["vlj"].nil? && appeal["prev_deciding_judge"].nil?) + end + + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + + def self.not_distributing_to_tied_judge?(appeal, judge_sattyid) + !appeal["vlj"].blank? && + (appeal["vlj"] == appeal["prev_deciding_judge"]) && + (appeal["vlj"] != judge_sattyid) + end + + def self.ineligible_or_excluded_deciding_judge?(appeal, excluded_judges_attorney_ids) + # {if deciding_judge is ineligible or excluded, we will skip, unless excluded deciding_judge = VLJ} + ineligible_judges_sattyids&.include?(appeal["prev_deciding_judge"]) || + (appeal["vlj"] != appeal["prev_deciding_judge"] && + excluded_judges_attorney_ids&.include?(appeal["prev_deciding_judge"])) + end + + def self.reject_due_to_affinity?(appeal, lever) + VACOLS::Case.find_by(bfkey: appeal["bfkey"])&.appeal_affinity&.affinity_start_date.nil? || + (VACOLS::Case.find_by(bfkey: appeal["bfkey"]) + .appeal_affinity + .affinity_start_date > lever.to_i.days.ago) + end + + def self.ineligible_judges_sattyids + Rails.cache.fetch("case_distribution_ineligible_judges")&.pluck(:sattyid)&.reject(&:blank?) || [] + end + + def self.excluded_judges_sattyids + VACOLS::Staff.where(sdomainid: JudgeTeam.active + .where(exclude_appeals_from_affinity: true) + .flat_map(&:judge).compact.pluck(:css_id))&.pluck(:sattyid) + end + + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength + def self.ineligible_judges_sattyid_cache(prev_deciding_judge = false) if FeatureToggle.enabled?(:acd_cases_tied_to_judges_no_longer_with_board) && - !Rails.cache.fetch("case_distribution_ineligible_judges")&.pluck(:sattyid)&.reject(&:blank?).blank? - list = Rails.cache.fetch("case_distribution_ineligible_judges")&.pluck(:sattyid)&.reject(&:blank?) + !ineligible_judges_sattyids.blank? + list = ineligible_judges_sattyids split_lists = {} num_of_lists = (list.size.to_f / 999).ceil - num_of_lists.times do |num| split_lists[num] = [] 999.times do @@ -545,15 +824,42 @@ def self.ineligible_judges_sattyid_cache vljs_strings = split_lists.flat_map do |k, v| base = "(#{v.join(', ')})" - base += " or VLJ in " unless k == split_lists.keys.last + if prev_deciding_judge + base += " or PREV_DECIDING_JUDGE in " unless k == split_lists.keys.last + else + base += " or VLJ in " unless k == split_lists.keys.last + end base end - "VLJ in #{vljs_strings.join}" + if prev_deciding_judge + "PREV_DECIDING_JUDGE in #{vljs_strings.join}" + else + "VLJ in #{vljs_strings.join}" + end + elsif prev_deciding_judge + "PREV_DECIDING_JUDGE = 'false'" else "VLJ = 'false'" end end - # rubocop:enable Metrics/MethodLength + + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize + + def self.vacols_judges_with_exclude_appeals_from_affinity(excluded_judges_attorney_ids) + return "PREV_DECIDING_JUDGE = 'false'" unless FeatureToggle.enabled?(:acd_exclude_from_affinity) + + if excluded_judges_attorney_ids.blank? + "PREV_DECIDING_JUDGE = 'false'" + else + "PREV_DECIDING_JUDGE in (#{excluded_judges_attorney_ids.join(', ')})" + end + end + + def self.case_affinity_days_lever_value_is_selected?(lever_value) + return false if lever_value == "omit" || lever_value == "infinite" + + true + end end # rubocop:enable Metrics/ClassLength diff --git a/app/queries/appeals_ready_for_distribution.rb b/app/queries/appeals_ready_for_distribution.rb index 5f6ce4c7a99..0675a688ad0 100644 --- a/app/queries/appeals_ready_for_distribution.rb +++ b/app/queries/appeals_ready_for_distribution.rb @@ -12,6 +12,7 @@ class AppealsReadyForDistribution target_distro_date: "Target Distro Date", days_before_goal_date: "Days Before Goal Date", hearing_judge: "Hearing Judge", + original_judge: "Original Deciding Judge", veteran_file_number: "Veteran File number", veteran_name: "Veteran", affinity_start_date: "Affinity Start Date" @@ -53,9 +54,7 @@ def self.ready_appeals def self.legacy_rows(appeals, docket, sym) appeals.map do |appeal| - veteran_name = FullName.new(appeal["snamef"], nil, appeal["snamel"]).to_s vlj_name = FullName.new(appeal["vlj_namef"], nil, appeal["vlj_namel"]).to_s - hearing_judge = vlj_name.empty? ? nil : vlj_name appeal_affinity = AppealAffinity.find_by(case_id: appeal["bfkey"], case_type: "VACOLS::Case") { @@ -67,9 +66,10 @@ def self.legacy_rows(appeals, docket, sym) ready_for_distribution_at: appeal["bfdloout"], target_distro_date: target_distro_date(appeal["bfd19"], docket), days_before_goal_date: days_before_goal_date(appeal["bfd19"], docket), - hearing_judge: hearing_judge, + hearing_judge: vlj_name.empty? ? nil : vlj_name, + original_judge: appeal["prev_deciding_judge"].nil? ? nil : legacy_original_deciding_judge(appeal), veteran_file_number: appeal["ssn"] || appeal["bfcorlid"], - veteran_name: veteran_name, + veteran_name: FullName.new(appeal["snamef"], nil, appeal["snamel"]).to_s, affinity_start_date: appeal_affinity&.affinity_start_date } end @@ -91,6 +91,7 @@ def self.ama_rows(appeals, docket, sym) target_distro_date: target_distro_date(appeal.receipt_date, docket), days_before_goal_date: days_before_goal_date(appeal.receipt_date, docket), hearing_judge: hearing_judge, + original_judge: appeal.cavc? ? ama_cavc_original_deciding_judge(appeal) : nil, veteran_file_number: appeal.veteran_file_number, veteran_name: appeal.veteran&.name.to_s, affinity_start_date: appeal.appeal_affinity&.affinity_start_date @@ -127,4 +128,16 @@ def self.days_before_goal_date(receipt_date, docket) target_date - docket.start_distribution_prior_to_goal.try(:value).to_i.days end + + def self.ama_cavc_original_deciding_judge(appeal) + source_appeal_id = CavcRemand.find_by(remand_appeal: appeal).source_appeal_id + + Task.find_by(appeal_id: source_appeal_id, appeal_type: Appeal.name, type: JudgeDecisionReviewTask.name) + &.assigned_to&.css_id + end + + def self.legacy_original_deciding_judge(appeal) + staff = VACOLS::Staff.find_by(sattyid: appeal["prev_deciding_judge"]) + staff&.sdomainid || appeal["prev_deciding_judge"] + end end diff --git a/app/queries/hearing_request_distribution_query.rb b/app/queries/hearing_request_distribution_query.rb index 646836cf5f6..5e989de0b6a 100644 --- a/app/queries/hearing_request_distribution_query.rb +++ b/app/queries/hearing_request_distribution_query.rb @@ -97,13 +97,13 @@ def generate_ama_not_genpop_non_aod_hearing_query(base_relation) base_relation .most_recent_hearings .tied_to_distribution_judge(judge) - .ama_non_aod_hearing_appeals + .ama_non_aod_appeals .affinitized_ama_affinity_cases(CaseDistributionLever.ama_hearing_case_affinity_days) elsif CaseDistributionLever.ama_hearing_case_affinity_days == Constants.ACD_LEVERS.infinite base_relation .most_recent_hearings .tied_to_distribution_judge(judge) - .ama_non_aod_hearing_appeals + .ama_non_aod_appeals elsif CaseDistributionLever.ama_hearing_case_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings @@ -120,13 +120,13 @@ def generate_ama_not_genpop_aod_hearing_query(base_relation) base_relation .most_recent_hearings .tied_to_distribution_judge(judge) - .ama_aod_hearing_appeals + .ama_aod_appeals .affinitized_ama_affinity_cases(CaseDistributionLever.ama_hearing_case_aod_affinity_days) elsif CaseDistributionLever.ama_hearing_case_aod_affinity_days == Constants.ACD_LEVERS.infinite base_relation .most_recent_hearings .tied_to_distribution_judge(judge) - .ama_aod_hearing_appeals + .ama_aod_appeals elsif CaseDistributionLever.ama_hearing_case_aod_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings @@ -143,7 +143,7 @@ def generate_ama_only_genpop_non_aod_hearing_query(base_relation) base_relation .most_recent_hearings .with_appeal_affinities - .ama_non_aod_hearing_appeals + .ama_non_aod_appeals .expired_ama_affinity_cases(CaseDistributionLever.ama_hearing_case_affinity_days) elsif CaseDistributionLever.ama_hearing_case_affinity_days == Constants.ACD_LEVERS.infinite base_relation @@ -155,7 +155,7 @@ def generate_ama_only_genpop_non_aod_hearing_query(base_relation) .most_recent_hearings .with_appeal_affinities .with_held_hearings - .ama_non_aod_hearing_appeals + .ama_non_aod_appeals end query @@ -167,7 +167,7 @@ def generate_ama_only_genpop_aod_hearing_query(base_relation) base_relation .most_recent_hearings .with_appeal_affinities - .ama_aod_hearing_appeals + .ama_aod_appeals .expired_ama_affinity_cases(CaseDistributionLever.ama_hearing_case_aod_affinity_days) elsif CaseDistributionLever.ama_hearing_case_aod_affinity_days == Constants.ACD_LEVERS.infinite base_relation @@ -179,7 +179,7 @@ def generate_ama_only_genpop_aod_hearing_query(base_relation) .most_recent_hearings .with_appeal_affinities .with_held_hearings - .ama_aod_hearing_appeals + .ama_aod_appeals end query diff --git a/db/seeds/case_distribution_levers.rb b/db/seeds/case_distribution_levers.rb index c60dec34694..ea7c9132866 100644 --- a/db/seeds/case_distribution_levers.rb +++ b/db/seeds/case_distribution_levers.rb @@ -304,7 +304,7 @@ def levers text: "Omit variable from distribution rules" } ], - is_disabled_in_ui: true, + is_disabled_in_ui: false, min_value: 0, max_value: 999, algorithms_used: [Constants.ACD_LEVERS.algorithms.docket, Constants.ACD_LEVERS.algorithms.proportion], @@ -338,7 +338,7 @@ def levers text: "Omit variable from distribution rules" } ], - is_disabled_in_ui: true, + is_disabled_in_ui: false, algorithms_used: [Constants.ACD_LEVERS.algorithms.proportion], lever_group: Constants.ACD_LEVERS.lever_groups.affinity, lever_group_order: 3003 diff --git a/db/seeds/cavc_affinity_levers_test_data.rb b/db/seeds/cavc_affinity_levers_test_data.rb new file mode 100644 index 00000000000..f7b838e5481 --- /dev/null +++ b/db/seeds/cavc_affinity_levers_test_data.rb @@ -0,0 +1,933 @@ +# frozen_string_literal: true + +module Seeds + class CavcAffinityLeversTestData < Base + + def initialize + RequestStore[:current_user] = User.system_user + initialize_bvagsporer_file_number_and_participant_id + initialize_bvaeemard_file_number_and_participant_id + initialize_bvabdaniel_file_number_and_participant_id + initialize_bvadcremin_file_number_and_participant_id + initialize_bvaoschowalt_file_number_and_participant_id + initialize_bvaawakefield_file_number_and_participant_id + initialize_activejudgeteam_file_number_and_participant_id + initialize_bvacgislason1_file_number_and_participant_id + initialize_inactivejudge_file_number_and_participant_id + initialize_inactivecfjudge_file_number_and_participant_id + initialize_inactivejudge101_file_number_and_participant_id + initialize_bvaabode_file_number_and_participant_id + initialize_bvakkeeling_file_number_and_participant_id + initialize_bvaaabshire_file_number_and_participant_id + initialize_veteran_file_number_and_participant_id + end + + def seed! + create_cavc_affinity_days_data + create_cavc_aod_affinity_days_data + create_legacy_cavc_affinity_cases + create_legacy_cavc_aod_affinity_cases + update_ineligible_users + end + + def find_veteran(file_number) + Veteran.find_by(file_number: format("%09d", n: file_number + 1)) + end + + def initialize_bvagsporer_file_number_and_participant_id + @bvagsporer_file_number ||= 400_000_000 + @bvagsporer_participant_id ||= 420_000_000 + + while find_veteran(@bvagsporer_file_number) + @bvagsporer_file_number += 2000 + @bvagsporer_participant_id += 2000 + end + end + + def initialize_bvaeemard_file_number_and_participant_id + @bvaeemard_file_number ||= 401_000_000 + @bvaeemard_participant_id ||= 421_000_000 + + while find_veteran(@bvaeemard_file_number) + @bvaeemard_file_number += 2000 + @bvaeemard_participant_id += 2000 + end + end + + def initialize_bvabdaniel_file_number_and_participant_id + @bvabdaniel_file_number ||= 402_000_000 + @bvabdaniel_participant_id ||= 422_000_000 + + while find_veteran(@bvabdaniel_file_number) + @bvabdaniel_file_number += 2000 + @bvabdaniel_participant_id += 2000 + end + end + + def initialize_bvadcremin_file_number_and_participant_id + @bvadcremin_file_number ||= 403_000_000 + @bvadcremin_participant_id ||= 423_000_000 + + while find_veteran(@bvadcremin_file_number) + @bvadcremin_file_number += 2000 + @bvadcremin_participant_id += 2000 + end + end + + def initialize_bvaoschowalt_file_number_and_participant_id + @bvaoschowalt_file_number ||= 404_000_000 + @bvaoschowalt_participant_id ||= 424_000_000 + while find_veteran(@bvaoschowalt_file_number) + @bvaoschowalt_file_number += 2000 + @bvaoschowalt_participant_id += 2000 + end + end + + def initialize_bvaawakefield_file_number_and_participant_id + @bvaawakefield_file_number ||= 500_000_000 + @bvaawakefield_participant_id ||= 425_000_000 + + while find_veteran(@bvaawakefield_file_number) + @bvaawakefield_file_number += 2000 + @bvaawakefield_participant_id += 2000 + end + end + + def initialize_activejudgeteam_file_number_and_participant_id + @activejudgeteam_file_number ||= 501_000_000 + @activejudgeteam_participant_id ||= 426_000_000 + + while find_veteran(@activejudgeteam_file_number) + @activejudgeteam_file_number += 2000 + @activejudgeteam_participant_id += 2000 + end + end + + def initialize_bvacgislason1_file_number_and_participant_id + @bvacgislason1_file_number ||= 502_000_000 + @bvacgislason1_participant_id ||= 427_000_000 + + while find_veteran(@bvacgislason1_file_number) + @bvacgislason1_file_number += 2000 + @bvacgislason1_participant_id += 2000 + end + end + + def initialize_inactivejudge_file_number_and_participant_id + @inactivejudge_file_number ||= 600_000_000 + @inactivejudge_participant_id ||= 428_000_000 + + while find_veteran(@inactivejudge_file_number) + @inactivejudge_file_number += 2000 + @inactivejudge_participant_id += 2000 + end + end + + def initialize_inactivecfjudge_file_number_and_participant_id + @inactivecfjudge_file_number ||= 601_000_000 + @inactivecfjudge_participant_id ||= 429_000_000 + while find_veteran(@inactivecfjudge_file_number) + @inactivecfjudge_file_number += 2000 + @inactivecfjudge_participant_id += 2000 + end + end + + def initialize_inactivejudge101_file_number_and_participant_id + @inactivejudge101_file_number ||= 602_000_000 + @inactivejudge101_participant_id ||= 430_000_000 + + while find_veteran(@inactivejudge101_file_number) + @inactivejudge101_file_number += 2000 + @inactivejudge101_participant_id += 2000 + end + end + + def initialize_bvaabode_file_number_and_participant_id + @bvaabode_file_number ||= 603_000_000 + @bvaabode_participant_id ||= 431_000_000 + + while find_veteran(@bvaabode_file_number) + @bvaabode_file_number += 2000 + @bvaabode_participant_id += 2000 + end + end + + def initialize_bvakkeeling_file_number_and_participant_id + @bvakkeeling_file_number ||= 604_000_000 + @bvakkeeling_participant_id ||= 432_000_000 + + while find_veteran(@bvakkeeling_file_number) + @bvakkeeling_file_number += 2000 + @bvakkeeling_participant_id += 2000 + end + end + + def initialize_bvaaabshire_file_number_and_participant_id + @bvaaabshire_file_number ||= 605_000_000 + @bvaaabshire_participant_id ||= 433_000_000 + + while find_veteran(@bvaaabshire_file_number) + @bvaaabshire_file_number += 2000 + @bvaaabshire_participant_id += 2000 + end + end + + def initialize_veteran_file_number_and_participant_id + @veteran_file_number ||= 700_000_000 + @veteran_participant_id ||= 434_000_000 + + while find_veteran(@veteran_file_number) + @veteran_file_number += 2000 + @veteran_participant_id += 2000 + end + end + + def create_veteran(options = {}) + params = { + file_number: format("%09d", n: options[:file_number]), + participant_id: format("%09d", n: options[:participant_id]) + } + + if options[:last_name].nil? + options[:last_name] = "Smith#{Faker::Name.last_name.downcase.tr('\'', '')}" + end + create(:veteran, params.merge(options)) + end + + def find_or_create_active_judge(css_id, full_name) + user = User.find_by_css_id(css_id) + + if user && !user.judge_in_vacols? + create(:staff, :judge_role, slogid: user.css_id, user: user) + elsif !user + user = create(:user, :judge, :with_vacols_judge_record, css_id: css_id, full_name: full_name) + end + + user + end + + def find_or_create_attorney(css_id, full_name) + User.find_by_css_id(css_id) || + create(:user, :with_vacols_attorney_record, css_id: css_id, full_name: full_name) + end + + def judge_bvagsporer + @judge_bvagsporer ||= find_or_create_active_judge("BVAGSPORER", "Gilbert P Sporer") + end + + def judge_bvaeemard + @judge_bvaeemard ||= find_or_create_active_judge("BVAEEMARD", "Evangeline Y Emard") + end + + def judge_bvabdaniel + @judge_bvabdaniel ||= find_or_create_active_judge("BVABDANIEL", "Bridgette P Daniel") + end + + def judge_bvadcremin + @judge_bvadcremin ||= find_or_create_active_judge("BVADCREMIN", "Daija K Cremin") + end + + def judge_bvaoschowalt + @judge_bvaoschowalt ||= find_or_create_active_judge("BVAOSCHOWALT", "Ophelia L Schowalter") + end + + def judge_bvaawakefield + @judge_bvaawakefield ||= + (judge = find_or_create_active_judge("BVAAWAKEFIELD", "Apurva Judge_CaseAtDispatch Wakefield") + JudgeTeam.for_judge(judge).update!(exclude_appeals_from_affinity: true) + judge) + end + + def judge_activejudgeteam + @judge_activejudgeteam ||= + (judge = find_or_create_active_judge("ACTIVEJUDGETEAM", "Judge WithJudgeTeam Active") + JudgeTeam.for_judge(judge).update!(exclude_appeals_from_affinity: true) + judge) + end + + def judge_bvacgislason1 + @judge_bvacgislason1 ||= + (judge = find_or_create_active_judge("BVACGISLASON1", "Chester F Gislason") + JudgeTeam.for_judge(judge).update!(exclude_appeals_from_affinity: true) + judge) + end + + def judge_inactivejudge + @judge_inactivejudge ||= find_or_create_active_judge("INACTIVEJUDGE", "Inactive InVacols Judge") + end + + def judge_inactivecfjudge + @judge_inactivecfjudge ||= find_or_create_active_judge("INACTIVECFJUDGE", "InactiveCF InactiveInCF Judge") + end + + def judge_inactivejudge101 + @judge_inactivejudge101 ||= find_or_create_active_judge("INACTIVEJUDGE101", "Inactive101 InactiveAt101 Judge") + end + + def judge_bvaabode + @judge_bvaabode ||= find_or_create_active_judge("BVAABODE", "Anastacio H Bode") + end + + def judge_bvakkeeling + @judge_bvakkeeling ||= find_or_create_active_judge("BVAKKEELING", "Keith Judge_CaseToAssign_NoTeam Keeling") + end + + def judge_bvaaabshire + @judge_bvaaabshire ||= find_or_create_active_judge("BVAAABSHIRE", "Aaron Judge_HearingsAndCases Abshire") + end + + def attorney + @attorney ||= find_or_create_attorney("CAVCATNY", "CAVC Attorney") + end + + def update_ineligible_users + ineligible_users = ["INACTIVEJUDGE", "INACTIVECFJUDGE", "INACTIVEJUDGE101", + "BVAABODE", "BVAKKEELING", "BVAAABSHIRE"] + + ineligible_users.each { |sdomainid| + vacols_record = VACOLS::Staff.find_by_sdomainid(sdomainid) + vacols_record.update!(sactive: "I") if vacols_record.sactive == "A" + } + end + + def create_veteran_for_bvagsporer_judge(last_name = nil) + @bvagsporer_file_number += 1 + @bvagsporer_participant_id += 1 + create_veteran( + file_number: @bvagsporer_file_number, + participant_id: @bvagsporer_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvaeemard_judge(last_name = nil) + @bvaeemard_file_number += 1 + @bvaeemard_participant_id += 1 + create_veteran( + file_number: @bvaeemard_file_number, + participant_id: @bvaeemard_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvabdaniel_judge(last_name = nil) + @bvabdaniel_file_number += 1 + @bvabdaniel_participant_id += 1 + create_veteran( + file_number: @bvabdaniel_file_number, + participant_id: @bvabdaniel_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvadcremin_judge(last_name = nil) + @bvadcremin_file_number += 1 + @bvadcremin_participant_id += 1 + create_veteran( + file_number: @bvadcremin_file_number, + participant_id: @bvadcremin_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvaoschowalt_judge(last_name = nil) + @bvaoschowalt_file_number += 1 + @bvaoschowalt_participant_id += 1 + create_veteran( + file_number: @bvaoschowalt_file_number, + participant_id: @bvaoschowalt_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvaawakefield_judge(last_name = nil) + @bvaawakefield_file_number += 1 + @bvaawakefield_participant_id += 1 + create_veteran( + file_number: @bvaawakefield_file_number, + participant_id: @bvaawakefield_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_activejudgeteam_judge(last_name = nil) + @activejudgeteam_file_number += 1 + @activejudgeteam_participant_id += 1 + create_veteran( + file_number: @activejudgeteam_file_number, + participant_id: @activejudgeteam_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvacgislason1_judge(last_name = nil) + @bvacgislason1_file_number += 1 + @bvacgislason1_participant_id += 1 + create_veteran( + file_number: @bvacgislason1_file_number, + participant_id: @bvacgislason1_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_inactivejudge_judge(last_name = nil) + @inactivejudge_file_number += 1 + @inactivejudge_participant_id += 1 + create_veteran( + file_number: @inactivejudge_file_number, + participant_id: @inactivejudge_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_inactivecfjudge_judge(last_name = nil) + @inactivecfjudge_file_number += 1 + @inactivecfjudge_participant_id += 1 + create_veteran( + file_number: @inactivecfjudge_file_number, + participant_id: @inactivecfjudge_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_inactivejudge101_judge(last_name = nil) + @inactivejudge101_file_number += 1 + @inactivejudge101_participant_id += 1 + create_veteran( + file_number: @inactivejudge101_file_number, + participant_id: @inactivejudge101_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvaabode_judge(last_name = nil) + @bvaabode_file_number += 1 + @bvaabode_participant_id += 1 + create_veteran( + file_number: @bvaabode_file_number, + participant_id: @bvaabode_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvakkeeling_judge(last_name = nil) + @bvakkeeling_file_number += 1 + @bvakkeeling_participant_id += 1 + create_veteran( + file_number: @bvakkeeling_file_number, + participant_id: @bvakkeeling_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_bvaaabshire_judge(last_name = nil) + @bvaaabshire_file_number += 1 + @bvaaabshire_participant_id += 1 + create_veteran( + file_number: @bvaaabshire_file_number, + participant_id: @bvaaabshire_participant_id, + last_name: last_name + ) + end + + def create_veteran_for_genpop(last_name = nil) + @veteran_file_number += 1 + @veteran_participant_id += 1 + create_veteran( + file_number: @veteran_file_number, + participant_id: @veteran_participant_id, + last_name: last_name + ) + end + + def create_cavc_affinity_days_data + create_legacy_appeals_without_hearing_held + create_legacy_appeals_with_hearing_and_excluded_or_ineligible_judge + create_ama_cavc_appeals_with_no_hearing_held + create_legacy_appeals_with_null_judge_value + create_ama_aod_appeals_with_null_judge_value + create_ama_cavc_appeals_with_null_judge_value + end + + def create_cavc_aod_affinity_days_data + create_ama_cavc_appeals + create_legacy_aod_appeals_with_hearing_and_excluded_or_ineligible_judge + ama_cavc_aod_appeals_with_no_hearing_held + create_legacy_aod_appeals_with_null_judge_value + create_ama_aod_appeals_with_null_judge_value + create_ama_cavc_aod_appeals_with_null_judge_value + end + + def create_legacy_cavc_affinity_cases + create_cases_for_cavc_affinty_days_lever + create_cases_for_cavc_affinty_days_lever_excluded_judge + create_cases_for_cavc_affinity_days_lever_ineligible_judge + end + + def create_legacy_cavc_aod_affinity_cases + create_cases_for_cavc_aod_affinty_days_lever + create_cases_for_cavc_aod_affinty_days_lever_excluded_judge + create_cases_for_cavc_aod_affinity_days_lever_ineligible_judge + end + + def create_legacy_appeals_without_hearing_held + 2.times do + create_legacy_appeal_without_hearing_held(judge_bvagsporer, create_veteran_for_bvagsporer_judge()) + end + create_legacy_appeal_without_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge()) + create_legacy_appeal_without_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge()) + create_legacy_appeal_without_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge()) + create_legacy_appeal_without_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge()) + create_legacy_appeal_without_hearing_held(judge_inactivejudge, create_veteran_for_inactivejudge_judge()) + create_legacy_appeal_without_hearing_held(judge_inactivecfjudge, create_veteran_for_inactivecfjudge_judge()) + create_legacy_appeal_without_hearing_held(judge_inactivejudge101, create_veteran_for_inactivejudge101_judge()) + create_legacy_appeal_without_hearing_held(judge_bvaabode, create_veteran_for_bvaabode_judge()) + create_legacy_appeal_without_hearing_held(judge_bvakkeeling, create_veteran_for_bvakkeeling_judge()) + create_legacy_appeal_without_hearing_held(judge_bvaaabshire, create_veteran_for_bvaaabshire_judge()) + end + + #{ TIED TO ?? } + def create_legacy_appeals_with_hearing_and_excluded_or_ineligible_judge + 2.times do + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaawakefield, create_veteran_for_bvaawakefield_judge("TiedToWakefield")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvacgislason1, create_veteran_for_bvacgislason1_judge("TiedToGislason")) + end + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_activejudgeteam, create_veteran_for_activejudgeteam_judge("TiedToActiveJudgeTeam")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivejudge, create_veteran_for_inactivejudge_judge("TiedToInactiveJudge")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivecfjudge, create_veteran_for_inactivecfjudge_judge("TiedToInactiveCFJudge")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivejudge101, create_veteran_for_inactivejudge101_judge("TiedToInactiveJudge101")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaabode, create_veteran_for_bvaabode_judge("TiedToBode")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvakkeeling, create_veteran_for_bvakkeeling_judge("TiedToKeeling")) + create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaaabshire, create_veteran_for_bvaaabshire_judge("TiedToAbshire")) + end + + def create_legacy_aod_appeals_with_hearing_and_excluded_or_ineligible_judge + 2.times do + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaawakefield, create_veteran_for_bvaawakefield_judge("TiedToWakefield")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvacgislason1, create_veteran_for_bvacgislason1_judge("TiedToGislason")) + end + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_activejudgeteam, create_veteran_for_activejudgeteam_judge("TiedToActiveJudgeTeam")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivejudge, create_veteran_for_inactivejudge_judge("TiedToInactiveJudge")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivecfjudge, create_veteran_for_inactivecfjudge_judge("TiedToInactiveCFJudge")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_inactivejudge101, create_veteran_for_inactivejudge101_judge("TiedToInactiveJudge101")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaabode, create_veteran_for_bvaabode_judge("TiedToBode")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvakkeeling, create_veteran_for_bvakkeeling_judge("TiedToKeeling")) + create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge_bvaaabshire, create_veteran_for_bvaaabshire_judge("TiedToAbshire")) + end + + def create_ama_cavc_appeals_with_no_hearing_held + create_ama_cavc_appeal_with_no_hearing_held(judge_bvagsporer, create_veteran_for_bvagsporer_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge(),14.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvagsporer, create_veteran_for_bvagsporer_judge(),30.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge(),30.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge(),30.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge(),30.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge(),30.days.ago) + create_ama_cavc_appeal_with_no_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge(),30.days.ago) + end + + #{ TIED TO ??} + def create_ama_cavc_appeals + 2.times do + create_ama_cavc_appeal(judge_bvaeemard, create_veteran_for_bvaeemard_judge("TiedToEmard")) + end + create_ama_cavc_appeal(judge_bvagsporer, create_veteran_for_bvagsporer_judge("TiedToSporer")) + create_ama_cavc_appeal(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge("TiedToDaniel")) + create_ama_cavc_appeal(judge_bvadcremin, create_veteran_for_bvadcremin_judge("TiedToCremin")) + create_ama_cavc_appeal(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge("TiedToSchowalt")) + create_ama_cavc_appeal(judge_inactivejudge, create_veteran_for_inactivejudge_judge("TiedToInactiveJudge")) + create_ama_cavc_appeal(judge_inactivecfjudge, create_veteran_for_inactivecfjudge_judge("TiedToInactiveCFJudge")) + create_ama_cavc_appeal(judge_inactivejudge101, create_veteran_for_inactivejudge101_judge("TiedToInactiveJudge101")) + create_ama_cavc_appeal(judge_bvaabode, create_veteran_for_bvaabode_judge("TiedToBode")) + create_ama_cavc_appeal(judge_bvakkeeling, create_veteran_for_bvakkeeling_judge("TiedToKeeling")) + create_ama_cavc_appeal(judge_bvaaabshire, create_veteran_for_bvaaabshire_judge("TiedToAbshire")) + end + + def ama_cavc_aod_appeals_with_no_hearing_held + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvagsporer, create_veteran_for_bvagsporer_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge(),7.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvagsporer, create_veteran_for_bvagsporer_judge(),21.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvaeemard, create_veteran_for_bvaeemard_judge(),21.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvabdaniel, create_veteran_for_bvabdaniel_judge(),21.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvadcremin, create_veteran_for_bvadcremin_judge(),21.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge(),21.days.ago) + ama_cavc_aod_appeal_with_no_hearing_held(judge_bvaoschowalt, create_veteran_for_bvaoschowalt_judge(),21.days.ago) + end + + def create_legacy_appeals_with_null_judge_value + 3.times do + create_legacy_appeal_with_null_judge_value(create_veteran_for_genpop()) + end + end + + def create_legacy_aod_appeals_with_null_judge_value + 3.times do + create_legacy_aod_appeal_with_null_judge_value(create_veteran_for_genpop()) + end + end + + def create_ama_aod_appeals_with_null_judge_value + 3.times do + create_ama_aod_appeal_with_null_judge_value(create_veteran_for_genpop()) + end + end + + def create_ama_cavc_appeals_with_null_judge_value + 3.times do + create_ama_cavc_appeal_with_null_judge_value(create_veteran_for_genpop()) + end + end + + def create_ama_cavc_aod_appeals_with_null_judge_value + 3.times do + create_ama_cavc_aod_appeal_with_null_judge_value(create_veteran_for_genpop()) + end + end + + def create_legacy_appeal_without_hearing_held(judge, veteran) + create(:legacy_cavc_appeal, cavc: false, tied_to: false, affinity_start_date: Time.zone.now, bfcorlid: "#{veteran.file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + end + + def create_legacy_appeal_with_hearing_and_excluded_or_ineligible_judge(judge, veteran) + create(:legacy_cavc_appeal, cavc: false, affinity_start_date: Time.zone.now, bfcorlid: "#{veteran.file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + end + + def create_legacy_aod_appeal_with_hearing_and_excluded_or_ineligible_judge(judge, veteran) + create(:legacy_cavc_appeal, cavc: false, aod:true, affinity_start_date: Time.zone.now, bfcorlid: "#{veteran.file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + end + + def create_ama_cavc_appeal_with_no_hearing_held(judge, veteran, days) + Timecop.travel(days + 1.day) + ama_cavc_appeal= create( + :appeal, + :dispatched, + veteran: veteran, + associated_judge: judge, + associated_attorney: attorney + ) + Timecop.return + Timecop.travel(days) + remand = create(:cavc_remand, source_appeal: ama_cavc_appeal) + remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! + create(:appeal_affinity, appeal: remand.remand_appeal) + Timecop.return + end + + def create_legacy_appeal_with_null_judge_value(veteran) + create( + :legacy_appeal, + :with_veteran, + vacols_case: + create( + :case, + :ready_for_distribution, + :type_original, + :with_appeal_affinity, + bfcorlid: "#{veteran.file_number}S" + ) + ) + end + + def create_legacy_aod_appeal_with_null_judge_value(veteran) + create( + :legacy_appeal, + :with_veteran, + vacols_case: + create( + :case, + :aod, + :ready_for_distribution, + :type_original, + :with_appeal_affinity, + bfcorlid: "#{veteran.file_number}S" + ) + ) + end + + def create_ama_aod_appeal_with_null_judge_value(veteran) + create( + :appeal, + :advanced_on_docket_due_to_age, + :ready_for_distribution, + :with_appeal_affinity, + veteran: veteran + ) + end + + def create_ama_cavc_appeal_with_null_judge_value(veteran) + Timecop.travel(1.day.ago) + ama_cavc_appeal= create( + :appeal, + :cavc_ready_for_distribution, + veteran: veteran, + associated_attorney: attorney + ) + Timecop.return + remand = create(:cavc_remand, source_appeal: ama_cavc_appeal) + remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! + create(:appeal_affinity, appeal: remand.remand_appeal) + end + + def create_ama_cavc_aod_appeal_with_null_judge_value(veteran) + Timecop.travel(1.day.ago) + ama_cavc_aod_appeal= create( + :appeal, + :advanced_on_docket_due_to_age, + :cavc_ready_for_distribution, + veteran: veteran + ) + Timecop.return + remand = create(:cavc_remand, source_appeal: ama_cavc_aod_appeal) + remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! + create(:appeal_affinity, appeal: remand.remand_appeal) + end + + def create_ama_cavc_appeal(judge, veteran) + # Go back to when we want the original appeal to have been decided + Timecop.travel(4.years.ago) + + # Create a decided appeal. all tasks are marked complete at the same time which won't affect distribution + source = create(:appeal, :dispatched, :hearing_docket, associated_judge: judge, veteran: veteran) + + Timecop.travel(1.year.from_now) + remand = create(:cavc_remand, source_appeal: source).remand_appeal + Timecop.return + + # Travel to 9 mo. ago and then in smaller increments for a more "realistic" looking task tree + Timecop.travel(9.months.ago) + remand.tasks.where(type: SendCavcRemandProcessedLetterTask.name).map(&:completed!) + create(:appeal_affinity, appeal: remand) + + Timecop.travel(1.month.from_now) + # Call the creator class which will handle the task manipulation normally done by a distribution + jat = JudgeAssignTaskCreator.new(appeal: remand, judge: judge, assigned_by_id: judge.id).call + # Create and complete a ScheduleHearingColocatedTask, which will create a new DistributionTask and + # HearingTask subtree to mimic how this would happen in a higher environment + create(:colocated_task, :schedule_hearing, parent: jat, assigned_by: judge).completed! + + Timecop.travel(1.month.from_now) + create(:hearing, :held, appeal: remand, judge: judge, adding_user: User.system_user) + + Timecop.travel(3.months.from_now) + # Completes the remaining open HearingTask descendant tasks to make appeal ready to distribute + remand.tasks.where(type: AssignHearingDispositionTask.name).flat_map(&:children).map(&:completed!) + Timecop.return + + # When a DistributionTask goes to assigned it clears the affinity start date, so restore that at the right date + remand.appeal_affinity.update!(affinity_start_date: Time.zone.now) + end + + def ama_cavc_aod_appeal_with_no_hearing_held(judge, veteran, days) + Timecop.travel(days + 1.day) + ama_cavc_aod_appeal= create( + :appeal, + :advanced_on_docket_due_to_age, + :dispatched, + veteran: veteran, + associated_judge: judge, + associated_attorney: attorney + ) + Timecop.return + Timecop.travel(days) + remand = create(:cavc_remand, source_appeal: ama_cavc_aod_appeal) + remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! + create(:appeal_affinity, appeal: remand.remand_appeal) + Timecop.return + end + + def create_cases_for_cavc_affinty_days_lever + # cavc affinity cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: nil) + + # no hearing held, no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false).update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false).update!(bfmemid: nil) + end + + def create_cases_for_cavc_affinty_days_lever_excluded_judge + # excluded judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + end + + def create_cases_for_cavc_affinity_days_lever_ineligible_judge + # ineligible judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), + affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id)).update!(bfmemid: nil) + end + + def create_cases_for_cavc_aod_affinty_days_lever + # cavc aod affinity cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvagsporer_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id).sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvabdaniel_judge("TiedToDaniel").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaeemard_judge("TiedToEmard").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvabdaniel.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: nil) + # no hearing held, no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvagsporer.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaeemard.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + .update!(bfmemid: nil) + end + + def create_cases_for_cavc_aod_affinty_days_lever_excluded_judge + # excluded judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id).sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_bvaawakefield_judge("TiedToWakefield").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaawakefield.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + end + + def create_cases_for_cavc_aod_affinity_days_lever_ineligible_judge + # ineligible judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_bvaoschowalt.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + .update!(bfmemid: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id).sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_inactivejudge_judge("TiedToInactiveJudge").file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true, appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_genpop().file_number}S", judge: VACOLS::Staff.find_by(sdomainid: judge_inactivejudge.css_id), attorney: VACOLS::Staff.find_by(sdomainid: attorney.css_id), aod: true) + .update!(bfmemid: nil) + end + end +end diff --git a/db/seeds/legacy_affinity_cases.rb b/db/seeds/legacy_affinity_cases.rb new file mode 100644 index 00000000000..cf33e630a26 --- /dev/null +++ b/db/seeds/legacy_affinity_cases.rb @@ -0,0 +1,310 @@ +# frozen_string_literal: true + +# This seed creates ~100 appeals which have an affinity to a judge based case distribution algorithm levers, +# and ~100 appeals which are similar but fall just outside of the affinity day levers and will be distributed +# to any judge. Used primarily in testing APPEALS-36998 and other ACD feature work +module Seeds + class LegacyAffinityCases < Base + def initialize + RequestStore[:current_user] = User.system_user + initial_file_number_and_participant_id + end + + def seed! + create_cavc_affinity_cases + create_cavc_aod_affinity_cases + end + + private + + def initial_file_number_and_participant_id + @file_number ||= 520_000_000 + @participant_id ||= 920_000_000 + @tied_to_file_number ||= 550_000_000 + @tied_to_participant_id ||= 950_000_000 + # n is (@file_number + 1) because @file_number is incremented before using it in factories in calling methods + while Veteran.find_by(file_number: format("%09d", n: @file_number + 1)) + @file_number += 1000 + @participant_id += 1000 + end + + while Veteran.find_by(file_number: format("%09d", n: @tied_to_file_number + 1)) + @tied_to_file_number += 1000 + @tied_to_participant_id += 1000 + end + end + + def create_veteran_for_tied_to + @tied_to_file_number += 1 + @tied_to_participant_id += 1 + + Veteran.find_by_participant_id(@tied_to_participant_id) || create( + :veteran, + file_number: format("%09d", n: @tied_to_file_number), + participant_id: format("%09d", n: @tied_to_participant_id) + ) + end + + def create_veteran + @file_number += 1 + @participant_id += 1 + + Veteran.find_by_participant_id(@participant_id) || create( + :veteran, + file_number: format("%09d", n: @file_number), + participant_id: format("%09d", n: @participant_id) + ) + end + + def create_cavc_affinity_cases + create_cases_for_cavc_affinty_days_lever + create_cases_for_cavc_affinty_days_lever_excluded_judge + create_cases_for_cavc_affinity_days_lever_ineligible_judge + end + + def create_cavc_aod_affinity_cases + create_cases_for_cavc_aod_affinty_days_lever + create_cases_for_cavc_aod_affinty_days_lever_excluded_judge + create_cases_for_cavc_aod_affinity_days_lever_ineligible_judge + end + + def affinity_judge + @affinity_judge ||= VACOLS::Staff.find_by_sdomainid("BVAGSPORER") + end + + def tied_to_judge + @tied_to_judge ||= VACOLS::Staff.find_by_sdomainid("BVABDANIEL") + end + + def affinity_and_tied_to_judge + @affinity_and_tied_to_judge ||= VACOLS::Staff.find_by_sdomainid("BVAEEMARD") + end + + def excluded_judge + @excluded_judge ||= find_or_create_active_excluded_judge("EXCLUDED_JUDGE", "Excluded FromAffinity Judge") + end + + def ineligible_judge + @ineligible_judge ||= find_or_create_ineligible_judge("INELIGIBLE_JUDGE", "Ineligible Vacols Judge") + end + + def attorney + @attorney ||= find_or_create_attorney("AFFINITY_ATTORNEY", "Affinity Cases Attorney") + end + + def other_judge + @other_judge ||= find_or_create_other_judge("OTHER_JUDGE", "Other Affinity Judge") + end + + def find_or_create_ineligible_judge(sdomainid, full_name) + VACOLS::Staff.find_by_sdomainid(sdomainid) || ( + user = create(:user, :judge, :with_inactive_vacols_judge_record, css_id: sdomainid, full_name: full_name) + VACOLS::Staff.find_by_sdomainid(user.css_id)) + end + + def find_or_create_active_excluded_judge(sdomainid, full_name) + VACOLS::Staff.find_by_sdomainid(sdomainid) || ( + user = create(:user, :judge_with_appeals_excluded_from_affinity, + :with_vacols_judge_record, css_id: sdomainid, full_name: full_name) + VACOLS::Staff.find_by_sdomainid(user.css_id)) + end + + def find_or_create_attorney(sdomainid, full_name) + VACOLS::Staff.find_by_sdomainid(sdomainid) || ( + user = create(:user, :with_vacols_attorney_record, css_id: sdomainid, full_name: full_name) + VACOLS::Staff.find_by_sdomainid(user.css_id)) + end + + def find_or_create_other_judge(sdomainid, full_name) + VACOLS::Staff.find_by_sdomainid(sdomainid) || ( + user = create(:user, :judge, :with_vacols_judge_record, css_id: sdomainid, full_name: full_name) + VACOLS::Staff.find_by_sdomainid(user.css_id)) + end + + def create_cases_for_cavc_affinty_days_lever + # cavc affinity cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney) + .update!(bfmemid: affinity_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + .update!(bfmemid: affinity_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, appeal_affinity: false) + .update!(bfmemid: affinity_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney) + .update!(bfmemid: affinity_and_tied_to_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + .update!(bfmemid: affinity_and_tied_to_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, appeal_affinity: false) + .update!(bfmemid: affinity_and_tied_to_judge.sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, appeal_affinity: false) + + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: tied_to_judge, attorney: attorney) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney) + .update!(bfmemid: nil) + + # no hearing held, no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, + tied_to: false).update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, + tied_to: false).update!(bfmemid: nil) + end + + def create_cases_for_cavc_affinty_days_lever_excluded_judge + # excluded judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney) + .update!(bfmemid: excluded_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + .update!(bfmemid: excluded_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, appeal_affinity: false) + .update!(bfmemid: excluded_judge.sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney, appeal_affinity: false) + end + + def create_cases_for_cavc_affinity_days_lever_ineligible_judge + # ineligible judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney) + .update!(bfmemid: ineligible_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + .update!(bfmemid: ineligible_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, appeal_affinity: false) + .update!(bfmemid: ineligible_judge.sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney, appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney).update!(bfmemid: nil) + end + + def create_cases_for_cavc_aod_affinty_days_lever + # cavc aod affinity cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true).update!(bfmemid: affinity_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: affinity_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + .update!(bfmemid: affinity_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true).update!(bfmemid: affinity_and_tied_to_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: affinity_and_tied_to_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + .update!(bfmemid: affinity_and_tied_to_judge.sattyid) + + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney, aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: tied_to_judge, attorney: attorney, aod: true, appeal_affinity: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: tied_to_judge, attorney: attorney, aod: true) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true) + .update!(bfmemid: nil) + # no hearing held, no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_judge, attorney: attorney, aod: true, tied_to: false) + .update!(bfmemid: nil) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: affinity_and_tied_to_judge, attorney: attorney, aod: true, tied_to: false) + .update!(bfmemid: nil) + end + + def create_cases_for_cavc_aod_affinty_days_lever_excluded_judge + # excluded judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: excluded_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true) + .update!(bfmemid: excluded_judge.sattyid) + + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago).update!(bfmemid: excluded_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + .update!(bfmemid: excluded_judge.sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney, aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: excluded_judge, attorney: attorney, aod: true, appeal_affinity: false) + end + + def create_cases_for_cavc_aod_affinity_days_lever_ineligible_judge + # ineligible judge cases: + # no hearing held but has previous decision + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true, tied_to: false) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) + # hearing held with previous decision where judge is not the same + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true) + .update!(bfmemid: ineligible_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + .update!(bfmemid: ineligible_judge.sattyid) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + .update!(bfmemid: ineligible_judge.sattyid) + # hearing held with previous decision where judge is same (THIS IS TIED TO) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran_for_tied_to.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true, appeal_affinity: false) + # hearing held but no previous deciding judge + create(:legacy_cavc_appeal, bfcorlid: "#{create_veteran.file_number}S", judge: ineligible_judge, attorney: attorney, aod: true) + .update!(bfmemid: nil) + end + + end +end diff --git a/spec/controllers/case_distribution_levers_tests_controller.rb b/spec/controllers/case_distribution_levers_tests_controller.rb new file mode 100644 index 00000000000..a8dca5fe726 --- /dev/null +++ b/spec/controllers/case_distribution_levers_tests_controller.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +describe CaseDistributionLeversTestsController do + before do + Timecop.freeze(Time.utc(2024, 1, 1, 12, 0, 0)) + User.authenticate!(user: User.system_user) + end + + context "#appeals_ready_to_distribute" do + it "downloads a properly named CSV file" do + get :appeals_ready_to_distribute, format: :csv + + expect(response.headers["Content-Type"]).to eq("text/csv") + expect(response.headers["Content-Disposition"]).to include("appeals_ready_to_distribute_20240101-0700.csv") + end + end + + context "#appeals_distributed" do + it "downloads a properly named CSV file" do + get :appeals_distributed, format: :csv + + expect(response.headers["Content-Type"]).to eq("text/csv") + expect(response.headers["Content-Disposition"]).to include("distributed_appeals_20240101-0700.csv") + end + end +end diff --git a/spec/factories/distributed_case.rb b/spec/factories/distributed_case.rb index 333dd8dda53..4b0cb4dbacf 100644 --- a/spec/factories/distributed_case.rb +++ b/spec/factories/distributed_case.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -# This factory will create a DistributedCase with the required fields based on an appeal -# It is currently only compatible with AMA appeals FactoryBot.define do factory :distributed_case do case_id { appeal.uuid } @@ -18,5 +16,18 @@ transient do appeal { create(:appeal, :assigned_to_judge) } end + + factory :legacy_distributed_case do + case_id { appeal.bfkey } + distribution { create(:distribution, judge: create(:user, :judge, :with_vacols_judge_record)) } + docket { LegacyDocket.docket_type } + docket_index { rand(1..100) } + priority { nil } + ready_at { appeal.bfdloout } + sct_appeal { false } + task { nil } + genpop { false } + genpop_query { "any" } + end end end diff --git a/spec/factories/document.rb b/spec/factories/document.rb index 9998a19dbda..a077bfba00f 100644 --- a/spec/factories/document.rb +++ b/spec/factories/document.rb @@ -2,7 +2,7 @@ FactoryBot.define do factory :document do - sequence(:vbms_document_id, 10_000) # start with initial high value to reserve manual assignment range + sequence(:vbms_document_id, 10_000) { |n| "#{Time.zone.today.day}#{n}#{Time.zone.now.to_i.to_s.last(1)}" } type { "VA 8 Certification of Appeal" } end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index 003998d3e7d..bfb5ebe7d85 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -62,6 +62,11 @@ roles { ["Hearing Prep"] } end + trait :judge_with_appeals_excluded_from_affinity do + with_appeals_excluded_from_affinity_judge_team + roles { ["Hearing Prep"] } + end + trait :ama_only_judge do after(:create) do |judge| JudgeTeam.for_judge(judge)&.update(ama_only_push: true, ama_only_request: true) || @@ -109,6 +114,13 @@ end end + trait :with_appeals_excluded_from_affinity_judge_team do + after(:create) do |judge| + judge_team = JudgeTeam.for_judge(judge) || JudgeTeam.create_for_judge(judge) + judge_team.update!(exclude_appeals_from_affinity: true) + end + end + trait :with_vacols_attorney_record do after(:create) do |user| create(:staff, :attorney_role, user: user) diff --git a/spec/factories/vacols/case.rb b/spec/factories/vacols/case.rb index 52cfd37c019..e26209dca6b 100644 --- a/spec/factories/vacols/case.rb +++ b/spec/factories/vacols/case.rb @@ -14,13 +14,13 @@ bfcorkey { generate :vacols_correspondent_key } bfcorlid { "#{generate :veteran_file_number}S" } - association :correspondent, factory: :correspondent + correspondent { association :correspondent } transient do docket_number { "150000#{bfkey}" } end # folder.tinum is the docket_number - folder { association :folder, ticknum: bfkey, tinum: docket_number } + folder { association :folder, ticknum: bfkey, tinum: docket_number, titrnum: bfcorlid } bfregoff { "RO18" } @@ -196,6 +196,116 @@ end end end + + # You can change the judge, attorney, AOD status, and Appeal Affinity of your Legacy CAVC Appeal. + # The Appeal_Affinity is default but the AOD must be toggled on. Example: + # "FactoryBot.create(:legacy_cavc_appeal, judge: judge, aod: true, affinity_start_date: 2.weeks.ago)" + + factory :legacy_cavc_appeal do + transient do + judge { nil } + attorney { nil } + aod { false } + cavc { true } + appeal_affinity { true } + affinity_start_date { 1.month.ago } + tied_to { true } + end + + bfmpro { "HIS" } + bfddec { 1.day.ago } + bfac { "1" } + bfdc { "3" } + bfcurloc { "99" } + + after(:create) do |vacols_case, evaluator| + vacols_case.bfmemid = if evaluator.judge + existing_judge = VACOLS::Staff.find_by_sattyid(evaluator.judge.sattyid) + existing_judge.sattyid + else + new_judge = create(:staff, :judge_role, user: evaluator.judge) + new_judge.sattyid + end + + vacols_case.bfattid = if evaluator.attorney + existing_attorney = VACOLS::Staff.find_by_sattyid(evaluator.attorney.sattyid) + existing_attorney.sattyid + else + new_attorney = create(:staff, :attorney_role, user: evaluator.attorney) + new_attorney.sattyid + end + + vacols_case.case_issues.each do |case_issue| + case_issue.issdc = "3" + case_issue.save + end + + vacols_case.correspondent.update!(ssn: vacols_case.bfcorlid.chomp("S")) + vacols_case.save + + if Veteran.find_by_file_number_or_ssn(vacols_case.correspondent.ssn) + veteran = Veteran.find_by_file_number_or_ssn(vacols_case.correspondent.ssn) + vacols_case.correspondent.update!(snamef: veteran.first_name, snamel: veteran.last_name) + else + create( + :veteran, + first_name: vacols_case.correspondent.snamef, + last_name: vacols_case.correspondent.snamel, + name_suffix: vacols_case.correspondent.ssalut, + ssn: vacols_case.correspondent.ssn, + file_number: vacols_case.correspondent.ssn + ) + end + + if evaluator.tied_to + create( + :case_hearing, + :disposition_held, + folder_nr: vacols_case.bfkey, + hearing_date: 5.days.ago.to_date, + user: User.find_by_css_id(evaluator.judge.sdomainid) + ) + end + + params = { + bfdpdcn: vacols_case.bfddec, + bfac: "7", + bfcurloc: "81", + bfcorkey: vacols_case.bfcorkey, + bfcorlid: vacols_case.bfcorlid, + bfdnod: vacols_case.bfdnod, + bfdsoc: vacols_case.bfdsoc, + bfd19: vacols_case.bfd19, + bfmpro: "ACT", + correspondent: vacols_case.correspondent, + folder_number_equal: true, + original_case: vacols_case, + case_issues_equal: true, + original_case_issues: vacols_case.case_issues + } + + if !evaluator.cavc + params[:bfac] = "1" + end + + cavc_appeal = if evaluator.aod + create( + :case, + :aod, + params + ) + else + create( + :case, + params + ) + end + + if evaluator.appeal_affinity + create(:appeal_affinity, appeal: cavc_appeal, affinity_start_date: evaluator.affinity_start_date) + end + end + end end end end @@ -229,6 +339,22 @@ end end + trait :tied_to_previous_judge do + transient do + previous_tied_judge { nil } + end + + after(:create) do |vacols_case, evaluator| + create( + :case_hearing, + :disposition_held, + folder_nr: vacols_case.bfkey, + hearing_date: 5.days.ago.to_date, + user: evaluator.previous_tied_judge + ) + end + end + trait :type_original do bfac { "1" } end @@ -401,6 +527,38 @@ end end + transient do + folder_number_equal { false } + original_case { nil } + + after(:create) do |vacols_case, evaluator| + if evaluator.folder_number_equal + folder_json = evaluator.original_case.folder.to_json + folder_attributes = JSON.parse(folder_json) + folder_attributes.except!("bfkey", "ticknum", "tidrecv", "tidcls", "tiaduser", + "tiadtime", "tikeywrd", "tiread2", "tioctime", "tiocuser", + "tidktime", "tidkuser") + vacols_case.folder.assign_attributes(folder_attributes) + vacols_case.folder.save(validate: false) + end + end + end + + transient do + case_issues_equal { false } + original_case_issues { [] } + + after(:create) do |vacols_case, evaluator| + if evaluator.case_issues_equal + evaluator.original_case_issues.each do |case_issue, i| + vacols_case.case_issues[i] = case_issue.attributes.except("issaduser", "issadtime", "issmduser", + "issmdtime", "issdc", "issdcls") + vacols_case.case_issues[i].save + end + end + end + end + transient do staff { nil } end diff --git a/spec/feature/case_distribution_levers/admin_ui_spec.rb b/spec/feature/case_distribution_levers/admin_ui_spec.rb index a52390941d7..cb7a08c526d 100644 --- a/spec/feature/case_distribution_levers/admin_ui_spec.rb +++ b/spec/feature/case_distribution_levers/admin_ui_spec.rb @@ -11,8 +11,6 @@ let(:disabled_lever_list) do [ - Constants.DISTRIBUTION.cavc_aod_affinity_days, - Constants.DISTRIBUTION.cavc_affinity_days, Constants.DISTRIBUTION.aoj_affinity_days, Constants.DISTRIBUTION.aoj_aod_affinity_days, Constants.DISTRIBUTION.aoj_cavc_affinity_days @@ -22,7 +20,9 @@ let(:enabled_lever_list) do [ Constants.DISTRIBUTION.ama_hearing_case_affinity_days, - Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days + Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days, + Constants.DISTRIBUTION.cavc_aod_affinity_days, + Constants.DISTRIBUTION.cavc_affinity_days ] end diff --git a/spec/jobs/incomplete_distributions_job_spec.rb b/spec/jobs/incomplete_distributions_job_spec.rb index 901820f4d9a..ac26004e172 100644 --- a/spec/jobs/incomplete_distributions_job_spec.rb +++ b/spec/jobs/incomplete_distributions_job_spec.rb @@ -11,6 +11,7 @@ create(:case_distribution_lever, :nod_adjustment) create(:case_distribution_lever, :batch_size_per_attorney) create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) create(:case_distribution_lever, :ama_hearing_case_affinity_days) create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days) create(:case_distribution_lever, :ama_direct_review_start_distribution_prior_to_goals) diff --git a/spec/jobs/push_priority_appeals_to_judges_job_spec.rb b/spec/jobs/push_priority_appeals_to_judges_job_spec.rb index c6a2bae3ea1..ea2cb33b691 100644 --- a/spec/jobs/push_priority_appeals_to_judges_job_spec.rb +++ b/spec/jobs/push_priority_appeals_to_judges_job_spec.rb @@ -9,6 +9,7 @@ create(:case_distribution_lever, :nod_adjustment) create(:case_distribution_lever, :batch_size_per_attorney) create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) create(:case_distribution_lever, :ama_hearing_case_affinity_days) create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days) create(:case_distribution_lever, :ama_direct_review_start_distribution_prior_to_goals) @@ -250,7 +251,7 @@ def to_judge_hash(arr) end after do FeatureToggle.disable!(:acd_distribute_by_docket_date) - FeatureToggle.enable!(:acd_exclude_from_affinity) + FeatureToggle.disable!(:acd_exclude_from_affinity) end it "should only distribute the ready priority cases tied to a judge" do diff --git a/spec/jobs/update_appeal_affinity_dates_job_spec.rb b/spec/jobs/update_appeal_affinity_dates_job_spec.rb index 83201b15e92..e68f298cf32 100644 --- a/spec/jobs/update_appeal_affinity_dates_job_spec.rb +++ b/spec/jobs/update_appeal_affinity_dates_job_spec.rb @@ -182,6 +182,21 @@ end end + context "#process_legacy_appeals_which_need_affinity_updates" do + let(:hashes_array) do + [{ docket: "hearing", priority: true, receipt_date: Time.zone.now }, + { docket: "direct_review", priority: true, receipt_date: Time.zone.now }, + { docket: "legacy", priority: true, receipt_date: Time.zone.now }] + end + + subject { described_class.new.send(:process_legacy_appeals_which_need_affinity_updates, hashes_array) } + + it "processes only legacy appeals" do + expect_any_instance_of(described_class).to receive(:create_or_update_appeal_affinities).exactly(1).times + subject + end + end + context "#create_or_update_appeal_affinties" do before { create(:case_distribution_lever, :request_more_cases_minimum) } @@ -212,6 +227,38 @@ end end + context "#legacy_appeals_with_no_appeal_affinities" do + before { create(:case_distribution_lever, :request_more_cases_minimum) } + + let(:judge) { create(:user, :judge, :with_vacols_judge_record) } + let(:distribution) { create(:distribution, :completed, judge: judge) } + let(:appeal_no_appeal_affinity) { create(:case) } + let(:appeal_with_appeal_affinity) { create(:case, :with_appeal_affinity) } + let(:appeal_with_appeal_affinity_no_start_date) { create(:case, :with_appeal_affinity, affinity_start_date: nil) } + let(:job) { described_class.new } + let(:appeal_no_affinity_hash) do + { "bfkey" => appeal_no_appeal_affinity.bfkey, + "bfd19" => appeal_no_appeal_affinity.bfd19 } + end + let(:appeal_with_affinity_hash) do + { "bfkey" => appeal_with_appeal_affinity.bfkey, + "bfd19" => appeal_with_appeal_affinity.bfd19 } + end + let(:appeal_with_affinity_no_start_date_hash) do + { "bfkey" => appeal_with_appeal_affinity_no_start_date.bfkey, + "bfd19" => appeal_with_appeal_affinity_no_start_date.bfd19 } + end + + before { job.instance_variable_set(:@distribution_id, distribution.id) } + + it "only returns appeals with no affinity records or affinity start dates" do + appeals = [appeal_with_affinity_hash, appeal_no_affinity_hash, appeal_with_affinity_no_start_date_hash] + result = job.send(:legacy_appeals_with_no_appeal_affinities, appeals) + + expect(result.count).to eq 2 + end + end + context "#perform" do it "updates from distribution if provided a distribution_id" do expect_any_instance_of(described_class).to receive(:update_from_requested_distribution).and_return(true) @@ -345,11 +392,30 @@ create(:appeal, :hearing_docket, :with_post_intake_tasks) end + # legacy appeal distributed + let!(:distributed_legacy_case) do + legacy_appeal = create(:case, :tied_to_judge, :type_original, tied_judge: judge, bfd19: 3.weeks.ago) + create(:legacy_distributed_case, appeal: legacy_appeal, distribution: previous_distribution, priority: false) + legacy_appeal + end + + # legacy appeals ready for distribution + let!(:legacy_appeal_no_appeal_affinity) { create(:case, :ready_for_distribution, :type_original) } + let!(:legacy_appeal_no_appeal_affinity_no_start_date) do + create(:case, :ready_for_distribution, :type_original, :with_appeal_affinity, affinity_start_date: nil) + end + let!(:legacy_appeal_with_appeal_affinity) do + create(:case, :ready_for_distribution, :with_appeal_affinity, :type_original) + end + let!(:legacy_appeal_no_appeal_affinity_later_bfd19) do + create(:case, :ready_for_distribution, :type_original, bfd19: 1.week.ago) + end + it "is successful and adds expected appeal affinity records or values" do described_class.perform_now(previous_distribution.id) - # Only 8 of the staged appeals should have an affinity - expect(AppealAffinity.count).to eq 8 + # Only 11 of the staged appeals should have an affinity + expect(AppealAffinity.count).to eq 11 # Validate that only the expected appeals are the ones that were updated expect(ready_appeal_drd_priority.appeal_affinity).to_not be nil @@ -360,6 +426,9 @@ expect(ready_appeal_esd_priority_no_start_date.appeal_affinity).to_not be nil expect(ready_appeal_hrd_priority_no_start_date.appeal_affinity).to_not be nil expect(ready_appeal_hrd_nonpriority_no_start_date.appeal_affinity).to_not be nil + expect(legacy_appeal_no_appeal_affinity.appeal_affinity).to_not be nil + expect(legacy_appeal_no_appeal_affinity_no_start_date.appeal_affinity).to_not be nil + expect(legacy_appeal_no_appeal_affinity_later_bfd19.appeal_affinity).to be nil end end end diff --git a/spec/models/case_distribution_lever_spec.rb b/spec/models/case_distribution_lever_spec.rb index f551e4d0244..d0f5850f7a9 100644 --- a/spec/models/case_distribution_lever_spec.rb +++ b/spec/models/case_distribution_lever_spec.rb @@ -12,6 +12,8 @@ ama_hearing_case_affinity_days ama_hearing_case_aod_affinity_days cavc_affinity_days + cavc_aod_affinity_days + ama_hearing_case_aod_affinity_days ama_evidence_submission_docket_time_goals ama_hearing_docket_time_goals ama_hearing_start_distribution_prior_to_goals diff --git a/spec/models/concerns/by_docket_date_distribution_spec.rb b/spec/models/concerns/by_docket_date_distribution_spec.rb index 49d56ea6454..120ebc338d6 100644 --- a/spec/models/concerns/by_docket_date_distribution_spec.rb +++ b/spec/models/concerns/by_docket_date_distribution_spec.rb @@ -25,6 +25,8 @@ def batch_size create(:case_distribution_lever, :ama_hearing_docket_time_goals) create(:case_distribution_lever, :disable_legacy_non_priority) create(:case_distribution_lever, :disable_legacy_priority) + create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) end # used to put {num} ambiguous objects into an array to mock the return array from requested_distribution diff --git a/spec/models/distribution_spec.rb b/spec/models/distribution_spec.rb index fe5118272e2..242572d2bce 100644 --- a/spec/models/distribution_spec.rb +++ b/spec/models/distribution_spec.rb @@ -15,6 +15,7 @@ create(:case_distribution_lever, :alternative_batch_size) create(:case_distribution_lever, :nod_adjustment) create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) create(:case_distribution_lever, :ama_hearing_case_affinity_days) create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days) create(:case_distribution_lever, :ama_direct_review_docket_time_goals) diff --git a/spec/models/docket_spec.rb b/spec/models/docket_spec.rb index 6b114f4467f..052be3f5602 100644 --- a/spec/models/docket_spec.rb +++ b/spec/models/docket_spec.rb @@ -11,6 +11,7 @@ create(:case_distribution_lever, :ama_direct_review_start_distribution_prior_to_goals) create(:case_distribution_lever, :ama_evidence_submission_review_start_distribution_prior_to_goals) create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) create(:case_distribution_lever, :request_more_cases_minimum) create(:case_distribution_lever, :disable_ama_non_priority_direct_review) end @@ -131,12 +132,11 @@ context "when called for ready is true and judge is passed" do let(:judge) { judge_decision_review_task.assigned_to } - subject { DirectReviewDocket.new.appeals(ready: true, judge: judge) } + + subject { DirectReviewDocket.new.appeals(ready: true, priority: false, judge: judge) } it "returns non priority appeals" do - expect(subject).to include appeal - expect(subject).to include denied_aod_motion_appeal - expect(subject).to include inapplicable_aod_motion_appeal + expect(subject).to match_array([appeal, denied_aod_motion_appeal, inapplicable_aod_motion_appeal]) end end end diff --git a/spec/models/dockets/hearing_request_docket_spec.rb b/spec/models/dockets/hearing_request_docket_spec.rb index 2fce445d47d..971ac83d2b6 100644 --- a/spec/models/dockets/hearing_request_docket_spec.rb +++ b/spec/models/dockets/hearing_request_docket_spec.rb @@ -6,10 +6,10 @@ # back to what the tests were originally written for create(:case_distribution_lever, :ama_hearing_case_affinity_days, value: "60") create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days, value: "14") + create(:case_distribution_lever, :cavc_affinity_days, value: "21") + create(:case_distribution_lever, :cavc_aod_affinity_days, value: "14") create(:case_distribution_lever, :request_more_cases_minimum) create(:case_distribution_lever, :batch_size_per_attorney) - create(:case_distribution_lever, :cavc_affinity_days) - create(:case_distribution_lever, :cavc_aod_affinity_days) create(:case_distribution_lever, :ama_hearing_docket_time_goals) create(:case_distribution_lever, :ama_hearing_start_distribution_prior_to_goals) @@ -17,11 +17,7 @@ # these were the defaut values at time of writing tests but can change over time, so ensure they are set # back to what the tests were originally written for - CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.ama_hearing_case_affinity_days).update!(value: "60") - CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days).update!(value: "14") CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.ama_hearing_docket_time_goals).update!(value: 60) - CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.ama_hearing_start_distribution_prior_to_goals) - .update!(is_toggle_active: true) end context "#ready_priority_appeals" do @@ -696,16 +692,30 @@ context "with multiple levers enabled and appeals meeting each criteria" do # ready non-aod appeals let!(:ready_cavc_appeal_tied_to_requesting_judge_in_window) do - create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 7.days.ago) + create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 15.days.ago) end - let!(:ready_cavc_appeal_tied_to_requesting_judge_out_of_window_21_days) do - create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 21.days.ago) + let!(:ready_cavc_appeal_tied_to_requesting_judge_out_of_window_22_days) do + create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 22.days.ago) end let!(:ready_cavc_appeal_tied_to_other_judge_in_window) do - create_ready_cavc_appeal(tied_judge: other_judge, created_date: 7.days.ago) + create_ready_cavc_appeal(tied_judge: other_judge, created_date: 15.days.ago) end - let!(:ready_cavc_appeal_tied_to_other_judge_out_of_window_21_days) do - create_ready_cavc_appeal(tied_judge: other_judge, created_date: 21.days.ago) + let!(:ready_cavc_appeal_tied_to_other_judge_out_of_window_22_days) do + create_ready_cavc_appeal(tied_judge: other_judge, created_date: 22.days.ago) + end + + # ready aod + cavc appeals to verify that distribution uses the lowest lever value to distribute + let!(:ready_cavc_aod_appeal_tied_to_requesting_judge_in_window) do + create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 5.days.ago, aod: true) + end + let!(:ready_cavc_aod_appeal_tied_to_requesting_judge_out_of_window_10_days) do + create_ready_cavc_appeal(tied_judge: requesting_judge_no_attorneys, created_date: 10.days.ago, aod: true) + end + let!(:ready_cavc_aod_appeal_tied_to_other_judge_in_window) do + create_ready_cavc_appeal(tied_judge: other_judge, created_date: 5.days.ago, aod: true) + end + let!(:ready_cavc_aod_appeal_tied_to_other_judge_out_of_window_10_days) do + create_ready_cavc_appeal(tied_judge: other_judge, created_date: 10.days.ago, aod: true) end # ready aod appeals @@ -738,7 +748,8 @@ before do FeatureToggle.enable!(:specialty_case_team_distribution) CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.ama_hearing_case_affinity_days).update!(value: "30") - CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.cavc_affinity_days).update!(value: "14") + CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.cavc_affinity_days).update!(value: "21") + CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.cavc_aod_affinity_days).update!(value: "7") CaseDistributionLever .find_by_item(Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days) .update!(value: "15") @@ -750,8 +761,11 @@ it "distributes appeals as expected" do expect(subject.map(&:case_id)).to match_array( [ready_cavc_appeal_tied_to_requesting_judge_in_window.uuid, - ready_cavc_appeal_tied_to_requesting_judge_out_of_window_21_days.uuid, - ready_cavc_appeal_tied_to_other_judge_out_of_window_21_days.uuid, + ready_cavc_appeal_tied_to_requesting_judge_out_of_window_22_days.uuid, + ready_cavc_appeal_tied_to_other_judge_out_of_window_22_days.uuid, + ready_cavc_aod_appeal_tied_to_requesting_judge_in_window.uuid, + ready_cavc_aod_appeal_tied_to_requesting_judge_out_of_window_10_days.uuid, + ready_cavc_aod_appeal_tied_to_other_judge_out_of_window_10_days.uuid, ready_aod_tied_to_requesting_judge_in_window.uuid, ready_aod_tied_to_requesting_judge_out_of_window_20_days.uuid, ready_aod_tied_to_other_judge_out_of_window_20_days.uuid, @@ -887,7 +901,7 @@ def create_ready_aod_appeal_no_appeal_affinity(tied_judge: nil, created_date: 1. appeal end - def create_ready_cavc_appeal(tied_judge: nil, created_date: 1.year.ago) + def create_ready_cavc_appeal(tied_judge: nil, created_date: 1.year.ago, aod: false) Timecop.travel(created_date - 6.months) if tied_judge judge = tied_judge @@ -920,9 +934,22 @@ def create_ready_cavc_appeal(tied_judge: nil, created_date: 1.year.ago) create(:appeal_affinity, appeal: remand_appeal) Timecop.return + create_aod_motion(remand_appeal, remand_appeal.claimant.person) if aod + remand_appeal end + def create_aod_motion(appeal, person) + create( + :advance_on_docket_motion, + appeal: appeal, + granted: true, + person: person, + reason: Constants.AOD_REASONS.financial_distress, + user_id: User.system_user.id + ) + end + def create_ready_nonpriority_appeal(tied_judge: nil, created_date: 1.year.ago) Timecop.travel(created_date) appeal = create( diff --git a/spec/models/dockets/legacy_docket_spec.rb b/spec/models/dockets/legacy_docket_spec.rb index 3763a52f145..83ccb4d00bd 100644 --- a/spec/models/dockets/legacy_docket_spec.rb +++ b/spec/models/dockets/legacy_docket_spec.rb @@ -6,6 +6,8 @@ create(:case_distribution_lever, :nod_adjustment) create(:case_distribution_lever, :disable_legacy_non_priority) create(:case_distribution_lever, :disable_legacy_priority) + create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) end let(:docket) do diff --git a/spec/models/vacols/case_docket_spec.rb b/spec/models/vacols/case_docket_spec.rb index 0322794d56f..5258485183d 100644 --- a/spec/models/vacols/case_docket_spec.rb +++ b/spec/models/vacols/case_docket_spec.rb @@ -4,6 +4,11 @@ before do FeatureToggle.enable!(:test_facols) FeatureToggle.enable!(:acd_disable_legacy_lock_ready_appeals) + FeatureToggle.enable!(:acd_distribute_by_docket_date) + FeatureToggle.enable!(:acd_cases_tied_to_judges_no_longer_with_board) + FeatureToggle.enable!(:acd_exclude_from_affinity) + create(:case_distribution_lever, :cavc_affinity_days) + create(:case_distribution_lever, :cavc_aod_affinity_days) end after do @@ -29,7 +34,7 @@ bfac: "3", bfmpro: "ACT", bfcurloc: "81", - bfdloout: 1.day.ago, + bfdloout: 3.days.ago, bfbox: nonpriority_ready_case_bfbox, folder: build(:folder, tinum: nonpriority_ready_case_docket_number, titrnum: "123456789S")) end @@ -55,7 +60,7 @@ bfac: "1", bfmpro: "ACT", bfcurloc: "83", - bfdloout: 1.day.ago, + bfdloout: 2.days.ago, folder: build(:folder, tinum: another_nonpriority_ready_case_docket_number, titrnum: "123456789S") ).tap { |vacols_case| create(:mail, :blocking, :completed, mlfolder: vacols_case.bfkey) } end @@ -63,7 +68,7 @@ let(:third_nonpriority_ready_case_docket_number) { "1801005" } let(:third_nonpriority_ready_case) do create(:case, - bfd19: 1.year.ago, + bfd19: 10.months.ago, bfac: "3", bfmpro: "ACT", bfcurloc: "83", @@ -327,8 +332,10 @@ let(:bust_backlog) { false } before do - FeatureToggle.enabled?(:acd_cases_tied_to_judges_no_longer_with_board) - third_nonpriority_ready_case + FeatureToggle.enable!(:acd_cases_tied_to_judges_no_longer_with_board) + nonpriority_ready_case.reload + another_nonpriority_ready_case.reload + third_nonpriority_ready_case.reload end subject { VACOLS::CaseDocket.distribute_nonpriority_appeals(judge, genpop, range, limit, bust_backlog) } @@ -350,6 +357,7 @@ let(:limit) { 1 } it "only distributes cases to the limit" do expect(subject.count).to eq(1) + expect(subject.first["bfkey"]).to eq nonpriority_ready_case.bfkey expect(nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") expect(third_nonpriority_ready_case.reload.bfcurloc).to eq("83") @@ -358,8 +366,13 @@ context "when range is specified" do let(:range) { 1 } + + # We do not provide a range if this feature toggle is enabled + before { FeatureToggle.disable!(:acd_distribute_by_docket_date) } + it "only distributes cases within the range" do expect(subject.count).to eq(1) + expect(subject.first["bfkey"]).to eq nonpriority_ready_case.bfkey expect(nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") expect(third_nonpriority_ready_case.reload.bfcurloc).to eq("83") @@ -369,6 +382,7 @@ let(:another_nonpriority_ready_case_docket_number) { "9901002" } it "correctly orders the docket" do expect(subject.count).to eq(1) + expect(subject.first["bfkey"]).to eq another_nonpriority_ready_case.bfkey expect(nonpriority_ready_case.reload.bfcurloc).to eq("81") expect(another_nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(third_nonpriority_ready_case.reload.bfcurloc).to eq("83") @@ -399,6 +413,7 @@ let(:genpop) { "not_genpop" } it "distributes the case" do expect(subject.count).to eq(1) + expect(subject.first["bfkey"]).to eq nonpriority_ready_case.bfkey expect(nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") expect(third_nonpriority_ready_case.reload.bfcurloc).to eq("83") @@ -418,6 +433,7 @@ let(:genpop) { "only_genpop" } it "does distribute the case only tied to inactive judge" do expect(subject.count).to eq(1) + expect(subject.first["bfkey"]).to eq third_nonpriority_ready_case.bfkey expect(third_nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(nonpriority_ready_case.reload.bfcurloc).to eq("81") expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") @@ -429,6 +445,9 @@ let(:bust_backlog) { true } let(:another_hearing_judge) { judge.vacols_attorney_id } + # We don't use bust backlog if this feature toggle is enabled + before { FeatureToggle.disable!(:acd_distribute_by_docket_date) } + context "when the judge does not have 30 cases in their backlog" do it "does not distribute any appeals" do expect(subject.count).to eq(0) @@ -447,6 +466,7 @@ it "only distributes the one case to get back down to 30" do expect(subject.count).to eq(number_of_cases_over_backlog) + expect(subject.first["bfkey"]).to eq nonpriority_ready_case.bfkey expect(nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") end @@ -662,8 +682,313 @@ end end end + + # rubocop:disable Layout/LineLength + context "when CaseDistributionLever" do + before do + VACOLS::Case.where(bfcurloc: %w[81 83]).map { |c| c.update!(bfcurloc: "testing") } + end + + let(:aff_judge_caseflow) { create(:user) } + let!(:aff_judge) { create(:staff, :judge_role, sdomainid: aff_judge_caseflow.css_id) } + + let(:other_judge_caseflow) { create(:user) } + let!(:other_judge) { create(:staff, :judge_role, sdomainid: other_judge_caseflow.css_id) } + + let(:tied_judge_caseflow) { create(:user) } + let!(:tied_judge) { create(:staff, :judge_role, sdomainid: tied_judge_caseflow.css_id) } + + let(:inel_judge_caseflow) { create(:user) } + let!(:inel_judge) { create(:staff, :judge_role, svlj: "V", sdomainid: inel_judge_caseflow.css_id) } + + let(:excl_judge_caseflow) { create(:user, :judge_with_appeals_excluded_from_affinity) } + let!(:excl_judge) { create(:staff, :judge_role, sdomainid: excl_judge_caseflow.css_id) } + + let(:attorney_caseflow) { create(:user) } + let!(:attorney) { create(:staff, :attorney_role, sdomainid: attorney_caseflow.css_id) } + + context ".cavc_affinity_days lever is active" do + # cavc affinity cases: + # no hearing held but has previous decision + let!(:c1) do + create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, tied_to: false) + end + let!(:c2) do + create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + end + let!(:c3) do + create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + end + # hearing held with previous decision where judge is not the same + let!(:c4) do + c4 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney) + c4.update!(bfmemid: aff_judge.sattyid) + c4 + end + let!(:c5) do + c5 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + c5.update!(bfmemid: aff_judge.sattyid) + c5 + end + let!(:c6) do + c6 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, appeal_affinity: false) + c6.update!(bfmemid: aff_judge.sattyid) + c6 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:c7) { create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney) } + let!(:c8) do + create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, affinity_start_date: 3.days.ago) + end + let!(:c9) { create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, appeal_affinity: false) } + # hearing held but no previous deciding judge + let!(:c10) do + c10 = create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney) + c10.update!(bfmemid: nil) + c10 + end + # no hearing held, no previous deciding judge + let!(:c11) do + c11 = create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, + tied_to: false) + c11.update!(bfmemid: nil) + c11 + end + # excluded judge cases: + # no hearing held but has previous decision + let!(:c12) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, tied_to: false) } + let!(:c13) do + create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + end + let!(:c14) do + create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + end + # hearing held with previous decision where judge is not the same + let!(:c15) do + c15 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney) + c15.update!(bfmemid: excl_judge.sattyid) + c15 + end + let!(:c16) do + c16 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + c16.update!(bfmemid: excl_judge.sattyid) + c16 + end + let!(:c17) do + c17 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, appeal_affinity: false) + c17.update!(bfmemid: excl_judge.sattyid) + c17 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:c18) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney) } + let!(:c19) do + create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, affinity_start_date: 3.days.ago) + end + let!(:c20) do + create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, appeal_affinity: false) + end + # ineligible judge cases: + # no hearing held but has previous decision + let!(:c21) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, tied_to: false) } + let!(:c22) do + create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, + tied_to: false, affinity_start_date: 3.days.ago) + end + let!(:c23) do + create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, + tied_to: false, appeal_affinity: false) + end + # hearing held with previous decision where judge is not the same + let!(:c24) do + c24 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney) + c24.update!(bfmemid: inel_judge.sattyid) + c24 + end + let!(:c25) do + c25 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, + affinity_start_date: 3.days.ago) + c25.update!(bfmemid: inel_judge.sattyid) + c25 + end + let!(:c26) do + c26 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, appeal_affinity: false) + c26.update!(bfmemid: inel_judge.sattyid) + c26 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:c27) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney) } + let!(:c28) do + create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, affinity_start_date: 3.days.ago) + end + let!(:c29) do + create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, appeal_affinity: false) + end + # hearing held but no previous deciding judge + let!(:c30) do + c30 = create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney) + c30.update!(bfmemid: nil) + c30 + end + + it "distributes CAVC cases correctly based on lever value", :aggregate_failures do + IneligibleJudgesJob.new.perform_now + cavc_lever = CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.cavc_affinity_days) + + # {FOR LEVER BEING A VALUE:} + cavc_lever.update!(value: 14) + expect(VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort) + .to match_array([c1, c4, c10, c11, c12, c13, c14, c15, c16, c17, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + # {FOR LEVER BEING INFINITE:} + cavc_lever.update!(value: "infinite") + expect( + VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort + ) + .to match_array([c11, c12, c13, c14, c15, c16, c17, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + # {FOR LEVER BEING OMIT:} + cavc_lever.update!(value: "omit") + expect(VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort) + .to match_array([ + c1, c2, c3, c4, c5, c6, c10, c11, c12, c13, c14, c15, c16, c17, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 + ] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + end + end + + context ".cavc_aod_affinity_days lever is active" do + # cavc aod affinity cases: + # no hearing held but has previous decision + let!(:ca1) { create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, aod: true, tied_to: false) } + let!(:ca2) { create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) } + let!(:ca3) { create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) } + # hearing held with previous decision where judge is not the same + let!(:ca4) do + ca4 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true) + ca4.update!(bfmemid: aff_judge.sattyid) + ca4 + end + let!(:ca5) do + ca5 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + ca5.update!(bfmemid: aff_judge.sattyid) + ca5 + end + let!(:ca6) do + ca6 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + ca6.update!(bfmemid: aff_judge.sattyid) + ca6 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:ca7) { create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, aod: true) } + let!(:ca8) { create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) } + let!(:ca9) { create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, aod: true, appeal_affinity: false) } + # hearing held but no previous deciding judge + let!(:ca10) do + ca10 = create(:legacy_cavc_appeal, judge: tied_judge, attorney: attorney, aod: true) + ca10.update!(bfmemid: nil) + ca10 + end + # no hearing held, no previous deciding judge + let!(:ca11) do + ca11 = create(:legacy_cavc_appeal, judge: aff_judge, attorney: attorney, aod: true, tied_to: false) + ca11.update!(bfmemid: nil) + ca11 + end + # excluded judge cases: + # no hearing held but has previous decision + let!(:ca12) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true, tied_to: false) } + let!(:ca13) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) } + let!(:ca14) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) } + # hearing held with previous decision where judge is not the same + let!(:ca15) do + ca15 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true) + ca15.update!(bfmemid: excl_judge.sattyid) + ca15 + end + let!(:ca16) do + ca16 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + ca16.update!(bfmemid: excl_judge.sattyid) + ca16 + end + let!(:ca17) do + ca17 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + ca17.update!(bfmemid: excl_judge.sattyid) + ca17 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:ca18) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true) } + let!(:ca19) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) } + let!(:ca20) { create(:legacy_cavc_appeal, judge: excl_judge, attorney: attorney, aod: true, appeal_affinity: false) } + # ineligible judge cases: + # no hearing held but has previous decision + let!(:ca21) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true, tied_to: false) } + let!(:ca22) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true, tied_to: false, affinity_start_date: 3.days.ago) } + let!(:ca23) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true, tied_to: false, appeal_affinity: false) } + # hearing held with previous decision where judge is not the same + let!(:ca24) do + ca24 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true) + ca24.update!(bfmemid: inel_judge.sattyid) + ca24 + end + let!(:ca25) do + ca25 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) + ca25.update!(bfmemid: inel_judge.sattyid) + ca25 + end + let!(:ca26) do + ca26 = create(:legacy_cavc_appeal, judge: other_judge, attorney: attorney, aod: true, appeal_affinity: false) + ca26.update!(bfmemid: inel_judge.sattyid) + ca26 + end + # hearing held with previous decision where judge is same (THIS IS TIED TO) + let!(:ca27) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true) } + let!(:ca28) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true, affinity_start_date: 3.days.ago) } + let!(:ca29) { create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true, appeal_affinity: false) } + # hearing held but no previous deciding judge + let!(:ca30) do + ca30 = create(:legacy_cavc_appeal, judge: inel_judge, attorney: attorney, aod: true) + ca30.update!(bfmemid: nil) + ca30 + end + + it "distributes CAVC AOD cases correctly based on lever value", :aggregate_failures do + IneligibleJudgesJob.new.perform_now + cavc_aod_lever = CaseDistributionLever.find_by_item(Constants.DISTRIBUTION.cavc_aod_affinity_days) + + # {FOR LEVER HAVING A VALUE:} + cavc_aod_lever.update!(value: 14) + expect(VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort) + .to match_array([ + ca1, ca4, ca10, ca11, ca12, ca13, ca14, ca15, ca16, ca17, ca21, ca22, ca23, ca24, ca25, + ca26, ca27, ca28, ca29, ca30 + ] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + # {FOR LEVER BEING INFINITE:} + cavc_aod_lever.update!(value: "infinite") + expect(VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort) + .to match_array([ca11, ca12, ca13, ca14, ca15, ca16, ca17, ca21, ca22, ca23, ca24, ca25, ca26, ca27, ca28, ca29, ca30] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + # {FOR LEVER BEING OMIT:} + cavc_aod_lever.update!(value: "omit") + expect(VACOLS::CaseDocket.distribute_priority_appeals(judge, "any", 100, true).map { |c| c["bfkey"] }.sort) + .to match_array([ + ca1, ca2, ca3, ca4, ca5, ca6, ca10, ca11, ca12, ca13, ca14, ca15, ca16, ca17, ca21, ca22, + ca23, ca24, ca25, ca26, ca27, ca28, ca29, ca30 + ] + .map { |c| (c["bfkey"].to_i + 1).to_s }.sort) + end + end + end end + # rubocop:enable Layout/LineLength + context "legacy_das_deprecation FeatureToggle enabled" do before do FeatureToggle.enable!(:legacy_das_deprecation) diff --git a/spec/queries/appeals_ready_for_distribution.rb b/spec/queries/appeals_ready_for_distribution.rb new file mode 100644 index 00000000000..6b29f0834ea --- /dev/null +++ b/spec/queries/appeals_ready_for_distribution.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +describe AppealsReadyForDistribution do + let(:hearing_judge) { create(:user, :judge, :with_vacols_judge_record) } + let(:original_deciding_judge) { create(:user, :judge, :with_vacols_judge_record) } + + context "#process and #ready_appeals" do + let!(:not_ready_ama_original_appeal) { create(:appeal, :evidence_submission_docket, :with_post_intake_tasks) } + let!(:ama_original_direct_review_appeal) { create(:appeal, :direct_review_docket, :ready_for_distribution) } + let!(:ama_original_evidence_submission_appeal) do + create(:appeal, :evidence_submission_docket, :ready_for_distribution) + end + let!(:ama_original_hearing_appeal) do + create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, tied_judge: hearing_judge) + end + let!(:ama_cavc_direct_review_appeal) { create_realistic_cavc_case(Constants.AMA_DOCKETS.direct_review) } + let!(:ama_cavc_evidence_submission_appeal) do + create_realistic_cavc_case(Constants.AMA_DOCKETS.evidence_submission) + end + let!(:ama_cavc_hearing_appeal) { create_realistic_cavc_case(Constants.AMA_DOCKETS.hearing) } + let!(:not_ready_legacy_original_appeal) do + create(:case_with_form_9, :type_original, :travel_board_hearing_requested) + end + let!(:legacy_original_appeal_no_hearing) { create(:case, :type_original, :ready_for_distribution) } + let!(:legacy_original_appeal_with_hearing) do + create(:case, :type_original, :ready_for_distribution, case_hearings: [legacy_original_appeal_case_hearing]) + end + let(:legacy_original_appeal_case_hearing) { build(:case_hearing, :disposition_held, user: hearing_judge) } + let!(:legacy_cavc_appeal_no_hearing) do + original = create(:legacy_cavc_appeal, judge: original_deciding_judge.vacols_staff) + VACOLS::Case.find_by(bfcorlid: original.bfcorlid, bfmpro: "ACT") + end + let!(:legacy_cavc_appeal_with_hearing) do + original = create(:legacy_cavc_appeal, judge: original_deciding_judge.vacols_staff) + create(:case_hearing, :disposition_held, folder_nr: original.bfkey, user: hearing_judge) + VACOLS::Case.find_by(bfcorlid: original.bfcorlid, bfmpro: "ACT") + end + + it "selects all ready to distribute appeals for all dockets and generates the CSV" do + expect { described_class.process }.not_to raise_error + expect(described_class.ready_appeals.size).to eq 10 + end + end + + context "legacy_rows" do + let!(:legacy_appeal_with_attributes) do + create(:case, :type_original, :aod, :ready_for_distribution, :with_appeal_affinity, case_hearings: [case_hearing]) + end + let(:case_hearing) { build(:case_hearing, :disposition_held, user: hearing_judge) } + let(:query_result) { VACOLS::CaseDocket.ready_to_distribute_appeals } + + subject { described_class.legacy_rows(query_result, LegacyDocket.new, :legacy).first } + + it "correctly uses attributes to create a hash for the row" do + corres = legacy_appeal_with_attributes.reload.correspondent + + expect(subject[:docket_number]).to eq legacy_appeal_with_attributes.folder.tinum + expect(subject[:docket]).to eq "legacy" + expect(subject[:aod]).to be true + expect(subject[:cavc]).to be false + expect(subject[:receipt_date]).to eq legacy_appeal_with_attributes.bfd19 + expect(subject[:ready_for_distribution_at]).to eq legacy_appeal_with_attributes.bfdloout + expect(subject[:hearing_judge]).to eq hearing_judge.full_name + expect(subject[:original_judge]).to be nil + expect(subject[:veteran_file_number]).to eq legacy_appeal_with_attributes.bfcorlid + expect(subject[:veteran_name]).to eq "#{corres.snamef} #{corres.snamel}" + expect(subject[:affinity_start_date]).to eq legacy_appeal_with_attributes.appeal_affinity.affinity_start_date + end + end + + context "ama_rows" do + let!(:ama_appeal_with_attributes) do + create( + :appeal, + :hearing_docket, + :advanced_on_docket_due_to_motion, + :held_hearing_and_ready_to_distribute, + :with_appeal_affinity, + tied_judge: hearing_judge + ) + end + let(:query_result) { HearingRequestDocket.new.ready_to_distribute_appeals } + + subject { described_class.ama_rows(query_result, HearingRequestDocket.new, :hearing).first } + + it "correctly uses the attributes to create a hash for the row" do + # Reload to update the appeal_affinity record correctly in memory because of eager loading + ama_appeal_with_attributes.reload + + expect(subject[:docket_number]).to eq ama_appeal_with_attributes.docket_number + expect(subject[:docket]).to eq "hearing" + expect(subject[:aod]).to be true + expect(subject[:cavc]).to be false + expect(subject[:receipt_date]).to eq ama_appeal_with_attributes.receipt_date + expect(subject[:ready_for_distribution_at]) + .to eq ama_appeal_with_attributes.tasks.where(type: DistributionTask.name).first.assigned_at + expect(subject[:hearing_judge]).to eq ama_appeal_with_attributes.hearings.first.judge.full_name + expect(subject[:original_judge]).to be nil + expect(subject[:veteran_file_number]).to eq ama_appeal_with_attributes.veteran_file_number + expect(subject[:veteran_name]).to eq ama_appeal_with_attributes.veteran.name.to_s + expect(subject[:affinity_start_date]).to eq ama_appeal_with_attributes.appeal_affinity.affinity_start_date + end + end + + context "ama_cavc_original_deciding_judge" do + let!(:appeal) { create_realistic_cavc_case(Constants.AMA_DOCKETS.direct_review) } + + it "returns the original judge's CSS_ID" do + expect(described_class.ama_cavc_original_deciding_judge(appeal)).to eq original_deciding_judge.css_id + end + end + + context "legacy_original_deciding_judge" do + let!(:legacy_appeal) do + { "bfkey" => "test_key_pls_ignore", "prev_deciding_judge" => original_deciding_judge.vacols_staff.sattyid } + end + + it "returns the original judge's SDOMAINID if present" do + expect(described_class.legacy_original_deciding_judge(legacy_appeal)).to eq original_deciding_judge.css_id + end + + context "when the original judge has no SDOMAINID" do + before { original_deciding_judge.vacols_staff.update!(sdomainid: nil) } + + it "returns the prev_deciding_judge value from the query" do + expect(described_class.legacy_original_deciding_judge(legacy_appeal)) + .to eq legacy_appeal["prev_deciding_judge"] + end + end + end + + def create_realistic_cavc_case(docket) + docket_trait = "#{docket}_docket".to_s + source = Timecop.travel(1.year.ago) do + create(:appeal, docket_trait, :dispatched, associated_judge: original_deciding_judge) + end + remand = create(:cavc_remand, source_appeal: source) + remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! + create(:appeal_affinity, appeal: remand.remand_appeal) + remand.remand_appeal + end +end diff --git a/spec/workflows/das_deprecation/case_distribution_spec.rb b/spec/workflows/das_deprecation/case_distribution_spec.rb index 76d7916d2f4..8f68282338b 100644 --- a/spec/workflows/das_deprecation/case_distribution_spec.rb +++ b/spec/workflows/das_deprecation/case_distribution_spec.rb @@ -2,6 +2,8 @@ describe DasDeprecation::CaseDistribution, :all_dbs do let(:judge) { create(:user, css_id: "BVATWARNER", roles: ["Hearing Prep"]) } + let!(:cavc_affinity_days_lever) { create(:case_distribution_lever, :cavc_affinity_days) } + let!(:cavc_aod_affinity_days_lever) { create(:case_distribution_lever, :cavc_aod_affinity_days) } describe "#create_judge_assign_task" do context "Non-Priority Legacy Appeal" do let!(:legacy_priority_cases) do