diff --git a/client/COPY.json b/client/COPY.json index c34d38c33e3..911c8be8952 100644 --- a/client/COPY.json +++ b/client/COPY.json @@ -1410,13 +1410,13 @@ "EMPLOYER_IDENTIFICATION_NUMBER": "Employer Identification Number", "PACKAGE_ACTION_MERGE_DESCRIPTION": "By confirming, you will send a request for the supervisor to take action on the following package:", "PACKAGE_ACTION_MERGE_TITLE": "Request merge", - "PACKAGE_ACTION_MERGE_TEXTAREA_LABEL": "Select a reason for merging this package", + "PACKAGE_ACTION_MERGE_TEXTAREA_LABEL": "Reason for merge", "PACKAGE_ACTION_MERGE_RADIO_LABEL": "Select a reason for merging this package.", "PACKAGE_ACTION_MODAL_DESCRIPTION": "By confirming, you will send a request for the supervisor to take action on the following package:", "PACKAGE_ACTION_REMOVAL_TITLE": "Request package removal", "PACKAGE_ACTION_REMOVAL_TEXTAREA_LABEL": "Provide a reason for removal", "PACKAGE_ACTION_REASSIGN_DESCRIPTION":"You have selected the following correspondence cases for reassignment to another users. Please confirm your selection(s) below:", - "PACKAGE_ACTION_REASSIGN_TITLE":"Request package assignment", + "PACKAGE_ACTION_REASSIGN_TITLE":"Request package reassignment", "PACKAGE_ACTION_REASSIGN_TEXTAREA_LABEL":"Provide a reason for reassignment", "PACKAGE_ACTION_SPLIT_TEXTAREA_LABEL":"Reason for split", "PACKAGE_ACTION_SPLIT_TITLE": "Request split package", diff --git a/client/app/queue/correspondence/intake/components/ConfirmCorrespondence/ConfirmTasksRelatedToAnAppeal.jsx b/client/app/queue/correspondence/intake/components/ConfirmCorrespondence/ConfirmTasksRelatedToAnAppeal.jsx index cff61553e48..8e32582dd9a 100644 --- a/client/app/queue/correspondence/intake/components/ConfirmCorrespondence/ConfirmTasksRelatedToAnAppeal.jsx +++ b/client/app/queue/correspondence/intake/components/ConfirmCorrespondence/ConfirmTasksRelatedToAnAppeal.jsx @@ -13,7 +13,8 @@ const borderlessTd = { const ConfirmTasksRelatedToAnAppeal = () => { const tasks = useSelector((state) => state.intakeCorrespondence.newAppealRelatedTasks); - const taskIds = useSelector((state) => state.intakeCorrespondence.taskRelatedAppealIds); + const taskIds = useSelector((state) => state.intakeCorrespondence.taskRelatedAppealIds). + sort((first, second) => first - second); const fetchedAppeals = useSelector((state) => state.intakeCorrespondence.fetchedAppeals); const waivedEvidenceTasks = useSelector((state) => state.intakeCorrespondence.waivedEvidenceTasks); diff --git a/client/app/queue/correspondence/intake/components/TasksAppeals/AddAppealRelatedTaskView.jsx b/client/app/queue/correspondence/intake/components/TasksAppeals/AddAppealRelatedTaskView.jsx index 7cd11e744c4..68989009b90 100644 --- a/client/app/queue/correspondence/intake/components/TasksAppeals/AddAppealRelatedTaskView.jsx +++ b/client/app/queue/correspondence/intake/components/TasksAppeals/AddAppealRelatedTaskView.jsx @@ -119,7 +119,7 @@ export const AddAppealRelatedTaskView = (props) => { then((appealResponse) => { const appealsForStore = prepareAppealForStore(appealResponse.body.appeals); - const appealArr = Object.values(appealsForStore.appeals); + const appealArr = Object.values(appealsForStore.appeals).sort((first, second) => first.id - second.id); dispatch(setFetchedAppeals(appealArr)); setLoading(false); diff --git a/client/app/queue/correspondence/modals/PackageActionModal.jsx b/client/app/queue/correspondence/modals/PackageActionModal.jsx index 3dc0b6b9a42..32bc719b1a1 100644 --- a/client/app/queue/correspondence/modals/PackageActionModal.jsx +++ b/client/app/queue/correspondence/modals/PackageActionModal.jsx @@ -183,6 +183,7 @@ const PackageActionModal = (props) => { name={modalInfo.label} aria-label={modalInfo.label} value={textInputReason} + placeholder={modalInfo.placeholder} onChange={(value) => setTextInputReason(value)} /> )} diff --git a/client/app/queue/correspondence/review_package/utils.js b/client/app/queue/correspondence/review_package/utils.js index 42d72a8bf18..5ed0485602e 100644 --- a/client/app/queue/correspondence/review_package/utils.js +++ b/client/app/queue/correspondence/review_package/utils.js @@ -81,7 +81,7 @@ export const getPackageActionColumns = (dropdownType) => { ), valueFunction: (row) => { - const vaDate = moment(row.correspondence.va_date_of_receipt).format('MM/DD/YYYY'); + const vaDate = moment.utc(row.correspondence.va_date_of_receipt).format('MM/DD/YYYY'); return ( @@ -105,7 +105,8 @@ export const getModalInformation = (dropdownType) => { title: PACKAGE_ACTION_MERGE_TITLE, description: PACKAGE_ACTION_MERGE_DESCRIPTION, label: PACKAGE_ACTION_MERGE_TEXTAREA_LABEL, - radioLabel: PACKAGE_ACTION_MERGE_RADIO_LABEL + radioLabel: PACKAGE_ACTION_MERGE_RADIO_LABEL, + placeholder: 'This is a reason for merge', }; case 'removePackage': return { diff --git a/client/test/app/queue/correspondences/modals/PackageActionModal.test.js b/client/test/app/queue/correspondences/modals/PackageActionModal.test.js index ee33a287b41..286638abf00 100644 --- a/client/test/app/queue/correspondences/modals/PackageActionModal.test.js +++ b/client/test/app/queue/correspondences/modals/PackageActionModal.test.js @@ -65,7 +65,7 @@ describe('PackageActionModal rendering', () => { renderPackageActionModal('reassignPackage'); - expect(screen.getByText('Request package assignment')).toBeInTheDocument(); + expect(screen.getByText('Request package reassignment')).toBeInTheDocument(); expect(screen.getByText('Veteran Details')).toBeInTheDocument(); expect(screen.getByText('Provide a reason for reassignment')).toBeInTheDocument(); expect(screen.getByText(correspondenceData.cmp_packet_number.toString())).toBeInTheDocument(); diff --git a/lib/tasks/correspondence.rake b/lib/tasks/correspondence.rake index 41f252acc0f..945e857f875 100644 --- a/lib/tasks/correspondence.rake +++ b/lib/tasks/correspondence.rake @@ -69,13 +69,45 @@ namespace :correspondence do correspondence_types_list.each do |type| CorrespondenceType.find_or_create_by(name: type) end + end + + task :correspondences_with_multiple_documents, [] => :environment do |_| + @file_number ||= 500_000_000 + @participant_id ||= 850_000_000 + while Veteran.find_by(file_number: format("%09d", n: @file_number + 1)) + @file_number += 100 + @participant_id += 100 + end + + @cmp_packet_number ||= 1_000_000_000 + @cmp_packet_number += 10_000 while ::Correspondence.find_by(cmp_packet_number: @cmp_packet_number + 1) + create_correspondences_with_documents + end + + task :vbms_document_types, [] => :environment do |_| + create_document_types + end + + task :correspondence_types, [] => :environment do |_| + create_correspondence_types + end + + task :package_document_types, [] => :environment do |_| + create_package_document_types + end + + task :multi_correspondences, [] => :environment do |_| + @file_number ||= 550_000_000 + @participant_id ||= 650_000_000 + while Veteran.find_by(file_number: format("%09d", n: @file_number + 1)) + @file_number += 100 + @participant_id += 100 + end - # REVIEW: package seed data - Seeds::Correspondence.new.seed! # create correspondence records - Seeds::VbmsDocumentTypes.new.seed! # create vbms_document_type records - Seeds::CorrespondenceTypes.new.seed! # create correspondence_type records - Seeds::PackageDocumentTypes.new.seed! # create package_document_type records - Seeds::MultiCorrespondences.new.seed! # create multi_correspondences records + @cmp_packet_number ||= 2_000_000_000 + @cmp_packet_number += 10_000 while ::Correspondence.find_by(cmp_packet_number: @cmp_packet_number + 1) + RequestStore[:current_user] = User.find_by_css_id("BVADWISE") + create_multi_correspondences end desc "creates a 20 correspondence and correspondence_document for a veteran" @@ -158,3 +190,372 @@ namespace :correspondence do end end end + +def initial_id_values + @file_number ||= 500_000_000 + @participant_id ||= 850_000_000 + while Veteran.find_by(file_number: format("%09d", n: @file_number + 1)) + @file_number += 100 + @participant_id += 100 + end + + @cmp_packet_number ||= 1_000_000_000 + @cmp_packet_number += 10_000 while ::Correspondence.find_by(cmp_packet_number: @cmp_packet_number + 1) +end + +def create_veteran(options = {}) + @file_number += 1 + @participant_id += 1 + params = { + file_number: format("%09d", n: @file_number), + participant_id: format("%09d", n: @participant_id) + } + veteran = FactoryBot.create(:veteran, params.merge(options)) + 5.times do + FactoryBot.create(:appeal, veteran_file_number: veteran.file_number) + end + veteran +end + +# rubocop:disable Metrics/AbcSize, Metrics/MethodLength +def create_correspondences_with_documents + # correspondences with multiple documents + 10.times do + veteran = create_veteran + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: 15, + correspondence_type_id: 8, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "This is a note from CMP.", + assigned_by_id: 81, + veteran_id: veteran.id + ) + create_multiple_docs(corres, veteran) + @cmp_packet_number += 1 + end + + (1..77).each do |package_doc_id| + veteran = create_veteran + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: package_doc_id, + correspondence_type_id: 8, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "This is a note from CMP.", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end + + (1..24).each do |corres_type_id| + veteran = create_veteran + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: 15, + correspondence_type_id: corres_type_id, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "This is a note from CMP.", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end + + (1..17).each do |cmp_queue_id| + veteran = create_veteran + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: 15, + correspondence_type_id: 8, + cmp_queue_id: cmp_queue_id, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "This is a note from CMP.", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end +end + +def create_multiple_docs(corres, veteran) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + correspondence_id: corres.id, + document_type: 1250, + pages: 30, + vbms_document_type_id: 1250 + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + correspondence_id: corres.id, + document_type: 719, + pages: 20, + vbms_document_type_id: 719 + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + correspondence_id: corres.id, + document_type: 672, + pages: 10, + vbms_document_type_id: 672 + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + correspondence_id: corres.id, + document_type: 18, + pages: 5, + vbms_document_type_id: 18 + ) +end + +# Note: Remove after document controller is implemented +def create_static_documents + Document.create!(vbms_document_id: 3) + Document.create!(vbms_document_id: 4) +end + +def create_document_types + # Caseflow keeps track of VBMS Document Types at Caseflow::DocumentTypes::TYPES + # https://github.com/department-of-veterans-affairs/caseflow-commons/blob/master/app/models/caseflow/document_types.rb + + # if VbmsDocumentType table is not empty we should only add the document types we are missing (recently added) + # else the table is empty, so we should add all the document types + # This is implemented this way so that if a new document type is added to the module, + # we do not have to clear the table before running this seed file + + doc_types = [] + if VbmsDocumentType.count > 0 + doc_types = Caseflow::DocumentTypes::TYPES.reject { |key, _value| VbmsDocumentType.exists?(doc_type_id: key) } + else + Caseflow::DocumentTypes::TYPES.each do |key, _value| + doc_types << VbmsDocumentType.new(doc_type_id: key) + end + end + VbmsDocumentType.import(doc_types, validate: false) unless doc_types.empty? +end + +def create_correspondence_types + correspondence_types_list = + ["Abeyance", + "Attorney Inquiry", + "CAVC Correspondence", + "Change of address", + "Congressional interest", + "CUE related", + "Death certificate", + "Evidence or argument", + "Extension request", + "FOIA request", + "Hearing Postponement Request", + "Hearing related", + "Hearing Withdrawal Request", + "Advance on docket", + "Motion for reconsideration", + "Motion to vacate", + "Other motions", + "Power of attorney related", + "Privacy Act complaints", + "Privacy Act request", + "Returned as undeliverable mail", + "Status Inquiry", + "Thurber", + "Withdrawal of appeal"] + + correspondence_types_list.each do |type| + CorrespondenceType.find_or_create_by(name: type) + end +end + +def create_package_document_types + [ + "0304", "0779", "0781", "0781a", "0820a", "0820b", "0820c", "0820e", "0820f", "082d", "0966", "0995", "0996", + "10007", "10182", "1330", "1330m", "1900", "1905", "1905c", "1905m", "1995", "1999", "1999b", "21-22", + "21-22a", "247", "2680", "296", "4138", "4142", "4706b", "4706c", "4718a", "516", "518", "526", "526b", + "526c", "526ez", "527", "527EZ", "530", "530a", "535", "537", "5490", "5495", "601", "674", "674c", + "8049", "820", "8416", "8940", "BENE TRVL", "CH 31 APP", "CH36 APP", "CONG INQ", "CONSNT", + "DBQ", "Debt Dispute", "GRADES/DEGREE", "IU", "NOD", "OMPF", "PMR", "RAMP", "REHAB PLAN", "RFA", "RM", + "RNI", "SF180", "STR", "VA 9", "VCAA", "VRE INV" + ].each do |package_document_type| + PackageDocumentType.find_or_create_by(name: package_document_type) + end +end + +def create_correspondence_veteran(options = {}) + @file_number += 1 + @participant_id += 1 + params = { + file_number: format("%09d", n: @file_number), + participant_id: format("%09d", n: @participant_id) + } + FactoryBot.create(:veteran, params.merge(options)) +end + +def create_multi_correspondences + veteran = create_correspondence_veteran(first_name: "Adam", last_name: "West") + 5.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 5.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number, + docket_type: Constants.AMA_DOCKETS.direct_review + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 21.times do + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: (1..20).to_a.sample, + correspondence_type_id: 4, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "Notes from CMP - Multi Correspondence Seed", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end + + veteran = create_correspondence_veteran(first_name: "Michael", last_name: "Keaton") + 2.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 5.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number, + docket_type: Constants.AMA_DOCKETS.direct_review + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 31.times do + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: (1..20).to_a.sample, + correspondence_type_id: 4, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "Notes from CMP - Multi Correspondence Seed", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end + + veteran = create_correspondence_veteran(first_name: "Christian", last_name: "Bale") + 1.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 10.times do + appeal = FactoryBot.create( + :appeal, + veteran_file_number: veteran.file_number, + docket_type: Constants.AMA_DOCKETS.direct_review + ) + InitialTasksFactory.new(appeal).create_root_and_sub_tasks! + end + 101.times do + corres = ::Correspondence.create!( + uuid: SecureRandom.uuid, + portal_entry_date: Time.zone.now, + source_type: "Mail", + package_document_type_id: (1..20).to_a.sample, + correspondence_type_id: 4, + cmp_queue_id: 1, + cmp_packet_number: @cmp_packet_number, + va_date_of_receipt: Time.zone.yesterday, + notes: "Notes from CMP - Multi Correspondence Seed", + assigned_by_id: 81, + veteran_id: veteran.id + ) + CorrespondenceDocument.find_or_create_by( + document_file_number: veteran.file_number, + uuid: SecureRandom.uuid, + vbms_document_type_id: 1250, + document_type: 1250, + pages: 30, + correspondence_id: corres.id + ) + @cmp_packet_number += 1 + end +end diff --git a/spec/controllers/explain_controller_spec.rb b/spec/controllers/explain_controller_spec.rb index 3dc838edb54..d220d6a4d03 100644 --- a/spec/controllers/explain_controller_spec.rb +++ b/spec/controllers/explain_controller_spec.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require "helpers/sanitized_json_configuration.rb" -require "helpers/sanitized_json_exporter.rb" -require "helpers/intake_renderer.rb" -require "helpers/hearing_renderer.rb" +require "helpers/sanitized_json_configuration" +require "helpers/sanitized_json_exporter" +require "helpers/intake_renderer" +require "helpers/hearing_renderer" describe ExplainController, :all_dbs, type: :controller do include TaskHelpers @@ -166,7 +166,11 @@ ) end - subject { get :show, params: { correspondence_uuid: correspondence.uuid, any: "review_package" }, as: response_format } + subject do + get :show, + params: { correspondence_uuid: correspondence.uuid, any: "review_package" }, + as: response_format + end before do User.authenticate!(roles: user_roles) diff --git a/spec/feature/queue/correspondence/edit_cmp_information_spec.rb b/spec/feature/queue/correspondence/edit_cmp_information_spec.rb index db3619bfd4c..3c2f05089d3 100644 --- a/spec/feature/queue/correspondence/edit_cmp_information_spec.rb +++ b/spec/feature/queue/correspondence/edit_cmp_information_spec.rb @@ -85,7 +85,7 @@ it "modal opens with disabled confirm button" do expect(page).to have_content( - "You have selected the following correspondence cases for reassignment to another user. Please confirm your selection(s) below:" + "You have selected the following correspondence cases for reassignment to another users. Please confirm your selection(s) below:" ) expect(page).to have_button("Confirm request", disabled: true) end