Skip to content

Commit

Permalink
Feature/appeals 44915.uat 4.3.0 (#22557)
Browse files Browse the repository at this point in the history
* Add in appeals_tied_to_non_ssc_avljs methods and SQL

* Update case_docket.rb

* Update case_docket.rb

* APPEALS-51263 added the lever to the seeds file (#22149)

* Amybids/appeals 51263 (#22169)

* APPEALS-51263 added the lever to the seeds file

* APPEALS-51263 test cleanup for case_docket, case_distribution_levers_controller_spec and case_distribution_test_data_spec.rb

* APPEALS-51262 (#22176)

* creates trait in factory for non_ssc_avlj user

* updates user in user factory with new traits in staff factory

* adds randomized judge method

* replaces user create with a vacols staff create and limits css_id to 12 using slogid, adds judge_role for active smemgrp

* updates naming

---------

Co-authored-by: Michael Beard <michael.beard@va.gov>

* APPEALS-45232. Added table in the DB and added requested columns (#22223)

* APPEALS-45232. Added table in the DB and added requested columns

* APPEALS-45232. Fix lint issues

* APPEALS-45232. Fixed the class name

* APPEALS-45232. Updated the column names from feedback

---------

Co-authored-by: SHarshain <spoosa@razortalent.com>

* Sharsha/appeals 45200 (#22233)

* APPEALS-45200. create Return Appeals tied to non-SSC AVLJs job

* APPEALS-45200. WIP

---------

Co-authored-by: SHarshain <spoosa@razortalent.com>

* Chrisbdetlef/appeals 45208 (#22305)

* Framework for seeds

* Add comments and fill in further methods

* Further shared dev work

* Update names

* Expanded possible functions

* More functions for shared work

* Combine everyones work into main branch

* Combined work - testing

* Combined work - testing complete

* rubocop fix

---------

Co-authored-by: Christopher Detlef <>

* APPEALS-45202.Added button to trigger the job and return the appeals (#22375)

Co-authored-by: SHarshain <spoosa@razortalent.com>

* Updates slack_service.rb to include local/demo console printout message (#22343)

* APPEALS-51487 Location 63 Query (#22398)

* APPEALS-51487 Location 63 Query

* fix naming and change query

* Working code

* Add 2 day limit to query

* Remove commented out code

* Fix lint issues

* Remove binding.pry

---------

Co-authored-by: Christopher Detlef <>

* APPEALS-45248 ACD Controls Test Page Alerts for Run Seed Fils and Case Movement Section Buttons (#22386)

* APPEALS-45248 Add success banner alerts to Run seed files and case movement section buttons

* APPEALS-45248 add fail job button and refactored code

* Ricky/APPEALS-45204 (#22373)

* Added button, and initial csv generation of appeals tied to non ssc avljs

* WIP. APPEALS-45204 tweaks to Push data into CSV

* APPEALS-45204. fix the method error

* APPEALS-45204. Lint fix

* Updated query to fetch hearing and grab non ssc avlj names properly

* Fixed outstanding issues and cleaned up seeds

* implements new hearing_judge, separates assigned_avlj and signing_avlj

* Fixed linting issues and other clean up

---------

Co-authored-by: SHarshain <133917878+SHarshain@users.noreply.github.com>
Co-authored-by: SHarshain <spoosa@razortalent.com>
Co-authored-by: Michael Beard <michael.beard@va.gov>

* Ricky/APPEALS-45204 (#22452)

* Added button, and initial csv generation of appeals tied to non ssc avljs

* WIP. APPEALS-45204 tweaks to Push data into CSV

* APPEALS-45204. fix the method error

* APPEALS-45204. Lint fix

* Updated query to fetch hearing and grab non ssc avlj names properly

* Fixed outstanding issues and cleaned up seeds

* implements new hearing_judge, separates assigned_avlj and signing_avlj

* Fixed linting issues and other clean up

* Updated name of CSV download button

---------

Co-authored-by: SHarshain <133917878+SHarshain@users.noreply.github.com>
Co-authored-by: SHarshain <spoosa@razortalent.com>
Co-authored-by: Michael Beard <michael.beard@va.gov>

* Chrisbdetlef/appeals 54138 (#22460)

* APPEALS-51487 Location 63 Query

* fix naming and change query

* Working code

* Add 2 day limit to query

* Remove commented out code

* Fix lint issues

* Remove binding.pry

* APPEALS-54138 Add button to seed non-SSC AVLJs

---------

Co-authored-by: Christopher Detlef <>

* Fix for routing table (#22466)

Co-authored-by: Christopher Detlef <>

* Chrisbdetlef/appeals 54138.1 (#22486)

* Fix for routing table

* Randomly select docket id number

---------

Co-authored-by: Christopher Detlef <>

* Updated query to correctly grab seed data (#22489)

Co-authored-by: Amy Detwiler <133032208+amybids@users.noreply.github.com>

* Ricky/APPEALS-51260 (#22497)

* Updated query to correctly grab seed data

* Replaced AOD and CAVC fields with Priority, fixed csv file name

---------

Co-authored-by: Amy Detwiler <133032208+amybids@users.noreply.github.com>

* APPEALS-54884. spec fix push priority appeals to judges job (#22505)

Co-authored-by: SHarshain <spoosa@razortalent.com>

* exchanges spaces for hyphens, updates method to filter by unique veteran file numbers (#22524)

* updates seed file names to match AC and adds hyphens instead of spaces (#22530)

* Chrisbdetlef/appeals 54152 (#22531)

* APPEALS-54152 Move Appeals to loc 63

* Fix minor issues with the query and data displayed in the CSV

* APPEALS-54152 Move qualifying appeals to Loc 63

---------

Co-authored-by: Christopher Detlef <>

* APPEALS-54152.1 Fix issues with the process of making and moving appeals tied to nonSSC AVLJs (#22541)

Co-authored-by: Christopher Detlef <>

* Chrisbdetlef/appeals 54152.1 (#22544)

* APPEALS-54152.1 Fix issues with the process of making and moving appeals tied to nonSSC AVLJs

* TEST ONLY DO NOT MERGE

---------

Co-authored-by: Christopher Detlef <>

* Chrisbdetlef/appeals 54152.2 (#22554)

* APPEALS-54152.2 Change movement to loc 63 to 2 per AVLJ

* Fix lint issues and errors

* Remove artifact code

* Fix errors

---------

Co-authored-by: Christopher Detlef <>

---------

Co-authored-by: Matthew Roth <roth_matthew@bah.com>
Co-authored-by: Blake Manus <33578594+Blake-Manus@users.noreply.github.com>
Co-authored-by: Michael Beard <michael.beard@va.gov>
Co-authored-by: SHarshain <133917878+SHarshain@users.noreply.github.com>
Co-authored-by: SHarshain <spoosa@razortalent.com>
Co-authored-by: cdetlefva <133903625+cdetlefva@users.noreply.github.com>
Co-authored-by: Michael Beard <131783726+mbeardy@users.noreply.github.com>
Co-authored-by: kristeja <112115264+kristeja@users.noreply.github.com>
  • Loading branch information
9 people authored Aug 21, 2024
1 parent aa5034b commit 1c5aed1
Show file tree
Hide file tree
Showing 29 changed files with 1,349 additions and 18 deletions.
43 changes: 43 additions & 0 deletions app/controllers/case_distribution_levers_tests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ def run_demo_docket_priority
head :ok
end

def run_demo_non_avlj_appeals
Rake::Task["db:seed:non_ssc_avlj_legacy_appeals"].reenable
Rake::Task["db:seed:non_ssc_avlj_legacy_appeals"].invoke

head :ok
end

def appeals_ready_to_distribute
csv_data = AppealsReadyForDistribution.process

Expand All @@ -66,6 +73,15 @@ def appeals_non_priority_ready_to_distribute
send_data csv_data, filename: filename
end

def run_return_legacy_appeals_to_board
result = ReturnLegacyAppealsToBoardJob.perform_now(params[:fail_job])
if params[:fail_job] && result.include?("Job failed with error")
return render json: { error: result }, status: :unprocessable_entity
end

head :ok
end

def appeals_distributed
# change this to the correct class
csv_data = AppealsDistributed.process
Expand All @@ -80,6 +96,20 @@ def appeals_distributed
send_data csv_data, filename: filename
end

def appeals_in_location_63_in_past_2_days
# change this to the correct class
csv_data = AppealsInLocation63InPast2Days.process

# Get the current date and time for dynamic filename
current_datetime = Time.zone.now.strftime("%Y%m%d-%H%M")

# Set dynamic filename with current date and time
filename = "appeals_in_location_63_past_2_days_#{current_datetime}.csv"

# Send CSV as a response with dynamic filename
send_data csv_data, filename: filename
end

def ineligible_judge_list
# change this to the correct class
csv_data = IneligibleJudgeList.process
Expand All @@ -94,6 +124,19 @@ def ineligible_judge_list
send_data csv_data, filename: filename
end

def appeals_tied_to_non_ssc_avlj
csv_data = AppealsTiedToNonSscAvljQuery.process

# Get the current date and time for dynamic filename
current_datetime = Time.zone.now.strftime("%Y%m%d-%H%M")

# Set dynamic filename with current date and time
filename = "appeals_tied_to_non_ssc_avljs_#{current_datetime}.csv"

# Send CSV as a response with dynamic filename
send_data csv_data, filename: filename
end

private

def check_environment
Expand Down
1 change: 1 addition & 0 deletions app/jobs/push_priority_appeals_to_judges_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def perform
@genpop_distributions = distribute_genpop_priority_appeals

perform_later_or_now(UpdateAppealAffinityDatesJob)
perform_later_or_now(ReturnLegacyAppealsToBoardJob)

slack_service.send_notification(generate_report.join("\n"), self.class.name)
rescue StandardError => error
Expand Down
97 changes: 97 additions & 0 deletions app/jobs/return_legacy_appeals_to_board_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

class ReturnLegacyAppealsToBoardJob < CaseflowJob
# For time_ago_in_words()
include ActionView::Helpers::DateHelper
# include RunAsyncable

queue_as :low_priority
application_attr :queue

def perform(fail_job = false)
begin
returned_appeal_job = create_returned_appeal_job
fail if fail_job

move_qualifying_appeals(LegacyDocket.new.appeals_tied_to_non_ssc_avljs)
complete_returned_appeal_job(returned_appeal_job, "Job completed successfully", appeals)
send_job_slack_report
rescue StandardError => error
message = "Job failed with error: #{error.message}"
errored_returned_appeal_job(returned_appeal_job, message)
start_time ||= Time.zone.now # temporary fix to get this job to succeed
duration = time_ago_in_words(start_time)
slack_msg = "<!here>\n [ERROR] after running for #{duration}: #{error.message}"
slack_service.send_notification(slack_msg, self.class.name)
log_error(error)
message
ensure
@start_time ||= Time.zone.now
metrics_service_report_runtime(metric_group_name: "return_legacy_appeals_to_board_job")
end
end

private

def move_qualifying_appeals(appeals)
qualifying_appeals = []

non_ssc_avljs.each do |non_ssc_avlj|
tied_appeals = appeals.select { |appeal| appeal["vlj"] == non_ssc_avlj.sattyid }

unless tied_appeals.empty?
tied_appeals = tied_appeals.sort_by { |t_appeal| [-t_appeal["priority"], t_appeal["bfd19"]] }
end

if appeals.count < 2
qualifying_appeals.push(tied_appeals).flatten
else
qualifying_appeals.push(tied_appeals[0..1]).flatten
end
end

unless qualifying_appeals.empty?
qualifying_appeals = qualifying_appeals
.flatten
.sort_by { |appeal| [-appeal["priority"], appeal["bfd19"]] }
end

VACOLS::Case.batch_update_vacols_location("63", qualifying_appeals.map { |q_appeal| q_appeal["bfkey"] })
end

def non_ssc_avljs
VACOLS::Staff.where("sactive = 'A' AND svlj = 'A' AND sattyid <> smemgrp")
end

def create_returned_appeal_job
ReturnedAppealJob.create!(
started_at: Time.zone.now,
stats: { message: "Job started" }.to_json
)
end

def complete_returned_appeal_job(returned_appeal_job, message, appeals)
returned_appeal_job.update!(
completed_at: Time.zone.now,
stats: { message: message }.to_json,
returned_appeals: appeals.map { |appeal| appeal["bfkey"] }
)
end

def errored_returned_appeal_job(returned_appeal_job, message)
returned_appeal_job.update!(
errored_at: Time.zone.now,
stats: { message: message }.to_json
)
end

def send_job_slack_report
slack_service.send_notification(slack_report.join("\n"), self.class.name)
end

def slack_report
report = []
report << "Job performed successfully"
report
end
end
8 changes: 8 additions & 0 deletions app/models/dockets/legacy_docket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ def ready_to_distribute_appeals
LegacyAppeal.repository.ready_to_distribute_appeals
end

def appeals_tied_to_non_ssc_avljs
LegacyAppeal.repository.appeals_tied_to_non_ssc_avljs
end

def loc_63_appeals
LegacyAppeal.repository.loc_63_appeals
end

# rubocop:disable Metrics/CyclomaticComplexity
def count(priority: nil, ready: nil)
counts_by_priority_and_readiness.inject(0) do |sum, row|
Expand Down
4 changes: 4 additions & 0 deletions app/models/returned_appeal_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class ReturnedAppealJob < ApplicationRecord
end
115 changes: 112 additions & 3 deletions app/models/vacols/case_docket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ 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}
"

Expand All @@ -92,7 +93,7 @@ class DocketNumberCentennialLoop < StandardError; end

JOIN_ASSOCIATED_VLJS_BY_HEARINGS = "
left join (
select distinct TITRNUM, TINUM,
select distinct TITRNUM, TINUM, HEARING_DATE,
first_value(BOARD_MEMBER) over (partition by TITRNUM, TINUM order by HEARING_DATE desc) VLJ
from HEARSCHED
inner join FOLDER on FOLDER.TICKNUM = HEARSCHED.FOLDER_NR
Expand All @@ -103,6 +104,21 @@ 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
from (
Expand Down Expand Up @@ -161,8 +177,28 @@ class DocketNumberCentennialLoop < StandardError; end
)
"

# this query should not be used during distribution it is only intended for reporting usage
# selects both priority and non-priority appeals that are ready to distribute
SELECT_READY_TO_DISTRIBUTE_APPEALS_ORDER_BY_BFD19 = "
select APPEALS.BFKEY, APPEALS.TINUM, APPEALS.BFD19, APPEALS.BFDLOOUT,
case when APPEALS.BFAC = '7' or APPEALS.AOD = 1 then 1 else 0 end PRIORITY,
APPEALS.VLJ, APPEALS.PREV_DECIDING_JUDGE, APPEALS.HEARING_DATE, APPEALS.PREV_BFDDEC
from (
select BRIEFF.BFKEY, BRIEFF.TINUM, BFD19, BFDLOOUT, BFAC, AOD,
case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ
, PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE
, VLJ_HEARINGS.HEARING_DATE HEARING_DATE
, PREV_APPEAL.PREV_BFDDEC PREV_BFDDEC
from (
#{SELECT_READY_APPEALS}
) BRIEFF
#{JOIN_ASSOCIATED_VLJS_BY_HEARINGS}
#{JOIN_PREVIOUS_APPEALS}
order by BFD19
) APPEALS
"

# this query should not be used during distribution it is only intended for reporting usage
SELECT_READY_TO_DISTRIBUTE_APPEALS_ORDER_BY_BFD19_ADDITIONAL_COLS = "
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,
Expand All @@ -181,7 +217,50 @@ class DocketNumberCentennialLoop < StandardError; end
order by BFD19
"

FROM_LOC_63_APPEALS = "
from BRIEFF
#{VACOLS::Case::JOIN_AOD}
inner join FOLDER on FOLDER.TICKNUM = BRIEFF.BFKEY
where BRIEFF.BFCURLOC in ('63')
and BRIEFF.BFBOX is null
and BRIEFF.BFAC is not null
and BRIEFF.BFD19 is not null
"

SELECT_LOC_63_APPEALS = "
select BFKEY, BFD19, BFDLOCIN, BFCORLID, BFDLOOUT, BFMPRO, BFCORKEY, BFCURLOC, BFAC, BFHINES, TINUM, TITRNUM, AOD,
BFMEMID, BFDPDCN
#{FROM_LOC_63_APPEALS}
"

# rubocop:disable Metrics/MethodLength
SELECT_APPEALS_IN_LOCATION_63_FROM_PAST_2_DAYS = "
select APPEALS.BFKEY, APPEALS.TINUM, APPEALS.BFD19, APPEALS.BFMEMID, APPEALS.BFCURLOC,
APPEALS.BFDLOCIN, APPEALS.BFCORLID, APPEALS.BFDLOOUT,
case when APPEALS.BFAC = '7' or APPEALS.AOD = 1 then 1 else 0 end AOD,
case when APPEALS.BFAC = '7' then 1 else 0 end CAVC,
APPEALS.VLJ, APPEALS.PREV_DECIDING_JUDGE, APPEALS.HEARING_DATE, APPEALS.PREV_BFDDEC,
CORRES.SNAMEF, CORRES.SNAMEL, CORRES.SSN,
STAFF.SNAMEF as VLJ_NAMEF, STAFF.SNAMEL as VLJ_NAMEL
from (
select BRIEFF.BFKEY, BRIEFF.TINUM, BFD19, BFDLOOUT, BFAC, BFCORKEY, BFMEMID, BFCURLOC,
BRIEFF.BFDLOCIN, BFCORLID, AOD,
case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ
, PREV_APPEAL.PREV_DECIDING_JUDGE PREV_DECIDING_JUDGE
, VLJ_HEARINGS.HEARING_DATE HEARING_DATE
, PREV_APPEAL.PREV_BFDDEC PREV_BFDDEC
from (
#{SELECT_LOC_63_APPEALS}
) BRIEFF
#{JOIN_ASSOCIATED_VLJS_BY_HEARINGS}
#{JOIN_PREVIOUS_APPEALS}
where BRIEFF.BFDLOCIN >= CURRENT_DATE - 2
order by BFD19
) APPEALS
left join CORRES on APPEALS.BFCORKEY = CORRES.STAFKEY
left join STAFF on APPEALS.VLJ = STAFF.SATTYID
"

def self.counts_by_priority_and_readiness
query = <<-SQL
select count(*) N, PRIORITY, READY
Expand Down Expand Up @@ -416,7 +495,37 @@ def self.priority_ready_appeal_vacols_ids

def self.ready_to_distribute_appeals
query = <<-SQL
#{SELECT_READY_TO_DISTRIBUTE_APPEALS_ORDER_BY_BFD19_ADDITIONAL_COLS}
SQL

fmtd_query = sanitize_sql_array([query])
connection.exec_query(fmtd_query).to_a
end

def self.loc_63_appeals
query = <<-SQL
#{SELECT_APPEALS_IN_LOCATION_63_FROM_PAST_2_DAYS}
SQL

fmtd_query = sanitize_sql_array([query])
connection.exec_query(fmtd_query).to_a
end

def self.appeals_tied_to_non_ssc_avljs
query = <<-SQL
with non_ssc_avljs as (
#{VACOLS::Staff::NON_SSC_AVLJS}
)
#{SELECT_READY_TO_DISTRIBUTE_APPEALS_ORDER_BY_BFD19}
where APPEALS.VLJ in (select * from non_ssc_avljs)
and (
APPEALS.PREV_DECIDING_JUDGE is null or
(
APPEALS.PREV_DECIDING_JUDGE = APPEALS.VLJ
AND APPEALS.HEARING_DATE <= APPEALS.PREV_BFDDEC
)
)
order by BFD19
SQL

fmtd_query = sanitize_sql_array([query])
Expand Down
8 changes: 8 additions & 0 deletions app/models/vacols/staff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ class VACOLS::Staff < VACOLS::Record
scope :judge, -> { pure_judge.or(acting_judge) }
scope :attorney, -> { pure_attorney.or(acting_judge) }

NON_SSC_AVLJS = "
select sattyid
from staff
where sattyid <> smemgrp
and svlj = 'A'
and sactive = 'A'
"

def self.find_by_css_id(css_id)
find_by(sdomainid: css_id)
end
Expand Down
Loading

0 comments on commit 1c5aed1

Please sign in to comment.