diff --git a/Gemfile b/Gemfile index 0b6822d2c27..ac9d8563f66 100644 --- a/Gemfile +++ b/Gemfile @@ -10,14 +10,14 @@ gem "acts_as_tree" # amoeba gem for cloning appeals gem "amoeba" -gem "aws-sdk" # BGS + gem "bgs", git: "https://github.com/department-of-veterans-affairs/ruby-bgs.git", ref: "a2e055b5a52bd1e2bb8c2b3b8d5820b1a404cd3d" # Bootsnap speeds up app boot (and started to be a default gem in 5.2). gem "bootsnap", require: false gem "browser" gem "business_time", "~> 0.9.3" -gem "caseflow", git: "https://github.com/department-of-veterans-affairs/caseflow-commons", ref: "716b58caf2116da5fca21c3b3aeea6c9712f3b9d" +gem "caseflow", git: "https://github.com/department-of-veterans-affairs/caseflow-commons", ref: "871f7034c502f8d7101bde74e58606716b601c70" gem "connect_mpi", git: "https://github.com/department-of-veterans-affairs/connect-mpi.git", ref: "a3a58c64f85b980a8b5ea6347430dd73a99ea74c" gem "connect_vbms", git: "https://github.com/department-of-veterans-affairs/connect_vbms.git", ref: "9807d9c9f0f3e3494a60b6693dc4f455c1e3e922" gem "console_tree_renderer", git: "https://github.com/department-of-veterans-affairs/console-tree-renderer.git", tag: "v0.1.1" @@ -66,8 +66,6 @@ gem "redis-namespace" gem "redis-rails", "~> 5.0.2" gem "request_store" gem "roo", "~> 2.7" -gem "rswag-api" -gem "rswag-ui" # Use SCSS for stylesheets gem "sass-rails", "~> 5.0" # Error reporting to Sentry @@ -116,7 +114,6 @@ group :test, :development, :demo do gem "rspec-rails" # For CircleCI test metadata analysis gem "rspec_junit_formatter" - gem "rswag-specs" gem "rubocop", "= 0.83", require: false gem "rubocop-performance" gem "rubocop-rails" diff --git a/Gemfile.lock b/Gemfile.lock index 82df5ebe5a5..c230058e4ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,11 +9,11 @@ GIT GIT remote: https://github.com/department-of-veterans-affairs/caseflow-commons - revision: 716b58caf2116da5fca21c3b3aeea6c9712f3b9d - ref: 716b58caf2116da5fca21c3b3aeea6c9712f3b9d + revision: 871f7034c502f8d7101bde74e58606716b601c70 + ref: 871f7034c502f8d7101bde74e58606716b601c70 specs: caseflow (0.4.8) - aws-sdk-s3 + aws-sdk (~> 3.2) bourbon (= 4.2.7) d3-rails jquery-rails @@ -1642,8 +1642,6 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.3.0) - json-schema (4.3.0) - addressable (>= 2.8) json_schemer (0.2.16) ecma-re-validator (~> 0.2) hana (~> 1.3) @@ -1870,17 +1868,6 @@ GEM rspec-support (3.9.2) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rswag-api (2.13.0) - activesupport (>= 3.1, < 7.2) - railties (>= 3.1, < 7.2) - rswag-specs (2.13.0) - activesupport (>= 3.1, < 7.2) - json-schema (>= 2.2, < 5.0) - railties (>= 3.1, < 7.2) - rspec-core (>= 2.14) - rswag-ui (2.13.0) - actionpack (>= 3.1, < 7.2) - railties (>= 3.1, < 7.2) rubocop (0.83.0) parallel (~> 1.10) parser (>= 2.7.0.1) @@ -2035,7 +2022,6 @@ DEPENDENCIES acts_as_tree amoeba anbt-sql-formatter - aws-sdk bgs! bootsnap brakeman @@ -2106,9 +2092,6 @@ DEPENDENCIES rspec-rails rspec-retry rspec_junit_formatter - rswag-api - rswag-specs - rswag-ui rubocop (= 0.83) rubocop-performance rubocop-rails @@ -2139,4 +2122,4 @@ DEPENDENCIES ziptz BUNDLED WITH - 2.4.17 + 2.4.19 diff --git a/Makefile.example b/Makefile.example index e27b6efcb99..100939c2b65 100644 --- a/Makefile.example +++ b/Makefile.example @@ -135,9 +135,6 @@ destroy: clean lint: ## Run linter for javascript and ruby bundle exec rake lint -rubocop: ## Run linter for ruby - bundle exec rake rubocop -a - jslint: ## Run linter for javascript cd client && yarn run lint diff --git a/app/controllers/api/application_controller.rb b/app/controllers/api/application_controller.rb index ea12981e0fc..0abbd85f544 100644 --- a/app/controllers/api/application_controller.rb +++ b/app/controllers/api/application_controller.rb @@ -92,14 +92,4 @@ def upstream_known_error(error) ] }, status: error.code || :bad_request end - - def endpoint_disabled(message) - result = { - uuid: SecureRandom.uuid, - code: "VEFSERR50102", - message: "Operation not enabled. #{message}" - } - - render json: result, status: :not_implemented - end end diff --git a/app/controllers/swagger/idt/swagger.yaml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml similarity index 98% rename from app/controllers/swagger/idt/swagger.yaml rename to app/controllers/api/docs/pacman/idt-pacman-spec.yml index 57f3b2c24fb..88d49d05851 100644 --- a/app/controllers/swagger/idt/swagger.yaml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -1,4 +1,3 @@ ---- openapi: 3.0.2 info: title: IDT-Caseflow-Package Manager Bridge API @@ -11,12 +10,13 @@ info: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 version: 1.0.0 -security: - - bearerAuth: [] servers: -- url: / +- url: https://appeals.cf.uat.ds.va.gov + description: UAT/Staging server +- url: http://localhost:3000 + description: Local Development server paths: - /addresses/validate: + /idt/api/v1/addresses/validate: post: tags: - Address Validation @@ -93,8 +93,7 @@ paths: - servers: - - url: /idt/api/v1/ + requestBody: content: application/json: @@ -171,17 +170,14 @@ paths: type: string example: message: 'Lighthouse API Error ID: 322483ae-7953-4d3c-9738-e108506d52c2 An unexpected error occurred, please try again.' - /appeals/{appeal_id}/upload_document: + /idt/api/v1/appeals/{appeal_id}/upload_document: post: tags: - Document Posting summary: Used for uploading documents to eFolder for specific appeals/veterans - servers: - - url: /idt/api/v1/ parameters: - in: path name: appeal_id - example: cc165d4f-1e16-4bcf-9134-4f864c121c97 schema: type: string required: true @@ -399,13 +395,11 @@ paths: message: type: string example: "Unexpected error: job error" - /upload_document: + /idt/api/v1/upload_document: post: tags: - Document Posting summary: Used for uploading documents to eFolder for specific appeals/veterans - servers: - - url: /idt/api/v1/ requestBody: content: application/json: @@ -623,17 +617,14 @@ paths: errors: "distribution 1": "Address line 3 can't be blank" - /appeals/{appeal_id}/outcode: + /idt/api/v2/appeals/{appeal_id}/outcode: post: tags: - Document Posting summary: Route used for outcoding decision reviews - servers: - - url: /idt/api/v2/ parameters: - in: path name: appeal_id - example: cc165d4f-1e16-4bcf-9134-4f864c121c97 schema: type: string required: true @@ -885,17 +876,14 @@ paths: detail: type: string example: "The veteran file number does not match the file number in VBMS" - /distributions/{distribution_id}: + /idt/api/v2/distributions/{distribution_id}: get: tags: - Distribution Tracking summary: Queries Package Manager for information on a specified distribution. - servers: - - url: /idt/api/v2/ parameters: - in: path name: distribution_id - example: 1234 schema: type: string required: true @@ -1379,7 +1367,7 @@ components: type: number format: double securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow + ApiKeyAuth: + type: apiKey + in: header + name: TOKEN diff --git a/app/controllers/swagger/v3/ama_issues.yaml b/app/controllers/api/docs/v3/ama_issues.yaml similarity index 99% rename from app/controllers/swagger/v3/ama_issues.yaml rename to app/controllers/api/docs/v3/ama_issues.yaml index 65d8ae75fad..9b0823c3a5f 100644 --- a/app/controllers/swagger/v3/ama_issues.yaml +++ b/app/controllers/api/docs/v3/ama_issues.yaml @@ -34,12 +34,10 @@ info: ``` version: 3.0.0 -security: - - bearerAuth: [] servers: -- url: /api/v3/issues/ama/ + - url: '{{CaseflowInstance}}/api/v3/ama_issues' paths: - /find_by_veteran/{veteran_participant_id}: + /api/v3/issues/ama/find_by_veteran/{veteran_participant_id}: get: tags: - Request Issues @@ -48,7 +46,6 @@ paths: in: path required: true description: Veteran Participant ID - example: 123456789 schema: $ref: "#/components/schemas/VeteranParticipantId" - in: query @@ -534,8 +531,3 @@ components: updated_at: type: string description: "The date and time the record was updated" - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/swagger/v3/decision_reviews.yaml b/app/controllers/api/docs/v3/decision_reviews.yaml similarity index 98% rename from app/controllers/swagger/v3/decision_reviews.yaml rename to app/controllers/api/docs/v3/decision_reviews.yaml index adf15df4441..580cbc2fc69 100644 --- a/app/controllers/swagger/v3/decision_reviews.yaml +++ b/app/controllers/api/docs/v3/decision_reviews.yaml @@ -32,10 +32,8 @@ info: ``` version: 3.0.0 -security: - - bearerAuth: [] servers: -- url: /api/v3/decision_reviews/ + - url: '{{CaseflowInstance}}/api/v3/decision_reviews' paths: /higher_level_reviews: post: @@ -47,7 +45,7 @@ paths: ### Asynchronous processing - The Decision Reviews API leverages a pattern recommended by JSON API for asynchronous processing (more information [here](https://jsonapi.org/recommendations/#asynchronous-processing)). Submitting a Decision Review is an asynchronous process due to the multiple systems that are involved. Because of this, when a new Decision Review is submitted, the POST endpoint will return a 202 `accepted` response including an Intake UUID. That Intake UUID is associated with the submission and can be used as an identifier for the Intake Status endpoint. While the submission is processing the Intake Status endpoint will return a 200 response. Once the asynchronous process is complete and the Decision Review is submitted into Caseflow, the Intake Status endpoint will return a 303 response including the Decision Review ID for the submitted Decision Review, which will allow you to retrieve the full details including the processing status. + The Decision Reviews API leverages a pattern recommended by JSON API for asynchronous processing (more information [here](https://jsonapi.org/recommendations/#asynchronous-processing)). Submitting a Decision Review is an asynchronous process due to the multiple systems that are involved. Because of this, when a new Decision Review is submitted, the POST endpoint will return a 202 `accepted` response including an Intake UUID. That Intake UUID is associated with the submission and can be used as an identifier for the Intake Status endpoint. While the submission is processing the Intake Status endpoint will return a 200 response. Once the asynchronous process is complete and the Decision Review is submitted into Caseflow, the Intake Status endpoint will return a 303 response including the Decision Review ID for the submitted Decision Review, which will allow you to retrieve the full details including the processing status. requestBody: required: true content: @@ -474,7 +472,6 @@ paths: in: path required: true description: Decision Review UUID - example: cc165d4f-1e16-4bcf-9134-4f864c121c97 schema: $ref: "#/components/schemas/Uuid" summary: Check a Decision Review's (Higher-Level Review, Supplemental Claim, Board Appeal) intake status. @@ -482,7 +479,7 @@ paths: After creating a Decision Review, you can use this endpoint to check its _intake status_—whether or not a Decision Review has been processed in the Caseflow system. - **A Decision Review is not immediately accessible after creation.** Intake involves communicating with several systems/databases asynchronously. Consequently, a new Decision Review isn't available for API interaction immediately after creation. + **A Decision Review is not immediately accessible after creation.** Intake involves communicating with several systems/databases asynchronously. Consequently, a new Decision Review isn't available for API interaction immediately after creation. _Check a Decision Review's intake status to know when it has become accessible, and also its location for further actions._ @@ -491,7 +488,7 @@ paths: * **Before a Decision Review is successfully processed:** This endpoint will return `200 OK` and a JSON payload describing the status in more detail. - * **Once processing is complete:** this endpoint will return a `303 see other` and a Location header containing the URL of the processed, and now accessible, Decision Review. You can use that URL to get the Decision Review and retrieve its full details. + * **Once processing is complete:** this endpoint will return a `303 see other` and a Location header containing the URL of the processed, and now accessible, Decision Review. You can use that URL to get the Decision Review and retrieve its full details. responses: '200': description: Processing incomplete @@ -583,6 +580,7 @@ paths: status: 500, code: unknown_error title: "Unknown error" + /higher_level_reviews/{uuid}: get: tags: @@ -592,7 +590,6 @@ paths: in: path required: true description: UUID of a Higher-Level Review - example: cc165d4f-1e16-4bcf-9134-4f864c121c97 schema: type : string format: uuid @@ -929,14 +926,9 @@ paths: in: header required: true description: (yyyy-mm-dd) In order to determine contestability of issues, the receipt date of a hypothetical Decision Review must be supplied. - example: '2000-01-01' schema: type: string format: date - servers: - - url: /api/v3/decision_reviews/higher_level_reviews/ - - url: /api/v3/decision_reviews/supplemental_claims/ - - url: /api/v3/decision_reviews/appeals/ summary: Returns all contestable issues for a specific veteran. description: >- Returns all issues a Veteran could contest in a Decision Review @@ -1422,8 +1414,3 @@ components: * `attempted` - Processing of the DecisionReview is being attempted. * `canceled` - The DecisionReview has been successfully canceled. * `processed` - The DecisionReview has been processed and transmitted to the appropriate government agency. - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/swagger/v3/vacols_issues.yaml b/app/controllers/api/docs/v3/vacols_issues.yaml similarity index 98% rename from app/controllers/swagger/v3/vacols_issues.yaml rename to app/controllers/api/docs/v3/vacols_issues.yaml index c158d30190a..d73baa09c93 100644 --- a/app/controllers/swagger/v3/vacols_issues.yaml +++ b/app/controllers/api/docs/v3/vacols_issues.yaml @@ -33,12 +33,10 @@ info: ``` version: 3.0.0 -security: - - bearerAuth: [] servers: -- url: /api/v3/issues/vacols/ + - url: '{{CaseflowInstance}}/api/v3/issues/vacols' paths: - /find_by_veteran: + /api/v3/issues/vacols/find_by_veteran: get: tags: - VACOLS Issues @@ -274,8 +272,3 @@ components: issue_note: type: string description: "Notes added to the VACOLS Issue. This may be used to capture handwritten notes on the form, New Material or other comments." - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/api/v1/cmp_controller.rb b/app/controllers/api/v1/cmp_controller.rb deleted file mode 100644 index 45cdb5f423c..00000000000 --- a/app/controllers/api/v1/cmp_controller.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::CmpController < Api::ApplicationController - def upload - endpoint_disabled("Payload is valid: #{validate_payload?}") - rescue StandardError => error - raise error - end - - private - - def upload_params - params.permit(:payload, file: []) - end - - def validate_payload? - payload = JSON.parse(upload_params[:payload]) - - validate_provider_data?(payload["providerData"]) if payload.present? - end - - def validate_provider_data?(provider_data) - return false if provider_data.blank? - - Rails.logger.info("provider data is #{provider_data}") - true - end -end diff --git a/app/controllers/explain_controller.rb b/app/controllers/explain_controller.rb index c1fb2b6ae2a..d534d02cd31 100644 --- a/app/controllers/explain_controller.rb +++ b/app/controllers/explain_controller.rb @@ -36,7 +36,7 @@ def access_allowed? Rails.env.development? end - helper_method :legacy_appeal?, :appeal, :appeal_affinity, + helper_method :legacy_appeal?, :appeal, :show_pii_query_param, :fields_query_param, :sections_query_param, :treee_fields, :enabled_sections, :available_fields, @@ -147,14 +147,6 @@ def appeal @appeal ||= fetch_appeal end - def appeal_affinity - @appeal_affinity ||= if legacy_appeal? - VACOLS::Case.find_by(bfkey: appeal.vacols_id)&.appeal_affinity - else - appeal.appeal_affinity - end - end - def fetch_appeal if appeal_id.start_with?("ama-") record_id = appeal_id.delete_prefix("ama-") diff --git a/app/controllers/route_docs_controller.rb b/app/controllers/route_docs_controller.rb index 99df04daf33..cc296ade099 100644 --- a/app/controllers/route_docs_controller.rb +++ b/app/controllers/route_docs_controller.rb @@ -57,9 +57,7 @@ def controller_klass def index all_routes = Rails.application.routes.routes.map(&method(:documented_route)) - @routes = all_routes.compact - .filter { |route| route.schema.present? } - .sort_by { |rt| [(rt.schema.present? ? 0 : 1), rt.path] } + @routes = all_routes.compact.sort_by { |rt| [(rt.schema.present? ? 0 : 1), rt.path] } end private diff --git a/app/controllers/swagger/cmp/swagger.yaml b/app/controllers/swagger/cmp/swagger.yaml deleted file mode 100644 index 82d99a12fce..00000000000 --- a/app/controllers/swagger/cmp/swagger.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -openapi: 3.0.2 -info: - title: API V1 - version: v1 -security: - - bearerAuth: [] -servers: -- url: /api/v1/ -paths: - "/cmp": - $ref: "./v1/upload.yml" -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow - schemas: - payload: - $ref: "./v1/payload.yml" diff --git a/app/controllers/swagger/cmp/v1/baseErrorResponse.yml b/app/controllers/swagger/cmp/v1/baseErrorResponse.yml deleted file mode 100644 index 2b918162439..00000000000 --- a/app/controllers/swagger/cmp/v1/baseErrorResponse.yml +++ /dev/null @@ -1,15 +0,0 @@ -type: object -title: Vefs Error Response -description: The root schema comprises generic File Store Errors. -examples: - - uuid: d1abad83-5468-4031-b42a-c487e19f46c7 - code: VEFSERR0000 - message: Unable to create valid response. -properties: - uuid: - type: string - format: uuid - title: Error UUID - description: UUID used to trace the error response - examples: - - d1abad83-5468-4031-b42a-c487e19f46c7 \ No newline at end of file diff --git a/app/controllers/swagger/cmp/v1/contentName.yml b/app/controllers/swagger/cmp/v1/contentName.yml deleted file mode 100644 index acf394c9efe..00000000000 --- a/app/controllers/swagger/cmp/v1/contentName.yml +++ /dev/null @@ -1,7 +0,0 @@ -type: string -title: Content Name -description: The content name of the document being uploaded. This must be unique for the folder being uploaded to. For instance the document "pdf.pdf" cannot be uploaded twice for fileNumber 987654321. The acceptable file extensions are png, pdf, tif, tiff, txt, jpg, jpeg, and bmp. -minLength: 4 -maxLength: 256 -pattern: "^[a-zA-Z0-9 Q`'~=+#^@$&-_.(){};[]E]+.[a-zA-Z]{3,4}$" -example: filename.pdf \ No newline at end of file diff --git a/app/controllers/swagger/cmp/v1/noApiKeyResponse.yml b/app/controllers/swagger/cmp/v1/noApiKeyResponse.yml deleted file mode 100644 index 03810b86584..00000000000 --- a/app/controllers/swagger/cmp/v1/noApiKeyResponse.yml +++ /dev/null @@ -1,13 +0,0 @@ -type: object -title: Vefs No/Invalid API Key Error Response -description: Error response when no or invalid API Key is present on the request -properties: - messages: - type: array - items: - type: object - properties: - status: - type: string - enum: - - "unauthorized" diff --git a/app/controllers/swagger/cmp/v1/payload.yml b/app/controllers/swagger/cmp/v1/payload.yml deleted file mode 100644 index a61aaffda05..00000000000 --- a/app/controllers/swagger/cmp/v1/payload.yml +++ /dev/null @@ -1,11 +0,0 @@ -type: object -title: Upload Payload -description: Payload containing content name and the provider specific data. Schema can be found here. -required: - - contentName - - providerData -properties: - contentName: - $ref: './contentName.yml' - providerData: - $ref: './uploadProviderDataRequest.yml' diff --git a/app/controllers/swagger/cmp/v1/upload.yml b/app/controllers/swagger/cmp/v1/upload.yml deleted file mode 100644 index cf9dc40aa83..00000000000 --- a/app/controllers/swagger/cmp/v1/upload.yml +++ /dev/null @@ -1,78 +0,0 @@ -post: - tags: - - File - summary: Upload a file with associated provider data - description: |- - ### Upload a file. - This endpoint when given a file and associated data returns a UUID which is a reference to the created object within Caseflow. Information on how to properly create a payload object for this endpoint is available in the schema section here. (Upload Payload) - operationId: upload - parameters: - - name: X-Folder-URI - in: header - description: >- - This should have a value of BIN:NAME:Caseflow - required: true - schema: - type: string - example: 'BIN:NAME:Caseflow ' - requestBody: - required: true - content: - multipart/form-data: # Media type - schema: # Request payload - $ref: './uploadRequest.yml' - responses: - '200': - description: >- - Response containing the Correspondence package UUID - content: - application/json: - schema: - $ref: './uploadResponse.yml' - '400': - description: Server was unable to understand the request. This may come back as an empty response if the json is malformed or not understood by the server. - content: - application/json: - schema: - oneOf: - - $ref: './vefsErrorCodes.yml#/components/schemas/INVALID_REQUEST' - - $ref: './vefsErrorCodes.yml#/components/schemas/DOES_NOT_CONFORM_TO_SCHEMA' - - $ref: './vefsErrorCodes.yml#/components/schemas/VALIDATE_INVALID_VALUE' - - $ref: './vefsErrorCodes.yml#/components/schemas/DUPLICATE_PROVIDERDATA_KEYS' - '401': - description: API Key does not exist or is not authorized to access the resource. - content: - application/json: - schema: - $ref: './noApiKeyResponse.yml' - '415': - description: Unsupported Media Type. This is common when uploading an unacceptable file type. - content: - application/json: - schema: - oneOf: - - $ref: './vefsErrorCodes.yml#/components/schemas/INVALID_MIMETYPE' - - $ref: './vefsErrorCodes.yml#/components/schemas/WRONG_MIMETYPE_EXTENSION' - '500': - description: >- - There was an error encountered processing the Request. Response - will contain a "messages" element that will provide further - information on the error. Please retry. If problem persists, - please contact support with a copy of the Response. - content: - application/json: - schema: - oneOf: - - $ref: './vefsErrorCodes.yml#/components/schemas/UNABLE_TO_DETERMINE_MIMETYPE' - - $ref: './vefsErrorCodes.yml#/components/schemas/UNABLE_TO_UPLOAD_DATA' - - $ref: './vefsErrorCodes.yml#/components/schemas/UNABLE_TO_PERSIST_DATA' - - $ref: './vefsErrorCodes.yml#/components/schemas/UNABLE_TO_CONVERT' - - $ref: './vefsErrorCodes.yml#/components/schemas/UNKNOWN_ERROR' - - $ref: './vefsErrorCodes.yml#/components/schemas/JSON_DESERIALIZATION' - - $ref: './vefsErrorCodes.yml#/components/schemas/JSON_SERIALIZATION' - '501': - description: This endpoint is not enabled. - content: - application/json: - schema: - $ref: './vefsErrorCodes.yml#/components/schemas/OPERATION_NOT_ENABLED' diff --git a/app/controllers/swagger/cmp/v1/uploadProviderDataRequest.yml b/app/controllers/swagger/cmp/v1/uploadProviderDataRequest.yml deleted file mode 100644 index cca8a8b8ef2..00000000000 --- a/app/controllers/swagger/cmp/v1/uploadProviderDataRequest.yml +++ /dev/null @@ -1,79 +0,0 @@ -type: object -title: Upload / Update Provider Data -description: Claim Evidence API Provider Data. -required: - - claimantFirstName - - claimantLastName - - documentTypeId - - dateVaReceivedDocument -properties: - contentSource: - title: Document content source - description: String field designating the originating source of the content being uploaded. - type: string - minimum: 1 - maximum: 500 - pattern: "^[a-zA-Z0-9\\'\\,\\s.\\-\\_\\|\\/@\\(\\)]*$" - example: VBMS - claimantFirstName: - title: Claimant First Name - description: String field designating the Claimant's first name. - type: string - maxLength: 64 - pattern: ^[a-zA-Z0-9\\'\\,\\s.\\-\\_\\|\\/@\\(\\)]*$ - example: John - claimantMiddleInitial: - title: Claimant Middle Initial - description: String field designating the Claimant's middle initial. - type: string - maxLength: 4 - pattern: ^[a-zA-Z]*$ - example: M - claimantLastName: - title: Claimant Last Name - description: String field designating the Claimant's last name. - type: string - maxLength: 64 - pattern: ^[a-zA-Z0-9\\'\\,\\s.\\-\\_\\|\\/@\\(\\)]*$ - example: Smith - claimantSsn: - title: Claimant SSN - description: String field designating the Claimant's SSN. Only accepts exactly 9 characters. - type: string - maxLength: 9 - pattern: ^[0-9]*$ - example: 123456789 - documentTypeId: - title: Document Type ID - description: Number field correlating to a Claim Evidence document type ID. Document types primary use is loosely categorizing their contents. - type: integer - minimum: 1 - example: 131 - dateVaReceivedDocument: - title: Date VA Received Document - description: Date field indicating the date the VA received the document. This can be any date in format of YYYY-MM-DD from 1900 until today - type: string - format: string - maxLength: 10 - minLength: 10 - minDate: 1900-01-01 - maxDate: today - pattern: "([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))" - example: 2022-02-01 - subject: - type: string - title: Subject - description: Free text describing the document. This is primarily notes used to - assist claim developers. - maxLength: 256 - pattern: ^[a-zA-Z0-9\s.\-_|\Q\\E@#~=%,;?!'"`():$+*^\[\]&<>{}\Q/\E]*$ - example: subject - claimantParticipantId: - title: Claimant Participant Id - description: String field designating the claimant participant Id. - type: string - maxLength: 15 - pattern: ^[0-9]*$ - example: '000000000' -additionalProperties: false - diff --git a/app/controllers/swagger/cmp/v1/uploadRequest.yml b/app/controllers/swagger/cmp/v1/uploadRequest.yml deleted file mode 100644 index 91643392c53..00000000000 --- a/app/controllers/swagger/cmp/v1/uploadRequest.yml +++ /dev/null @@ -1,15 +0,0 @@ -type: object -title: Upload Request -description: Upload request containing the file binary and upload payload data -required: - - payload - - file[] -properties: - payload: - $ref: './payload.yml' - 'file[]': - description: Array of files to be uploaded - type: array - items: - type: string - format: binary diff --git a/app/controllers/swagger/cmp/v1/uploadResponse.yml b/app/controllers/swagger/cmp/v1/uploadResponse.yml deleted file mode 100644 index 6649939fd28..00000000000 --- a/app/controllers/swagger/cmp/v1/uploadResponse.yml +++ /dev/null @@ -1,9 +0,0 @@ -type: object -title: Upload Response -properties: - uuid: - type: string - description: >- - UUID representing the package as a whole. This is used for all primary Caseflow Correspondence operations. - format: uuid - example: c30626c9-954d-4dd1-9f70-1e38756d9d97 diff --git a/app/controllers/swagger/cmp/v1/vefsErrorCodes.yml b/app/controllers/swagger/cmp/v1/vefsErrorCodes.yml deleted file mode 100644 index 9a303f12043..00000000000 --- a/app/controllers/swagger/cmp/v1/vefsErrorCodes.yml +++ /dev/null @@ -1,226 +0,0 @@ -components: - schemas: - DOES_NOT_CONFORM_TO_SCHEMA: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR40001 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - null -# ", , 400), - VALIDATE_INVALID_VALUE: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR40003 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - 'Key: %s contained invalid value(s) %s' -# ", "", 400), - DUPLICATE_PROVIDERDATA_KEYS: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR40002 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - 'Duplicate key: providerData contained duplicate keys %s' -# ", "", 400), - INVALID_MIMETYPE: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR41501 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - 'File binary content contained magic bytes indicates mime type: %s which does not match accepted mime types: %s' -# ", "", 415), - WRONG_MIMETYPE_EXTENSION: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR41502 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - 'File binary content contained magic bytes indicates mime type: %s which does not match filename extension: %s' -# ", "", 415), - INVALID_REQUEST: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR40010 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Invalid request data. -# ", "", 400), - UNABLE_TO_DETERMINE_MIMETYPE: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50001 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - 'File binary content''s mime type was unable to be determined. Accepted Type(s): %s' -# ", "", 500), - OPERATION_NOT_ENABLED: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50102 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Operation not enabled. -# ", "", 501), - UNABLE_TO_PERSIST_DATA: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50003 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Unknown error encountered saving data. -# ", "", 500), - UNABLE_TO_UPLOAD_DATA: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50004 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Unknown error encountered uploading data. -# ", "", 500), - JSON_SERIALIZATION: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50010 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - JSON serialization error. -# ", "", 500), - JSON_DESERIALIZATION: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50011 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - JSON deserialization error. -# ", "", 500), - UNKNOWN_ERROR: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50009 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Unknown system error occurred. -# ", "", 500), - UNABLE_TO_CONVERT: - allOf: - - $ref: './baseErrorResponse.yml' - - type: object - properties: - code: - type: string - enum: - - VEFSERR50012 - message: - type: string - title: The message schema - description: The message describing the error. - enum: - - Unable to convert document from mime type %s to mime type %s -# ", "", 500), diff --git a/app/controllers/swagger/v1/swagger.yaml b/app/controllers/swagger/v1/swagger.yaml deleted file mode 100644 index 013ea3988d4..00000000000 --- a/app/controllers/swagger/v1/swagger.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -openapi: 3.0.2 -info: - title: API V1 - version: v1 -security: - bearerAuth: [] -servers: -- url: "/api/v1" -paths: {} -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/swagger/v2/swagger.yaml b/app/controllers/swagger/v2/swagger.yaml deleted file mode 100644 index 6af6e2a176c..00000000000 --- a/app/controllers/swagger/v2/swagger.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -openapi: 3.0.2 -info: - title: API V2 - version: V2 -security: - bearerAuth: [] -servers: -- url: "/api/v2" -paths: - "/api/v2/appeals": - get: - summary: list appeals - responses: - '200': - description: successful -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/swagger/v3/swagger.yaml b/app/controllers/swagger/v3/swagger.yaml deleted file mode 100644 index 4853574fc7e..00000000000 --- a/app/controllers/swagger/v3/swagger.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -openapi: 3.0.2 -info: - title: API V3 - version: V3 -security: - bearerAuth: [] -servers: -- url: "/api/v3" -paths: {} -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - description: API Key provided by Caseflow diff --git a/app/controllers/test/users_controller.rb b/app/controllers/test/users_controller.rb index b54a53fb0d2..50e3a082410 100644 --- a/app/controllers/test/users_controller.rb +++ b/app/controllers/test/users_controller.rb @@ -65,8 +65,7 @@ class Test::UsersController < ApplicationController admin: "/admin", test_veterans: "/test/data", metrics_dashboard: "/metrics/dashboard", - case_distribution_dashboard: "/acd-controls/test", - swagger: "/api-docs" + case_distribution_dashboard: "/acd-controls/test" } } ].freeze diff --git a/app/jobs/ama_notification_efolder_sync_job.rb b/app/jobs/ama_notification_efolder_sync_job.rb index bbf9b6db122..a015cdbcb3d 100644 --- a/app/jobs/ama_notification_efolder_sync_job.rb +++ b/app/jobs/ama_notification_efolder_sync_job.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class AmaNotificationEfolderSyncJob < CaseflowJob - include MessageConfigurations::DeleteMessageBeforeStart - queue_with_priority :low_priority BATCH_LIMIT = ENV["AMA_NOTIFICATION_REPORT_SYNC_LIMIT"] || 500 diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index f72a18f3a4a..7b06c649ed4 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -5,17 +5,6 @@ class ApplicationJob < ActiveJob::Base class InvalidJobPriority < StandardError; end - # Override in job classes if you anticipate that the job will take longer than the SQS visibility - # timeout value (ex: currently 5 hours for our low priority queue at the time of writing this) - # to prevent multiple instances of the job from being executed. - # - # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html - DELETE_SQS_MESSAGE_BEFORE_START = false - - # For jobs that run multiple times in a short time span, we do not want to continually update - # the JobsExecutionTime table. This boolean will help us ignore those jobs - IGNORE_JOB_EXECUTION_TIME = false - class << self def queue_with_priority(priority) unless [:low_priority, :high_priority].include? priority @@ -59,15 +48,5 @@ def capture_exception(error:, extra: {}) if self.class.app_name.present? RequestStore.store[:application] = "#{self.class.app_name}_job" end - - # Check whether Job execution time should be tracked - unless self.class::IGNORE_JOB_EXECUTION_TIME - # Add Record to JobExecutionTimes to track the current job execution time - JobExecutionTime.upsert( - { job_name: self.class.to_s, - last_executed_at: Time.now.utc }, - unique_by: :job_name - ) - end end end diff --git a/app/jobs/caseflow_job.rb b/app/jobs/caseflow_job.rb index b9717f403b0..e1ce79195f7 100644 --- a/app/jobs/caseflow_job.rb +++ b/app/jobs/caseflow_job.rb @@ -14,35 +14,6 @@ class CaseflowJob < ApplicationJob metrics_service_report_runtime(metric_group_name: job.class.name.underscore) unless @reported_to_metrics_service end - class << self - # Serializes and formats a job object so that it can be placed into an SQS message queue - # - # @param job [ActiveJob::Base] The job to be serialized - # - # @return [Hash] - # A hash representation of the job object that is compatible with SQS. - def serialize_job_for_enqueueing(job) - ActiveJob::QueueAdapters::ShoryukenAdapter.instance.send(:message, job) - end - - # Allows for enqueueing up to 10 async jobs at a time via the SendMessageBatch endpoint in the - # SQS API. This is to allow for reducing the number of round trips to the API when enqueueing a large - # number of jobs for delayed execution. - # - # @param jobs_to_enqueue [Array] The jobs to enqueue for later execution. - # @param name_of_queue [String] The name of the SQS queue to place the messages onto. - # - # @return [Aws::SQS::Types::SendMessageBatchResult] - # A struct containing the messages that were successfully enqueued and those that failed. - def enqueue_batch_of_jobs(jobs_to_enqueue:, name_of_queue:) - fail Caseflow::Error::MaximumBatchSizeViolationError if jobs_to_enqueue.size > 10 - - Shoryuken::Client.queues(name_of_queue).send_messages( - jobs_to_enqueue.map { serialize_job_for_enqueueing(_1) } - ) - end - end - def metrics_service_report_runtime(metric_group_name:) MetricsService.record_runtime( app_name: "caseflow_job", diff --git a/app/jobs/hearings/geomatch_and_cache_appeal_job.rb b/app/jobs/hearings/geomatch_and_cache_appeal_job.rb index 5e6a8f647d4..16e11ed1c1b 100644 --- a/app/jobs/hearings/geomatch_and_cache_appeal_job.rb +++ b/app/jobs/hearings/geomatch_and_cache_appeal_job.rb @@ -5,7 +5,7 @@ class Hearings::GeomatchAndCacheAppealJob < ApplicationJob application_attr :hearing_schedule # :nocov: - retry_on(StandardError, wait: 10.seconds, attempts: 5) do |job, exception| + retry_on(StandardError, wait: 10.seconds, attempts: 10) do |job, exception| Rails.logger.error("#{job.class.name} (#{job.job_id}) failed with error: #{exception}") if job.executions == 10 diff --git a/app/jobs/ignore_job_execution_time.rb b/app/jobs/ignore_job_execution_time.rb deleted file mode 100644 index f22d22029f4..00000000000 --- a/app/jobs/ignore_job_execution_time.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -module IgnoreJobExecutionTime - IGNORE_JOB_EXECUTION_TIME = true -end diff --git a/app/jobs/legacy_notification_efolder_sync_job.rb b/app/jobs/legacy_notification_efolder_sync_job.rb index 4107d2a9a45..1aa41950469 100644 --- a/app/jobs/legacy_notification_efolder_sync_job.rb +++ b/app/jobs/legacy_notification_efolder_sync_job.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class LegacyNotificationEfolderSyncJob < CaseflowJob - include MessageConfigurations::DeleteMessageBeforeStart - queue_with_priority :low_priority BATCH_LIMIT = ENV["LEGACY_NOTIFICATION_REPORT_SYNC_LIMIT"] || 500 diff --git a/app/jobs/message_configurations/delete_message_before_start.rb b/app/jobs/message_configurations/delete_message_before_start.rb deleted file mode 100644 index 233298b9480..00000000000 --- a/app/jobs/message_configurations/delete_message_before_start.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -module MessageConfigurations::DeleteMessageBeforeStart - DELETE_SQS_MESSAGE_BEFORE_START = true -end diff --git a/app/jobs/middleware/job_message_deletion_middleware.rb b/app/jobs/middleware/job_message_deletion_middleware.rb deleted file mode 100644 index c4b0c760637..00000000000 --- a/app/jobs/middleware/job_message_deletion_middleware.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -# Deletes the message from the associated SQS queue if the job class -# specifies that this operation should take place PRIOR to the job being initiated. -# -# This will occur if the job will take longer than the SQS queue's visibility timeout -# which would potentially allow multiple instances of the same job to be executed. -class JobMessageDeletionMiddleware - # :reek:LongParameterList - def call(_worker, _queue, msg, body) - if body["job_class"].constantize::DELETE_SQS_MESSAGE_BEFORE_START - msg.client.delete_message(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - end - - yield - end -end diff --git a/app/jobs/nightly_syncs_job.rb b/app/jobs/nightly_syncs_job.rb index ef835251d04..1dbe22bc95f 100644 --- a/app/jobs/nightly_syncs_job.rb +++ b/app/jobs/nightly_syncs_job.rb @@ -11,7 +11,6 @@ def perform RequestStore.store[:current_user] = User.system_user @slack_report = [] - sync_hearing_states sync_vacols_cases sync_vacols_users sync_decision_review_tasks @@ -89,21 +88,4 @@ def dangling_legacy_appeals reporter.call reporter.buffer.map { |vacols_id| LegacyAppeal.find_by(vacols_id: vacols_id) } end - - # Adjusts any appeal states appropriately if it is found that a seemingly pending - # hearing has been marked with a disposition in VACOLS without Caseflow's knowledge. - def sync_hearing_states - AppealState.where(appeal_type: "LegacyAppeal", hearing_scheduled: true).each do |state| - case state.appeal&.hearings&.max_by(&:scheduled_for)&.disposition - when Constants.HEARING_DISPOSITION_TYPES.held - state.hearing_held_appeal_state_update_action! - when Constants.HEARING_DISPOSITION_TYPES.cancelled - state.hearing_withdrawn_appeal_state_update_action! - when Constants.HEARING_DISPOSITION_TYPES.postponed - state.hearing_postponed_appeal_state_update_action! - when Constants.HEARING_DISPOSITION_TYPES.scheduled_in_error - state.scheduled_in_error_appeal_state_update_action! - end - end - end end diff --git a/app/jobs/notification_initialization_job.rb b/app/jobs/notification_initialization_job.rb deleted file mode 100644 index 41a2f0ae0ba..00000000000 --- a/app/jobs/notification_initialization_job.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -# == Overview -# -# The NotificationInitializationJob encapsulates the instantiation of templates -# for messages to be sent by VANotify. -# -# Information such as whether or not the claimant is deceased and if the veteran is still the -# primary claimant (or if an appellant substitution has taken place) is gathered and factored -# into what is then sent to the SendNotificationJob. -# -# This job was created in order to extract logic that causes calls to external services so that -# large batch notification queueing jobs, like the QuarterlyNotificationsJob, can run much more quickly. -class NotificationInitializationJob < CaseflowJob - include Hearings::EnsureCurrentUserIsSet - include IgnoreJobExecutionTime - - queue_as SendNotificationJob.queue_name_suffix - application_attr :va_notify - - # ... - # - # @param appeal_id [Integer] Foreign key ID of the appeal to be associated with the notification. - # @param appeal_type [String] Class name of appeal to be associated with the notification. Appeal or LegacyAppeal. - # @param template_name [String] VANotify template name to be requested transmission of. - # Must be present in the configuration for our VANotify account, and must be a template represented in our - # notification_events table. - # @param appeal_status [String] An optional status that is used to fill in a blank in the quarterly notification - # template to let the claimant know what the status of their appeal is. - # - # @return [SendNotificationJob, nil] - # A SendNotificationJob job object representing the job that was enqueued, or nil if a notification - # wasn't ultimately attempted to be sent. - # :reek:LongParameterList - def perform(appeal_id:, appeal_type:, template_name:, appeal_status: nil) - begin - ensure_current_user_is_set - - appeal = appeal_type.constantize.find_by(id: appeal_id) - - fail Caseflow::Error::AppealNotFound, "#{appeal_type} with ID #{appeal_id} could not be found." unless appeal - - AppellantNotification.notify_appellant( - appeal, - template_name, - appeal_status - ) - rescue StandardError => error - log_error(error) - end - end -end diff --git a/app/jobs/poll_docketed_legacy_appeals_job.rb b/app/jobs/poll_docketed_legacy_appeals_job.rb index e9f11051a5f..ae5f0443226 100644 --- a/app/jobs/poll_docketed_legacy_appeals_job.rb +++ b/app/jobs/poll_docketed_legacy_appeals_job.rb @@ -18,7 +18,6 @@ def perform RequestStore.store[:current_user] = User.system_user vacols_ids = most_recent_docketed_appeals(LEGACY_DOCKETED) filtered_vacols_ids = filter_duplicate_legacy_notifications(vacols_ids) - create_corresponding_appeal_states(filtered_vacols_ids.uniq) send_legacy_notifications(filtered_vacols_ids) end @@ -39,25 +38,6 @@ def filter_duplicate_legacy_notifications(vacols_ids) vacols_ids.reject { |id| duplicate_ids.include?(id) } end - # Purpose: To create an AppealState record for the docketed legacy appeals - # Params: An array of vacols_ids for docketed legacy appeals - # Return: None - def create_corresponding_appeal_states(vacols_ids) - vacols_ids.each do |vacols_id| - appeal = LegacyAppeal.find_by_vacols_id(vacols_id) - appeal_state = AppealState.find_by(appeal: appeal) - if appeal_state - appeal_state.appeal_docketed = true - appeal_state.save! - else - AppealState.new(appeal: appeal, - created_by_id: User.system_user.id, - appeal_docketed: true) - .save! - end - end - end - # rubocop:disable all # Purpose: To send the 'appeal docketed' notification for the legacy appeals # Params: vacols_ids - An array of filtered vacols ids for legacy appeals that didnt already have notifications sent @@ -66,10 +46,7 @@ def send_legacy_notifications(vacols_ids) Rails.logger.info("Found #{vacols_ids.count} legacy appeals that have been recently docketed and have not gotten docketed notifications") vacols_ids.each do |vacols_id| begin - AppellantNotification.notify_appellant( - LegacyAppeal.find_by_vacols_id(vacols_id), - Constants.EVENT_TYPE_FILTERS.appeal_docketed - ) + AppellantNotification.notify_appellant(LegacyAppeal.find_by_vacols_id(vacols_id), "Appeal docketed") rescue Exception => ex Rails.logger.error("#{ex.class}: #{ex.message} for vacols id:#{vacols_id} on #{JOB_ATTR.class} of ID:#{JOB_ATTR.job_id}\n #{ex.backtrace.join("\n")}") next diff --git a/app/jobs/push_priority_appeals_to_judges_job.rb b/app/jobs/push_priority_appeals_to_judges_job.rb index e042610c08a..3e1bcfb7a9b 100644 --- a/app/jobs/push_priority_appeals_to_judges_job.rb +++ b/app/jobs/push_priority_appeals_to_judges_job.rb @@ -7,7 +7,6 @@ class PushPriorityAppealsToJudgesJob < CaseflowJob # For time_ago_in_words() include ActionView::Helpers::DateHelper - include RunAsyncable queue_with_priority :low_priority application_attr :queue @@ -19,8 +18,6 @@ def perform @genpop_distributions = distribute_genpop_priority_appeals - perform_later_or_now(UpdateAppealAffinityDatesJob) - send_job_report rescue StandardError => error start_time ||= Time.zone.now # temporary fix to get this job to succeed diff --git a/app/jobs/quarterly_notifications_job.rb b/app/jobs/quarterly_notifications_job.rb index c6277e09dfe..70444b312bf 100644 --- a/app/jobs/quarterly_notifications_job.rb +++ b/app/jobs/quarterly_notifications_job.rb @@ -1,57 +1,140 @@ # frozen_string_literal: true class QuarterlyNotificationsJob < CaseflowJob - include MessageConfigurations::DeleteMessageBeforeStart - include Hearings::EnsureCurrentUserIsSet queue_with_priority :low_priority - application_attr :va_notify + application_attr :hearing_schedule - NOTIFICATION_TYPES = Constants.QUARTERLY_STATUSES.to_h.freeze + QUERY_LIMIT = ENV["QUARTERLY_NOTIFICATIONS_JOB_BATCH_SIZE"] - # Locates appeals eligible for quarterly notifications and queues a NotificationInitializationJob - # for each for further processing, and eventual (maybe) transmission of correspondence to an appellant. + # Purpose: Loop through all open appeals quarterly and sends statuses for VA Notify + # + # Params: none # - # @return [Hash] - # Returns the hash of NOTIFICATION_TYPES that were iterated over, though this value isn't designed - # to be utilized by a caller due to the async nature of this job. - def perform + # Response: None + def perform # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity ensure_current_user_is_set - begin - NOTIFICATION_TYPES.each_key do |notification_type| - status_text = NOTIFICATION_TYPES[notification_type.to_sym] - - jobs = AppealState.eligible_for_quarterly.send(notification_type).pluck(:appeal_id, :appeal_type) - .map do |related_appeal_info| - NotificationInitializationJob.new( - appeal_id: related_appeal_info.first, - appeal_type: related_appeal_info.last, - template_name: Constants.EVENT_TYPE_FILTERS.quarterly_notification, - appeal_status: status_text - ) + AppealState.where.not(decision_mailed: true).where.not(appeal_cancelled: true) + .find_in_batches(batch_size: QUERY_LIMIT.to_i) do |batched_appeal_states| + batched_appeal_states.each do |appeal_state| + # add_record_to_appeal_states_table(appeal_state.appeal) + if appeal_state.appeal_type == "Appeal" + appeal = Appeal.find_by(id: appeal_state.appeal_id) + elsif appeal_state.appeal_type == "LegacyAppeal" + appeal = LegacyAppeal.find_by(id: appeal_state.appeal_id) + end + if appeal.nil? + begin + fail Caseflow::Error::AppealNotFound, "Standard Error ID: " + SecureRandom.uuid + " The appeal was unable "\ + "to be found." + rescue Caseflow::Error::AppealNotFound => error + Rails.logger.error("QuarterlyNotificationsJob::Error - Unable to send a notification for "\ + "#{appeal_state&.appeal_type} ID #{appeal_state&.appeal_id} because of #{error}") + end + else + begin + MetricsService.record("Creating Quarterly Notification for #{appeal.class} ID #{appeal.id}", + name: "send_quarterly_notifications(appeal_state, appeal)") do + send_quarterly_notifications(appeal_state, appeal) + end + rescue StandardError => error + Rails.logger.error("QuarterlyNotificationsJob::Error - Unable to send a notification for "\ + "#{appeal_state&.appeal_type} ID #{appeal_state&.appeal_id} because of #{error}") + end end - - Parallel.each(jobs.each_slice(10).to_a, in_threads: 5) { |jobs_to_enqueue| enqueue_init_jobs(jobs_to_enqueue) } end - rescue StandardError => error - log_error(error) end end private - # Batches enqueueing of the NotificationInitializationJobs in order to reduce round-trips to the SQS API + # Purpose: Method to check appeal state for statuses and send out a notification based on + # which statuses are turned on in the appeal state # - # @param jobs [Array] An array of NotificationInitializationJob objects to enqueue. + # Params: appeal state, appeal # - # @return [Aws::SQS::Types::SendMessageBatchResult] - # A struct containing the messages that were successfully enqueued and those that failed. - def enqueue_init_jobs(jobs) - CaseflowJob.enqueue_batch_of_jobs( - jobs_to_enqueue: jobs, - name_of_queue: NotificationInitializationJob.queue_name - ) + # Response: SendNotificationJob queued to send_notification SQS queue + def send_quarterly_notifications(appeal_state, appeal) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + # if either there's a hearing postponed or a hearing scheduled in error + if appeal_state.hearing_postponed || appeal_state.scheduled_in_error + # appeal status is Hearing to be Rescheduled / Privacy Act Pending + if appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.hearing_to_be_rescheduled_privacy_pending + ) + # appeal status is Hearing to be Rescheduled + else + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.hearing_to_be_rescheduled + ) + end + # if there's a hearing scheduled + elsif appeal_state.hearing_scheduled + # if there's privacy act tasks pending + # appeal status is Hearing Scheduled / Privacy Act Pending + if appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.hearing_scheduled_privacy_pending + ) + # if there's no privacy act tasks pending + # appeal status is Hearing Scheduled + elsif !appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.hearing_scheduled + ) + end + # if there's no hearing scheduled and no hearing withdrawn + elsif !appeal_state.hearing_withdrawn + # if there's ihp tasks pending and privacy act tasks pending + # appeal status is VSO IHP Pending / Privacy Act Pending + if appeal_state.vso_ihp_pending && appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.ihp_pending_privacy_pending + ) + # if there's no ihp tasks pending and there are privacy act tasks pending + # appeal status is Privacy Act Pending + elsif !appeal_state.vso_ihp_pending && appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.privacy_pending + ) + # if there's no privacy acts pending and there are ihp tasks pending + # appeal status is VSO IHP Pending + elsif appeal_state.vso_ihp_pending && !appeal_state.privacy_act_pending + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.ihp_pending + ) + # if there's no privacy acts pending or ihp tasks pending + # appeal status is Appeal Docketed + elsif !appeal_state.vso_ihp_pending && !appeal_state.privacy_act_pending && appeal_state.appeal_docketed + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.appeal_docketed + ) + end + # appeal status is Appeal Docketed + elsif appeal_state.appeal_docketed && appeal_state.hearing_withdrawn + AppellantNotification.notify_appellant( + appeal, + "Quarterly Notification", + Constants.QUARTERLY_STATUSES.appeal_docketed + ) + end end end diff --git a/app/jobs/send_notification_job.rb b/app/jobs/send_notification_job.rb index 4438014e8ec..1a145882481 100644 --- a/app/jobs/send_notification_job.rb +++ b/app/jobs/send_notification_job.rb @@ -3,292 +3,226 @@ # Purpose: Active Job that handles the processing of VA Notifcation event trigger. # This job saves the data to an audit table and If the corresponding feature flag is enabled will send # an email or SMS request to VA Notify API -# :reek:RepeatedConditional class SendNotificationJob < CaseflowJob include Hearings::EnsureCurrentUserIsSet - include IgnoreJobExecutionTime - queue_as { self.class.queue_name_suffix } - application_attr :va_notify - attr_accessor :notification_audit, :message + queue_as ApplicationController.dependencies_faked? ? :send_notifications : :"send_notifications.fifo" + application_attr :hearing_schedule - class SendNotificationJobError < StandardError; end - - RETRY_ERRORS = [ - Caseflow::Error::VANotifyNotFoundError, - Caseflow::Error::VANotifyInternalServerError, - Caseflow::Error::VANotifyRateLimitError, - HTTPClient::ReceiveTimeoutError - ].freeze + retry_on(Caseflow::Error::VANotifyNotFoundError, attempts: 5, wait: :exponentially_longer) do |job, exception| + Rails.logger.error("Retrying #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") + end - DISCARD_ERRORS = [ - Caseflow::Error::VANotifyUnauthorizedError, - Caseflow::Error::VANotifyForbiddenError, - SendNotificationJobError - ].freeze + retry_on(Caseflow::Error::VANotifyInternalServerError, attempts: 5, wait: :exponentially_longer) do |job, exception| + Rails.logger.error("Retrying #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") + end - RETRY_ERRORS.each do |err| - retry_on(err, attempts: 5, wait: :exponentially_longer) do |job, exception| - Rails.logger.error("Retrying #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") - end + retry_on(Caseflow::Error::VANotifyRateLimitError, attempts: 5, wait: :exponentially_longer) do |job, exception| + Rails.logger.error("Retrying #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") end - DISCARD_ERRORS.each do |err| - discard_on(err) do |job, exception| - error_message = "Discarding #{job.class.name} (#{job.job_id}) because failed with error: #{exception}" - err_level = exception.instance_of?(SendNotificationJobError) ? :error : :warn - Rails.logger.send(err_level, error_message) - end + discard_on(Caseflow::Error::VANotifyUnauthorizedError) do |job, exception| + Rails.logger.warn("Discarding #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") end - class << self - def queue_name_suffix - ApplicationController.dependencies_faked? ? :send_notifications : :"send_notifications.fifo" - end + discard_on(Caseflow::Error::VANotifyForbiddenError) do |job, exception| + Rails.logger.warn("Discarding #{job.class.name} (#{job.job_id}) because failed with error: #{exception}") end # Must receive JSON string as argument - def perform(message_json) ensure_current_user_is_set begin - fail SendNotificationJobError, "Message argument of value nil supplied to job" if message_json.nil? - - @message = validate_message(JSON.parse(message_json, object_class: OpenStruct)) - - transaction_wrapper do - @notification_audit = find_or_create_notification_audit - update_notification_statuses - send_to_va_notify if message_status_valid? - end - rescue StandardError => error - if Rails.deploy_env?(:prodtest) && error.in?(DISCARD_ERRORS) - transaction_wrapper do - @notification_audit = find_or_create_notification_audit - end + unless message_json + fail Caseflow::Error::NotificationInitializationError, + message: "There was no message passed into the " \ + "SendNotificationJob.perform_later function. Exiting job." end + handle_message_json(message_json) + rescue StandardError => error log_error(error) - raise error end end private - # Conditionally wraps database operations in a transaction block depending on whether - # the current environment is ProdTest. The choice to not have ProdTest queries utilize - # a transction is due to how unlikely it will be for us to have an operation VA Notify - # integration in that environment due to this environment having production-replicated - # data and us not wanting to inadvertently transmit messages to actual recipients. - # - # The lack of a transaction block will prevent rollbacks on the records created in the - # notifications table and allow for observations around notification accuracy to be - # more easily obtained. - def transaction_wrapper - ActiveRecord::Base.transaction { yield } - end - - def event_type - message.template_name - end - - def event - @event ||= NotificationEvent.find_by(event_type: event_type) - end - - def appeal - @appeal ||= find_appeal_by_external_id - end - - # Purpose: Find appeal by external ID - # - # Returns: Appeal object - def find_appeal_by_external_id - appeal = Appeal.find_appeal_by_uuid_or_find_or_create_legacy_appeal_by_vacols_id(message.appeal_id) - - return appeal unless appeal.nil? - - fail SendNotificationJobError, "Associated appeal cannot be found for external ID #{message.appeal_id}" - end - - # Purpose: Determine if either a quarterly sms notification or non-quarterly sms notification - # - # Returns: Boolean - def sms_enabled? - @sms_enabled ||= va_notify_sms_enabled? || va_notify_quarterly_sms_enabled? - end - - def va_notify_sms_enabled? - FeatureToggle.enabled?(:va_notify_sms) && !quarterly_notification? - end - - def va_notify_quarterly_sms_enabled? - FeatureToggle.enabled?(:va_notify_quarterly_sms) && quarterly_notification? - end - - def quarterly_notification? - event_type == Constants.EVENT_TYPE_FILTERS.quarterly_notification - end - - # Purpose: Ensure necessary message attributes present to send notification - # - # Params: message: object containing details from appeal for notification - # - # Returns: message - # :reek:FeatureEnvy - def validate_message(message_to_validate) - nil_attributes = [:appeal_id, :appeal_type, :template_name].filter { |attr| message_to_validate.send(attr).nil? } - - return message_to_validate unless nil_attributes.any? - - fail SendNotificationJobError, "Nil message attribute(s): #{nil_attributes.map(&:to_s).join(', ')}" - end - - # Purpose: Find or create a new notification table row for the appeal - # - # Returns: Notification active model or nil - def find_or_create_notification_audit - params = { - appeals_id: message.appeal_id, - appeals_type: message.appeal_type, - event_type: event_type, - event_date: Time.zone.today, - notification_type: notification_type, - notifiable: appeal - } - - if legacy_appeal_docketed_event? && FeatureToggle.enabled?(:appeal_docketed_event) - notification = Notification.where(params).last - - return notification unless notification.nil? + # Purpose: Conditionally handles a JSON outline of a notification and maybe sends it to + # to a veteran via VANotify. + # + # Params: A JSON object containing notification data + # + # Response: nil + # rubocop:disable Layout/LineLength, Metrics/BlockNesting + def handle_message_json(message_json) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + @va_notify_email = FeatureToggle.enabled?(:va_notify_email) + @va_notify_sms = FeatureToggle.enabled?(:va_notify_sms) + @va_notify_quarterly_sms = FeatureToggle.enabled?(:va_notify_quarterly_sms) + message = JSON.parse(message_json, object_class: OpenStruct) + if message.appeal_id && message.appeal_type && message.template_name + notification_audit_record = create_notification_audit_record( + message.appeal_id, + message.appeal_type, + message.template_name, + message.participant_id + ) + if notification_audit_record + if message.status != "No participant_id" && message.status != "No claimant" + to_update = {} + if @va_notify_email + to_update[:email_notification_status] = message.status + end + if @va_notify_sms && message.template_name != "Quarterly Notification" || + @va_notify_quarterly_sms && message.template_name == "Quarterly Notification" + to_update[:sms_notification_status] = message.status + end + update_notification_audit_record(notification_audit_record, to_update) + if message.template_name == "Appeal docketed" && message.appeal_type == "LegacyAppeal" && !FeatureToggle.enabled?(:appeal_docketed_notification) + notification_audit_record.update!(email_enabled: false) + else + send_to_va_notify(message, notification_audit_record) + end + else + status = (message.status == "No participant_id") ? "No Participant Id Found" : "No Claimant Found" + to_update = {} + if @va_notify_email + to_update[:email_notification_status] = status + end + if @va_notify_sms && message.template_name != "Quarterly Notification" || + @va_notify_quarterly_sms && message.template_name == "Quarterly Notification" + to_update[:sms_notification_status] = status + end + update_notification_audit_record(notification_audit_record, to_update) + end + notification_audit_record.save! + else + fail Caseflow::Error::NotificationInitializationError, + message: "Audit record was unable to be found or created in SendNotificationJob. Exiting Job." + end + else + fail Caseflow::Error::NotificationInitializationError, + message: "appeals_id or appeal_type or event_type was nil in the SendNotificationJob. Exiting job." end - - create_notification(params.merge(participant_id: message.participant_id, notified_at: Time.zone.now)) end + # rubocop:enable Layout/LineLength, Metrics/BlockNesting - # Purpose: Determine if the notification event is for a legacy appeal that has been docketed + # Purpose: Updates and saves notification status for notification_audit_record # - # Returns: Boolean - def legacy_appeal_docketed_event? - event_type == Constants.EVENT_TYPE_FILTERS.appeal_docketed && appeal.is_a?(LegacyAppeal) - end - - # Purpose: Create notification audit record - # - # Params: params: Payload of attributes with which to create notification object + # Params: notification_audit_record: object, + # to_update: hash. key corresponds to notification_events column and value corresponds to new value # - # Returns: Notification object - def create_notification(params) - notification = Notification.create(params) - - return notification unless notification.nil? - - fail SendNotificationJobError, "Notification audit record was unable to be found or created" - end - - # Purpose: Updates and saves notification status for notification object - # - # Response: Updated notification object - def update_notification_statuses - status = format_message_status - params = {} - params[:email_notification_status] = status - params[:sms_notification_status] = status if sms_enabled? - - notification_audit.update(params) - end - - # Purpose: Reformat message status if status belongs to invalid category - # - # Response: Message string - def format_message_status - return message.status if message_status_valid? - - case message.status - when "No participant_id" then "No Participant Id Found" - when "No claimant" then "No Claimant Found" - when "Failure Due to Deceased" then "Failure Due to Deceased" - else - fail StandardError, "Message status #{message.status} is not recognized." + # Response: Updated notification_audit_record + def update_notification_audit_record(notification_audit_record, to_update) + to_update.each do |key, value| + notification_audit_record[key] = value end end - # Purpose: Determine if message status belongs to invalid - # - # Response: Boolean - def message_status_valid? - ["No participant_id", "No claimant", "Failure Due to Deceased"].exclude?(message.status) - end - # Purpose: Send message to VA Notify to send notification # - # Response: Updated Notification object - def send_to_va_notify - send_va_notify_email - send_va_notify_sms if sms_enabled? - end - - # Purpose: Build payload for VA Notify request body - # - # Response: Payload object - def va_notify_payload - { - participant_id: message.participant_id, - notification_id: notification_audit.id.to_s, - first_name: first_name || "Appellant", - docket_number: appeal.docket_number, - status: message.appeal_status || "" - } - end - - # Purpose: Send payload to VA Notify to send email notification - # - # Response: Updated notification object - def send_va_notify_email - email_response = VANotifyService.send_email_notifications( - va_notify_payload.merge(email_template_id: event.email_template_id) - ) - - if email_response.present? - body = email_response.body - notification_audit.update( - notification_content: body["content"]["body"], - email_notification_content: body["content"]["body"], - email_notification_external_id: body["id"] + # Params: message (object containing participant_id, template_name, and others) Details from appeal for notification + # notification_id: ID of the notification_audit record (must be converted to string to work with API) + # + # Response: Updated Notification object (still not saved) + def send_to_va_notify(message, notification_audit_record) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + event = NotificationEvent.find_by(event_type: message.template_name) + email_template_id = event.email_template_id + sms_template_id = event.sms_template_id + quarterly_sms_template_id = NotificationEvent.find_by(event_type: "Quarterly Notification").sms_template_id + appeal = Appeal.find_by_uuid(message.appeal_id) || LegacyAppeal.find_by(vacols_id: message.appeal_id) + first_name = appeal&.appellant_or_veteran_name&.split(" ")&.first || "Appellant" + status = message.appeal_status || "" + docket_number = appeal.docket_number + + if @va_notify_email + response = VANotifyService.send_email_notifications( + message.participant_id, + notification_audit_record.id.to_s, + email_template_id, + first_name, + docket_number, + status ) + if !response.nil? && response != "" + to_update = { notification_content: response.body["content"]["body"], + email_notification_content: response.body["content"]["body"], + email_notification_external_id: response.body["id"] } + update_notification_audit_record(notification_audit_record, to_update) + end end - end - - # Purpose: Send payload to VA Notify to send sms notification - # - # Response: Updated notification object - def send_va_notify_sms - response = VANotifyService.send_sms_notifications(va_notify_payload.merge(sms_template_id: event.sms_template_id)) - if response.present? - notification_audit.update( - sms_notification_content: response.body["content"]["body"], - sms_notification_external_id: response.body["id"] + if @va_notify_sms && sms_template_id != quarterly_sms_template_id || + @va_notify_quarterly_sms && sms_template_id == quarterly_sms_template_id + response = VANotifyService.send_sms_notifications( + message.participant_id, + notification_audit_record.id.to_s, + sms_template_id, + first_name, + docket_number, + status ) + if !response.nil? && response != "" + to_update = { + sms_notification_content: response.body["content"]["body"], sms_notification_external_id: response.body["id"] + } + update_notification_audit_record(notification_audit_record, to_update) + end end end - # Purpose: Determine notification type depending on enabled feature toggles and event type + # Purpose: Method to create a new notification table row for the appeal + # + # Params: + # - appeals_id - UUID or vacols_id of the appeals the event triggered + # - appeals_type - Polymorphic column to identify the type of appeal + # - - Appeal + # - - LegacyAppeal + # - event_type: Name of the event that has transpired. Event names can be found in the notification_events table # - # Response: String - def notification_type - if sms_enabled? - "Email and SMS" + # Returns: Notification active model or nil + + # rubocop:disable all + def create_notification_audit_record(appeals_id, appeals_type, event_type, participant_id) + notification_type = + if @va_notify_email && @va_notify_sms && event_type != "Quarterly Notification" || + @va_notify_email && @va_notify_quarterly_sms && event_type == "Quarterly Notification" + "Email and SMS" + elsif @va_notify_email + "Email" + elsif @va_notify_sms && event_type != "Quarterly Notification" || + @va_notify_quarterly_sms && event_type == "Quarterly Notification" + "SMS" + else + "None" + end + + if event_type == "Appeal docketed" && appeals_type == "LegacyAppeal" && FeatureToggle.enabled?(:appeal_docketed_event) + notification = Notification.where(appeals_id: appeals_id, event_type: event_type, notification_type: notification_type, appeals_type: appeals_type, event_date: Time.zone.today).last + if !notification.nil? + notification + else + Notification.new( + appeals_id: appeals_id, + appeals_type: appeals_type, + event_type: event_type, + notification_type: notification_type, + participant_id: participant_id, + notified_at: Time.zone.now, + event_date: Time.zone.today + ) + end else - "Email" + Notification.new( + appeals_id: appeals_id, + appeals_type: appeals_type, + event_type: event_type, + notification_type: notification_type, + participant_id: participant_id, + notified_at: Time.zone.now, + event_date: Time.zone.today + ) end end - - # Purpose: Parse first name of veteran or appellant from appeal - # - # Response: String - def first_name - appeal&.appellant_or_veteran_name&.split(" ")&.first - end + # rubocop:enable all end diff --git a/app/jobs/start_distribution_job.rb b/app/jobs/start_distribution_job.rb index 040aa4e154b..88138106f0d 100644 --- a/app/jobs/start_distribution_job.rb +++ b/app/jobs/start_distribution_job.rb @@ -1,15 +1,12 @@ # frozen_string_literal: true class StartDistributionJob < ApplicationJob - include RunAsyncable - queue_with_priority :high_priority application_attr :queue def perform(distribution, user = nil) RequestStore.store[:current_user] = user if user distribution.distribute! - perform_later_or_now(UpdateAppealAffinityDatesJob, distribution.id) rescue StandardError => error handle_error(error) # do not re-raise, since we only want to run once. diff --git a/app/jobs/update_appeal_affinity_dates_job.rb b/app/jobs/update_appeal_affinity_dates_job.rb deleted file mode 100644 index a2875f2823c..00000000000 --- a/app/jobs/update_appeal_affinity_dates_job.rb +++ /dev/null @@ -1,123 +0,0 @@ -# frozen_string_literal: true - -class UpdateAppealAffinityDatesJob < CaseflowJob - queue_with_priority :low_priority - application_attr :queue - - # the ["docket_name", priority] format is how ActiveRecord returns the query results - PAIRS_TO_DELETE = [["evidence_submission", false], ["direct_review", false]].freeze - - def perform(distribution_id = nil) - RequestStore.store[:current_user] = User.system_user - @distribution_id = distribution_id - - if @distribution_id - update_from_requested_distribution - else - update_from_push_priority_appeals_job - end - rescue StandardError => error - title = "UpdateAppealAffinityDatesJob Error" - slack_service.send_notification(error.message, title) - log_error(error) - end - - private - - def update_from_requested_distribution - receipt_date_hashes_array = latest_receipt_dates_from_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) - end - - def update_from_push_priority_appeals_job - receipt_date_hashes_array = latest_receipt_dates_from_push_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) - end - - def latest_receipt_dates_from_distribution - distributed_cases_hash = - DistributedCase - .joins("INNER JOIN appeals ON case_id = uuid::text") - .where(distribution_id: @distribution_id) - .group("docket", "priority") - .maximum("receipt_date") - - format_distributed_case_hash(distributed_cases_hash) - end - - def latest_receipt_dates_from_push_job - distributed_cases_hash = - DistributedCase - .includes(:distribution) - .joins("INNER JOIN appeals ON case_id = uuid::text") - .where(distributions: { priority_push: true, completed_at: Time.zone.today.midnight..Time.zone.now }) - .group("docket", "priority") - .maximum("receipt_date") - - format_distributed_case_hash(distributed_cases_hash) - end - - 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 - distributed_cases_hash.delete_if { |combo, _| PAIRS_TO_DELETE.include?(combo) } - - # Transform the SQL output into a more workable array of hashes - receipt_date_hashes_array = [] - distributed_cases_hash.each_pair do |keys, receipt_date| - receipt_date_hashes_array << { docket: keys[0], priority: keys[1], receipt_date: receipt_date } - end - - receipt_date_hashes_array - end - - def process_ama_appeals_which_need_affinity_updates(receipt_date_hashes_array) - receipt_date_hashes_array.map do |receipt_date_hash| - next if receipt_date_hash[:docket] == LegacyDocket.docket_type - - base_appeals_to_update = - Appeal.extending(DistributionScopes) - .ready_for_distribution - .with_appeal_affinities - .where(docket_type: receipt_date_hash[:docket], appeal_affinities: { affinity_start_date: nil }) - .where("receipt_date <= (?)", receipt_date_hash[:receipt_date]) - - appeals_to_update_adjusted_for_priority = if receipt_date_hash[:priority] - base_appeals_to_update.priority - 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 - - # 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) - appeals.map do |appeal| - existing_affinity = appeal.appeal_affinity - - if existing_affinity - existing_affinity.update!(affinity_start_date: Time.zone.now, distribution_id: @distribution_id) - existing_affinity - else - appeal.create_appeal_affinity!( - docket: appeal.docket_type, - priority: priority, - affinity_start_date: Time.zone.now, - distribution_id: @distribution_id - ) - end - end - end -end diff --git a/app/jobs/virtual_hearings/create_conference_job.rb b/app/jobs/virtual_hearings/create_conference_job.rb index e88973d77c0..0da4a21227f 100644 --- a/app/jobs/virtual_hearings/create_conference_job.rb +++ b/app/jobs/virtual_hearings/create_conference_job.rb @@ -31,16 +31,16 @@ class VirtualHearingLinkGenerationFailed < StandardError; end ) end - retry_on(IncompleteError, attempts: 5, wait: :exponentially_longer) do |job, exception| + retry_on(IncompleteError, attempts: 10, wait: :exponentially_longer) do |job, exception| Rails.logger.error("#{job.class.name} (#{job.job_id}) failed with error: #{exception}") end - retry_on(VirtualHearingNotCreatedError, attempts: 5, wait: :exponentially_longer) do |job, exception| + retry_on(VirtualHearingNotCreatedError, attempts: 10, wait: :exponentially_longer) do |job, exception| Rails.logger.error("#{job.class.name} (#{job.job_id}) failed with error: #{exception}") end # Retry if Pexip returns an invalid response. - retry_on(Caseflow::Error::PexipApiError, attempts: 5, wait: :exponentially_longer) do |job, exception| + retry_on(Caseflow::Error::PexipApiError, attempts: 10, wait: :exponentially_longer) do |job, exception| Rails.logger.error("#{job.class.name} (#{job.job_id}) failed with error: #{exception}") kwargs = job.arguments.first diff --git a/app/jobs/warm_bgs_caches_job.rb b/app/jobs/warm_bgs_caches_job.rb index f821720b1de..ab72151c89c 100644 --- a/app/jobs/warm_bgs_caches_job.rb +++ b/app/jobs/warm_bgs_caches_job.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class WarmBgsCachesJob < CaseflowJob - include MessageConfigurations::DeleteMessageBeforeStart - queue_with_priority :low_priority application_attr :hearing_schedule diff --git a/app/models/appeal.rb b/app/models/appeal.rb index 51ba29ecbcf..813de5cb956 100644 --- a/app/models/appeal.rb +++ b/app/models/appeal.rb @@ -26,7 +26,6 @@ class Appeal < DecisionReview has_many :email_recipients, class_name: "HearingEmailRecipient" has_many :available_hearing_locations, as: :appeal, class_name: "AvailableHearingLocations" has_many :vbms_uploaded_documents, as: :appeal - has_many :notifications, as: :notifiable # decision_documents is effectively a has_one until post decisional motions are supported has_many :decision_documents, as: :appeal @@ -35,8 +34,6 @@ class Appeal < DecisionReview has_one :special_issue_list, as: :appeal has_one :post_decision_motion - has_one :appeal_affinity, as: :case, primary_key: "uuid" - # Each appeal has one appeal_state that is used for tracking quarterly notifications has_one :appeal_state, as: :appeal @@ -959,10 +956,6 @@ def is_legacy? false end - def appeal_state - super || AppealState.find_or_create_by(appeal: self) - end - private def business_lines_needing_assignment diff --git a/app/models/appeal_affinity.rb b/app/models/appeal_affinity.rb deleted file mode 100644 index 546e6980a91..00000000000 --- a/app/models/appeal_affinity.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -class AppealAffinity < CaseflowRecord - validates :case_id, :docket, presence: true - validates :case_type, inclusion: %w[Appeal VACOLS::Case] - validates :priority, inclusion: [true, false] - - belongs_to :distribution - - after_save :update_distribution_task_instructions, if: :should_update_task_instructions? - - # A true polymorphic association isn't possible because of the differences in foreign keys between the various - # tables, so instead we define a getter which will return the correct type of record based on case_type - def case - case case_type - when Appeal.name - Appeal.find_by(uuid: case_id) if case_type == Appeal.name - when VACOLS::Case.name - VACOLS::Case.find_by(bfkey: case_id) if case_type == VACOLS::Case.name - end - end - - def update_distribution_task_instructions - distribution_task = DistributionTask.find_by(appeal: self.case, status: Constants.TASK_STATUSES.assigned) - return unless distribution_task - - distribution_task.instructions << "Affinity start date: #{affinity_start_date.to_date.strftime('%m/%d/%Y')}" - distribution_task.save! - end - - def should_update_task_instructions? - Constants::AMA_DOCKETS.include?(docket) && affinity_start_date? - end -end diff --git a/app/models/appeal_state.rb b/app/models/appeal_state.rb index 6acd80c9c8f..32322fc338a 100644 --- a/app/models/appeal_state.rb +++ b/app/models/appeal_state.rb @@ -1,451 +1,7 @@ # frozen_string_literal: true -# == Overview -# -# AppealState records are utilized to facilitate state machine-like behavior in order -# to track which status each appeal (AMA and Legacy) being processed in Caseflow is in. -# -# These states are most prominently used in the determination of which status to place in the -# 'Quarterly Notification' template whenever sending the quarterly correspondence to appellants. -# This is performed by the QuarterlyNotificationsJob. class AppealState < CaseflowRecord include HasAppealUpdatedSince include CreatedAndUpdatedByUserConcern include AppealStateBelongsToPolymorphicAppealConcern - - # Purpose: Default state of a hash of attributes for an appeal_state, all set to false. - # This will be used in the `update_appeal_state` method. - DEFAULT_STATE = ActiveSupport::HashWithIndifferentAccess.new(decision_mailed: false, - hearing_postponed: false, - hearing_withdrawn: false, - hearing_scheduled: false, - vso_ihp_pending: false, - vso_ihp_complete: false, - scheduled_in_error: false, - appeal_cancelled: false).freeze - - # Locates appeal states that are related to appeals eligible to potentially receive quarterly notifications. - # These appeals must not have been cancelled and their decisions must not have already been mailed. - # - # @return [ActiveRecord::Relation] - # Appeals eligible (potentially, assuming claimant is listed and claimant doesn't have an NOD on file) - # to receive a quarterly notification. - scope :eligible_for_quarterly, lambda { - where( - appeal_cancelled: false, - decision_mailed: false - ) - } - - # Locates appeal states related to appeals whose hearings have been cancelled - # (postponed or marked as "scheduled in error") and have yet to be rescheduled. - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals with hearings awaiting reschedulement. - scope :hearing_to_be_rescheduled, lambda { - where( - <<~SQL - hearing_scheduled IS FALSE AND - privacy_act_pending IS FALSE AND - ( - hearing_postponed IS TRUE OR - scheduled_in_error IS TRUE - ) - SQL - ) - } - - # Locates appeal states related to appeals whose hearings have been cancelled - # (postponed or marked as "scheduled in error") and have yet to be rescheduled. - # In addition, these appeals have an active Privacy Act/FOIA request in their trees. - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals with hearings awaiting reschedulement with Privacy Act/FOIA tasks. - scope :hearing_to_be_rescheduled_privacy_pending, lambda { - where( - <<~SQL - hearing_scheduled IS FALSE AND - privacy_act_pending IS TRUE AND - ( - hearing_postponed IS TRUE OR - scheduled_in_error IS TRUE - ) - SQL - ) - } - - # Locates appeal states related to appeals whose hearings have been scheduled and waiting to be held. - # - # @return [Array] - # Appeal states for appeals with scheduled hearings without dispositions - scope :hearing_scheduled, lambda { - hearing_scheduled_ama.where( - privacy_act_pending: false - ) + validated_hearing_scheduled_legacy_states.where( - privacy_act_pending: false - ) - } - - # Locates appeal states related to appeals whose hearings have been scheduled and waiting to be held. - # In addition, these appeals have an active Privacy Act/FOIA request in their trees. - # - # @return [Array] - # Appeal states for appeals with scheduled hearings without dispositions, and those appeals - # have open Privacy Act/FOIA-related tasks in their task trees. - scope :hearing_scheduled_privacy_pending, lambda { - hearing_scheduled_ama.where( - privacy_act_pending: true - ) + validated_hearing_scheduled_legacy_states.where( - privacy_act_pending: true - ) - } - - # Locates appeal states related to appeals with open InformalHearingPresentationTasks. - # In addition, these appeals have an open Privacy Act/FOIA request-related tasks in their trees. - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals with open InformalHearingPresentationTasks. - # have open Privacy Act/FOIA-related tasks in their task trees. - scope :ihp_pending_privacy_pending, lambda { - where( - vso_ihp_pending: true, - privacy_act_pending: true, - hearing_scheduled: false, - hearing_postponed: false, - scheduled_in_error: false, - hearing_withdrawn: false - ) - } - - # Locates appeal states related to appeals with open InformalHearingPresentationTasks. - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals with open InformalHearingPresentationTasks. - scope :ihp_pending, lambda { - where( - vso_ihp_pending: true, - privacy_act_pending: false, - hearing_scheduled: false, - hearing_postponed: false, - scheduled_in_error: false, - hearing_withdrawn: false - ) - } - - # Locates appeal states related to appeals with open Privacy Act/FOIA request-related tasks in their trees, - # however no other actions have taken place on the appeal (aside from perhaps docketing). - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals with open Privacy Act/FOIA request-related tasks - scope :privacy_pending, lambda { - where( - vso_ihp_pending: false, - privacy_act_pending: true, - hearing_scheduled: false, - hearing_postponed: false, - scheduled_in_error: false, - hearing_withdrawn: false - ) - } - - # Locates appeal states related to appeals that have either just been docketed, or have had their hearing withdrawn - # causing them to return to their initial state. - # - # @return [ActiveRecord::Relation] - # Appeal states for appeals that have been docketed and are awaiting further action. - scope :appeal_docketed, lambda { - where( - <<~SQL - appeal_docketed IS TRUE AND - hearing_postponed IS FALSE AND - scheduled_in_error IS FALSE AND - hearing_scheduled IS FALSE AND - ( - ( - hearing_withdrawn IS FALSE AND - vso_ihp_pending IS FALSE AND - privacy_act_pending IS FALSE - ) OR ( - hearing_withdrawn IS TRUE - ) - ) - SQL - ) - } - - # Purpose: Method to update appeal_state in the case of - # a mailed decision. - # - # Params: appeal_state - # - # Response: None - def decision_mailed_appeal_state_update_action! - update_appeal_state_action!(:decision_mailed) - end - - # Purpose: Method to update appeal_state in the case of - # a cancelled appeal. - # - # Params: appeal_state - # - # Response: None - def appeal_cancelled_appeal_state_update_action! - update_appeal_state_action!(:appeal_cancelled) - end - - # Purpose: Method to update appeal_state in the case of - # a completed informal hearing presentaiton(IHP). - # - # Params: appeal - # Params: None - # - # Response: None - def vso_ihp_complete_appeal_state_update_action! - if !appeal.active_vso_ihp_task? - update_appeal_state_action!(:vso_ihp_complete) - end - end - - # Purpose: Method to update appeal_state in the case of - # a privacy related tasks marked as complete. - # - # Params: appeal - # Params: None - # - # Response: None - def privacy_act_complete_appeal_state_update_action! - unless appeal.active_foia_task? - update!(privacy_act_pending: false, privacy_act_complete: true) - end - end - - # Purpose: Method to update appeal_state in the case of - # privacy related tasks being cancelled. - # - # Params: appeal - # Params: None - # - # Response: None - def privacy_act_cancelled_appeal_state_update_action! - unless appeal.active_foia_task? - update!(privacy_act_pending: false) - end - end - - # Purpose: Method to update appeal_state in the case of - # a docketed appeal. - # - # Params: None - # - # Response: None - def appeal_docketed_appeal_state_update_action! - update_appeal_state_action!(:appeal_docketed) - end - - # Purpose: Method to update appeal_state in the case of - # a hearing being postponed. - # - # Params: None - # - # Response: None - def hearing_postponed_appeal_state_update_action! - update_appeal_state_action!(:hearing_postponed) - end - - # Purpose: Method to update appeal_state in the case of - # a hearing being marked as having been held. - # - # Params: None - # - # Response: None - def hearing_held_appeal_state_update_action! - update!(hearing_scheduled: false) - end - - # Purpose: Method to update appeal_state in the case of - # a hearing being withdrawn. - # - # Params: None - # - # Response: None - def hearing_withdrawn_appeal_state_update_action! - update_appeal_state_action!(:hearing_withdrawn) - end - - # Purpose: Method to update appeal_state in the case of - # a hearing being scheduled. - # - # Params: None - # - # Response: None - def hearing_scheduled_appeal_state_update_action! - update_appeal_state_action!(:hearing_scheduled) - end - - # Purpose: Method to update appeal_state in the case of - # a hearing being scheduled in error. - # - # Params: None - # - # Response: None - def scheduled_in_error_appeal_state_update_action! - update_appeal_state_action!(:scheduled_in_error) - end - - # Purpose: Method to update appeal_state in the case of - # the most recent VSO IHP Organizational task in the task - # tree being in an opened state. - # - # Params: None - # - # Response: None - def vso_ihp_pending_appeal_state_update_action! - update_appeal_state_action!(:vso_ihp_pending) - end - - # Purpose: Method to update appeal_state in the case of - # the most recent VSO IHP Organizational task in the task - # tree being cancelled. - # - # Params: None - # - # Response: None - def vso_ihp_cancelled_appeal_state_update_action! - update!(vso_ihp_pending: false, vso_ihp_complete: false) - end - - # Purpose: Method to update appeal_state in the case of - # there being at least one of the privacy act related - # tasks is still in an opened status. - # - # Params: None - # - # Response: None - def privacy_act_pending_appeal_state_update_action! - update!(privacy_act_pending: true, privacy_act_complete: false) - end - - private - - # A base set of conditions for identifying if an appeal's most recent milestone was its - # hearing being scheduled. This scope can be utilized for any variation on this - # status, such as whether or not certain mail or FOIA tasks also exist for the appeal. - # - # @return [AppealState::ActiveRecord_Relation] - # An ActiveRecord_Relation that can be changes with other AR scopes, clauses, methods, etc.. - # in order to construct a SQL query. - scope :hearing_scheduled_base, lambda { - where( - hearing_scheduled: true, - hearing_postponed: false, - scheduled_in_error: false - ) - } - - # @return [AppealState::ActiveRecord_Relation] - # The base hearing scheduled status query scoped only to AMA appeals. - scope :hearing_scheduled_ama, lambda { - task_join.hearing_scheduled_base.where(appeal_type: "Appeal").with_assigned_assign_hearing_disposition_task - } - - # @return [AppealState::ActiveRecord_Relation] - # The base hearing scheduled status query scoped only to legacy appeals. - scope :hearing_scheduled_legacy_base, lambda { - hearing_scheduled_base.where(appeal_type: "LegacyAppeal") - } - - # Represents an inner join between the appeal_states and tasks tables. This allows for utilizing - # tasks to further inform us of where an appeal is in its lifecycle. - # - # @return [AppealState::ActiveRecord_Relation] - # An ActiveRecord_Relation that can be changes with other AR scopes, clauses, methods, etc.. - # in order to construct a SQL query. - scope :task_join, lambda { - joins( - "join tasks on tasks.appeal_id = appeal_states.appeal_id and tasks.appeal_type = appeal_states.appeal_type" - ) - } - - # Represents an inner join between the appeal_states and legacy_appeals tables. - # This association is used to then pull relevant data from VACOLS to validate an appeal's state. - # - # @return [AppealState::ActiveRecord_Relation] - # An ActiveRecord_Relation that can be changes with other AR scopes, clauses, methods, etc.. - # in order to construct a SQL query. - scope :legacy_appeals_join, lambda { - joins( - "join legacy_appeals on legacy_appeals.id = appeal_states.appeal_id " \ - "and appeal_states.appeal_type = 'LegacyAppeal'" - ) - } - - # A clause to enforce the need for an assigned AssignHearingDispositionTask to be - # associated with the same appeal as an appeal state record. - # - # If constraints are met, then it should mean that there is a pending hearing for the appeal - # that is waiting for a disposition, and therefore has not been held. This is key - # for us in determining which appeals are in a state of hearing_scheduled. - # - # At this time this task is not possible to be placed into a status of in_progress, and on_hold - # often means that it has a child EvidenceSubmissionWindowTask (as long as the evidence submission wasn't waived) - # and/or TranscriptionTask. This occurs after a hearing is held. - # - # @return [AppealState::ActiveRecord_Relation] - # An ActiveRecord_Relation that can be changes with other AR scopes, clauses, methods, etc.. - # in order to construct a SQL query. - scope :with_assigned_assign_hearing_disposition_task, lambda { - where( - "tasks.type = ? and tasks.status = ?", - AssignHearingDispositionTask.name, - Constants.TASK_STATUSES.assigned - ) - } - - class << self - # Utilizes the appeal states that we have recorded as being hearing_scheduled = true - # and then reaches out to VACOLS to validate that the related hearings do not yet have - # a disposition. - # - # This is to combat instances where VACOLS is updated without Caseflow's knowledge and other - # difficulties around synchronizing the appeals states table for legacy appeals and hearings. - # - # @note The in_groups_of size must not exceed 1k due to Oracle database limitations. - # - # @return [AppealState::ActiveRecord_Relation] - # Either an AR relation signifying appeal states where the hearing has been confirmed to have a pending - # disposition in VACOLS, or simply nothing (none). Regardless, the relation returned can be safely chained to - # other ActiveRecord query building methods. - def validated_hearing_scheduled_legacy_states - ids_to_validate = hearing_scheduled_legacy_base.legacy_appeals_join.pluck(:vacols_id) - validated_vacols_ids = [] - - ids_to_validate.in_groups_of(500, false) do |ids_to_examine| - validated_vacols_ids.concat(VACOLS::CaseHearing.where( - folder_nr: ids_to_examine, - hearing_disp: nil - ).pluck(:folder_nr)) - end - - return none if validated_vacols_ids.empty? - - where( - appeal_type: "LegacyAppeal", - appeal_id: LegacyAppeal.where(vacols_id: validated_vacols_ids).pluck(:id) - ) - end - end - - # :reek:FeatureEnvy - def update_appeal_state_action!(status_to_update) - update!({}.merge(DEFAULT_STATE).tap do |existing_statuses| - existing_statuses[status_to_update] = true - - if status_to_update == :appeal_cancelled - existing_statuses.merge!({ - privacy_act_complete: false, - privacy_act_pending: false - }) - end - end) - end end diff --git a/app/models/case_distribution_lever.rb b/app/models/case_distribution_lever.rb index 8d99040c380..b8d36733063 100644 --- a/app/models/case_distribution_lever.rb +++ b/app/models/case_distribution_lever.rb @@ -19,7 +19,6 @@ class CaseDistributionLever < ApplicationRecord #{Constants.DISTRIBUTION.batch_size_per_attorney} #{Constants.DISTRIBUTION.ama_direct_review_start_distribution_prior_to_goals} #{Constants.DISTRIBUTION.ama_hearing_case_affinity_days} - #{Constants.DISTRIBUTION.ama_hearing_case_aod_affinity_days} #{Constants.DISTRIBUTION.cavc_affinity_days} #{Constants.DISTRIBUTION.ama_evidence_submission_docket_time_goals} #{Constants.DISTRIBUTION.ama_hearings_docket_time_goals} diff --git a/app/models/concerns/appeal_concern.rb b/app/models/concerns/appeal_concern.rb index d7e28da2689..767c63be2e1 100644 --- a/app/models/concerns/appeal_concern.rb +++ b/app/models/concerns/appeal_concern.rb @@ -90,25 +90,6 @@ def representative_tz timezone_identifier_for_address(representative_address) end - # Checks for any active foia tasks on an appeal. - def active_foia_task? - tasks.open.where(type: [ - FoiaColocatedTask.name, - PrivacyActTask.name, - HearingAdminActionFoiaPrivacyRequestTask.name, - FoiaRequestMailTask.name, - PrivacyActRequestMailTask.name - ]).any? - end - - # Checks for any active vso ihp tasks on an appeal. - def active_vso_ihp_task? - tasks.open.where(type: [ - IhpColocatedTask.name, - InformalHearingPresentationTask.name - ]).any? - end - def accessible? # this is used for calling BGSService.can_access? to fix VSO access that is being blocked # by BGS returning false for veteran.accessible? when they should indeed have access to the appeal. diff --git a/app/models/concerns/distribution_concern.rb b/app/models/concerns/distribution_concern.rb index 82efe6006e1..982b14d5fb9 100644 --- a/app/models/concerns/distribution_concern.rb +++ b/app/models/concerns/distribution_concern.rb @@ -22,7 +22,7 @@ def assign_judge_tasks_for_appeals(appeals, judge) # If an appeal does not have an open DistributionTask, then it has already been distributed by automatic # case distribution and a new JudgeAssignTask should not be created. This should only occur if two users # request a distribution simultaneously. - next nil unless appeal.tasks.open.of_type(:DistributionTask).any? && appeal.active? + next nil unless appeal.tasks.open.of_type(:DistributionTask).any? distribution_task_assignee_id = appeal.tasks.of_type(:DistributionTask).first.assigned_to_id Rails.logger.info("Calling JudgeAssignTaskCreator for appeal #{appeal.id} with judge #{judge.css_id}") @@ -35,7 +35,7 @@ def assign_judge_tasks_for_appeals(appeals, judge) # Check for tasks which are open that we would not expect to see at the time of distribution. Send a slack # message for notification of a potential bug in part of the application, but do not stop the distribution def check_for_unexpected_tasks(appeal) - unless appeal.tasks.open.reject { |task| ALLOWABLE_TASKS.include?(task.class.name) }.empty? && appeal.active? + unless appeal.tasks.open.reject { |task| ALLOWABLE_TASKS.include?(task.class.name) }.empty? send_slack_notification(appeal) end end diff --git a/app/models/concerns/distribution_scopes.rb b/app/models/concerns/distribution_scopes.rb index ffa07fb72a9..c6485012127 100644 --- a/app/models/concerns/distribution_scopes.rb +++ b/app/models/concerns/distribution_scopes.rb @@ -8,9 +8,15 @@ module DistributionScopes # rubocop:disable Metrics/ModuleLength extend ActiveSupport::Concern - def with_appeal_affinities - joins("LEFT OUTER JOIN appeal_affinities ON appeals.uuid::text = appeal_affinities.case_id - and appeal_affinities.case_type = 'Appeal'") + def with_assigned_distribution_task_sql + # both `appeal_type` and `appeal_id` necessary due to composite index + <<~SQL + INNER JOIN tasks AS distribution_task + ON distribution_task.appeal_type = 'Appeal' + AND distribution_task.appeal_id = appeals.id + AND distribution_task.type = 'DistributionTask' + AND distribution_task.status = 'assigned' + SQL end # From docket.rb @@ -41,16 +47,16 @@ def include_aod_motions def ready_for_distribution joins(:tasks) - .where(tasks: { type: DistributionTask.name, status: Constants.TASK_STATUSES.assigned }) + .group("appeals.id") + .having("count(case when tasks.type = ? and tasks.status = ? then 1 end) >= ?", + DistributionTask.name, Constants.TASK_STATUSES.assigned, 1) end def genpop - with_appeal_affinities + join_distribution_tasks .with_original_appeal_and_judge_task .where( - "appeals.stream_type != ? - OR appeal_affinities.affinity_start_date <= ? - OR original_judge_task.assigned_to_id in (?)", + "appeals.stream_type != ? OR distribution_task.assigned_at <= ? OR original_judge_task.assigned_to_id in (?)", Constants.AMA_STREAM_TYPES.court_remand, CaseDistributionLever.cavc_affinity_days.days.ago, JudgeTeam.judges_with_exclude_appeals_from_affinity @@ -81,10 +87,9 @@ 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 + join_distribution_tasks .with_original_appeal_and_judge_task - .where("appeal_affinities.affinity_start_date > ? or appeal_affinities.affinity_start_date is null", - CaseDistributionLever.cavc_affinity_days.days.ago) + .where("distribution_task.assigned_at > ?", CaseDistributionLever.cavc_affinity_days.days.ago) .where(original_judge_task: { assigned_to_id: judge&.id }) end @@ -122,35 +127,38 @@ def most_recent_hearings end def tied_to_distribution_judge(judge) - with_appeal_affinities + join_distribution_tasks .where(hearings: { disposition: "held", judge_id: judge.id }) end def tied_to_ineligible_judge - with_appeal_affinities + join_distribution_tasks .where(hearings: { disposition: "held", judge_id: HearingRequestDistributionQuery.ineligible_judges_id_cache }) end def tied_to_judges_with_exclude_appeals_from_affinity - with_appeal_affinities + join_distribution_tasks .where(hearings: { disposition: "held", judge_id: JudgeTeam.judges_with_exclude_appeals_from_affinity }) end # If an appeal has exceeded the affinity, it should be returned to genpop. def expired_ama_affinity_cases(lever_days) where(hearings: { disposition: "held" }) - .where("appeal_affinities.affinity_start_date <= ?", lever_days.to_i.days.ago) + .where("distribution_task.assigned_at <= ?", lever_days.to_i.days.ago) end def affinitized_ama_affinity_cases(lever_days) - where("appeal_affinities.affinity_start_date > ? or appeal_affinities.affinity_start_date is null", - lever_days.to_i.days.ago) + where("distribution_task.assigned_at > ?", lever_days.to_i.days.ago) + end + + def join_distribution_tasks + joins(with_assigned_distribution_task_sql) end # Historical note: We formerly had not_tied_to_any_active_judge until CASEFLOW-1928, # when that distinction became irrelevant because cases become genpop after 30 days anyway. def not_tied_to_any_judge - with_appeal_affinities + join_distribution_tasks .where(hearings: { disposition: "held", judge_id: nil }) end diff --git a/app/models/docket.rb b/app/models/docket.rb index 389bcf5498a..d56e7bc2a13 100644 --- a/app/models/docket.rb +++ b/app/models/docket.rb @@ -14,11 +14,7 @@ def docket_type def appeals(priority: nil, genpop: nil, ready: nil, judge: nil) fail "'ready for distribution' value cannot be false" if ready == false - scope = docket_appeals - - # The `ready_for_distribution` scope will functionally add a filter for active appeals, and adding it here first - # will cause that scope to always return zero appeals. - scope = scope.active unless ready + scope = docket_appeals.active if ready scope = scope.ready_for_distribution @@ -44,7 +40,7 @@ def count(priority: nil, ready: nil) # currently this is used for reporting needs def ready_to_distribute_appeals - docket_appeals.ready_for_distribution + docket_appeals.active.ready_for_distribution end def genpop_priority_count @@ -63,12 +59,14 @@ def age_of_n_oldest_genpop_priority_appeals(num) appeals(priority: true, ready: true).limit(num).map(&:ready_for_distribution_at) end - def age_of_n_oldest_priority_appeals_available_to_judge(judge, num) - appeals(priority: true, ready: true, judge: judge).limit(num).map(&:receipt_date) + def age_of_n_oldest_priority_appeals_available_to_judge(_judge, num) + appeals(priority: true, ready: true).limit(num).map(&:receipt_date) end - def age_of_n_oldest_nonpriority_appeals_available_to_judge(judge, num) - appeals(priority: false, ready: true, judge: judge).limit(num).map(&:receipt_date) + # this method needs to have the same name as the method in legacy_docket.rb for by_docket_date_distribution, + # but the judge that is passed in isn't relevant here + def age_of_n_oldest_nonpriority_appeals_available_to_judge(_judge, num) + appeals(priority: false, ready: true).limit(num).map(&:receipt_date) end def age_of_oldest_priority_appeal diff --git a/app/models/dockets/legacy_docket.rb b/app/models/dockets/legacy_docket.rb index 4550400694b..fa54536d5b2 100644 --- a/app/models/dockets/legacy_docket.rb +++ b/app/models/dockets/legacy_docket.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true class LegacyDocket < Docket - def self.docket_type - "legacy" - end - def docket_type - self.class.docket_type + "legacy" end # currently this is used for reporting needs diff --git a/app/models/hearing.rb b/app/models/hearing.rb index cafe866bba5..82ab53e311b 100644 --- a/app/models/hearing.rb +++ b/app/models/hearing.rb @@ -32,12 +32,10 @@ class Hearing < CaseflowRecord include HearingConcern include HasHearingEmailRecipientsConcern - # VA Notify Hooks prepend HearingScheduled prepend HearingPostponed prepend HearingWithdrawn prepend HearingScheduledInError - prepend HearingHeld belongs_to :hearing_day belongs_to :appeal @@ -293,7 +291,6 @@ def update_appeal_states_on_hearing_update update_appeal_states_on_hearing_scheduled_in_error update_appeal_states_on_hearing_postponed update_appeal_states_on_hearing_withdrawn - update_appeal_states_on_hearing_held end def assign_created_by_user diff --git a/app/models/hearings/forms/hearing_update_form.rb b/app/models/hearings/forms/hearing_update_form.rb index fda1377fbee..a55149196b9 100644 --- a/app/models/hearings/forms/hearing_update_form.rb +++ b/app/models/hearings/forms/hearing_update_form.rb @@ -1,11 +1,8 @@ # frozen_string_literal: true class HearingUpdateForm < BaseHearingUpdateForm - # VA Notify Hooks prepend DocketHearingPostponed prepend DocketHearingWithdrawn - prepend DocketHearingHeld - attr_accessor :advance_on_docket_motion_attributes, :evidence_window_waived, :hearing_issue_notes_attributes, :transcript_sent_date, :transcription_attributes diff --git a/app/models/job_execution_time.rb b/app/models/job_execution_time.rb deleted file mode 100644 index 12d8ddbb964..00000000000 --- a/app/models/job_execution_time.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class JobExecutionTime < CaseflowRecord -end diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index be859405409..8ac8befc495 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -42,7 +42,6 @@ class LegacyAppeal < CaseflowRecord accepts_nested_attributes_for :worksheet_issues, allow_destroy: true has_one :appeal_state, as: :appeal has_many :vbms_uploaded_documents, as: :appeal - has_many :notifications, as: :notifiable class UnknownLocationError < StandardError; end @@ -348,10 +347,6 @@ def power_of_attorney end end - def appeal_affinity - VACOLS::Case.find_by(bfkey: vacols_id).appeal_affinity - end - ## BEGIN Hearing specific attributes and methods attr_writer :hearings @@ -963,10 +958,6 @@ def is_legacy? end # rubocop:enable Naming/PredicateName - def appeal_state - super || AppealState.find_or_create_by(appeal: self) - end - private def soc_eligible_for_opt_in?(receipt_date:, covid_flag: false) diff --git a/app/models/legacy_hearing.rb b/app/models/legacy_hearing.rb index b1c32759852..370ce6aa900 100644 --- a/app/models/legacy_hearing.rb +++ b/app/models/legacy_hearing.rb @@ -35,13 +35,10 @@ class LegacyHearing < CaseflowRecord include UpdatedByUserConcern include HearingConcern include HasHearingEmailRecipientsConcern - - # VA Notify Hooks prepend HearingScheduled prepend HearingWithdrawn prepend HearingPostponed prepend HearingScheduledInError - prepend HearingHeld # When these instance variable getters are called, first check if we've # fetched the values from VACOLS. If not, first fetch all values and save them @@ -400,7 +397,6 @@ def update_appeal_states_on_hearing_update update_appeal_states_on_hearing_scheduled_in_error update_appeal_states_on_hearing_postponed update_appeal_states_on_hearing_withdrawn - update_appeal_states_on_hearing_held end def assign_created_by_user diff --git a/app/models/prepend/va_notify/appeal_cancelled.rb b/app/models/prepend/va_notify/appeal_cancelled.rb index 886d55f2823..408c8c289b5 100644 --- a/app/models/prepend/va_notify/appeal_cancelled.rb +++ b/app/models/prepend/va_notify/appeal_cancelled.rb @@ -8,6 +8,9 @@ module AppealCancelled extend AppellantNotification + # rubocop:disable all + @@template_name = "Appeal Cancelled" + # rubocop:enable all # Original Method in app/models/task.rb # Purpose: Update Record in Appeal States Table @@ -18,7 +21,12 @@ module AppealCancelled def update_appeal_state_when_appeal_cancelled if ["RootTask"].include?(type) && status == Constants.TASK_STATUSES.cancelled - appeal.appeal_state.appeal_cancelled_appeal_state_update_action! + MetricsService.record("Updating APPEAL_CANCELLED column in Appeal States Table to TRUE "\ + "for #{appeal.class} ID #{appeal.id}", + service: :queue, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "appeal_cancelled") + end end end end diff --git a/app/models/prepend/va_notify/appeal_decision_mailed.rb b/app/models/prepend/va_notify/appeal_decision_mailed.rb index 708af3e4955..baaa752660c 100644 --- a/app/models/prepend/va_notify/appeal_decision_mailed.rb +++ b/app/models/prepend/va_notify/appeal_decision_mailed.rb @@ -3,9 +3,12 @@ # Module to notify appellant if an Appeal Decision is Mailed module AppealDecisionMailed extend AppellantNotification + # rubocop:disable all + @@template_name = "Appeal decision mailed" - CONTESTED_CLAIM = Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_contested_claims - NON_CONTESTED_CLAIM = Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims + CONTESTED_CLAIM = "#{@@template_name} (Contested claims)" + NON_CONTESTED_CLAIM = "#{@@template_name} (Non-contested claims)" + # rubocop:enable all # Purpose: Adds VA Notify integration to the original method defined in app/models/decision_document.rb # @@ -15,7 +18,7 @@ module AppealDecisionMailed def process!(mail_package = nil) super_return_value = super if processed? - appeal.appeal_state.decision_mailed_appeal_state_update_action! + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "decision_mailed") case appeal_type when "Appeal" template = appeal.contested_claim? ? CONTESTED_CLAIM : NON_CONTESTED_CLAIM diff --git a/app/models/prepend/va_notify/appeal_docketed.rb b/app/models/prepend/va_notify/appeal_docketed.rb index a9df03b8972..36e98bca385 100644 --- a/app/models/prepend/va_notify/appeal_docketed.rb +++ b/app/models/prepend/va_notify/appeal_docketed.rb @@ -19,6 +19,9 @@ # Module to notify appellant when an appeal gets docketed module AppealDocketed extend AppellantNotification + # rubocop:disable all + @@template_name = "Appeal docketed" + # rubocop:enable all # original method defined in app/models/appeal.rb @@ -36,7 +39,7 @@ def create_tasks_on_intake_success! "for #{self.class} ID #{self.id}", service: nil, name: "AppellantNotification.notify_appellant") do - AppellantNotification.notify_appellant(self, Constants.EVENT_TYPE_FILTERS.appeal_docketed) + AppellantNotification.notify_appellant(self, @@template_name) end end super_return_value @@ -56,7 +59,7 @@ def docket_appeal "for #{appeal.class} ID #{appeal.id}", service: nil, name: "AppellantNotification.notify_appellant") do - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.appeal_docketed) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -70,7 +73,12 @@ def docket_appeal # Response: Update 'appeal_docketed' column to True def update_appeal_state_when_appeal_docketed if type == "DistributionTask" - appeal.appeal_state.appeal_docketed_appeal_state_update_action! + MetricsService.record("Updating APPEAL_DOCKETED column in Appeal States Table to TRUE for #{appeal.class} "\ + "ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "appeal_docketed") + end end end end diff --git a/app/models/prepend/va_notify/appellant_notification.rb b/app/models/prepend/va_notify/appellant_notification.rb index 77e4df6ec8b..12988bd712e 100644 --- a/app/models/prepend/va_notify/appellant_notification.rb +++ b/app/models/prepend/va_notify/appellant_notification.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true # Module containing Aspect Overrides to Classes used to Track Statuses for Appellant Notification +# rubocop:disable Metrics/ModuleLength module AppellantNotification extend ActiveSupport::Concern class NoParticipantIdError < StandardError @@ -24,19 +25,143 @@ def status end class NoAppealError < StandardError; end - + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity def self.handle_errors(appeal) fail NoAppealError if appeal.nil? message_attributes = {} message_attributes[:appeal_type] = appeal.class.to_s - message_attributes[:appeal_id] = appeal.external_id + message_attributes[:appeal_id] = (appeal.class.to_s == "Appeal") ? appeal.uuid : appeal.vacols_id message_attributes[:participant_id] = appeal.claimant_participant_id claimant = get_claimant(appeal) - AppellantNotification.error_handling_messages_and_attributes(appeal, claimant, message_attributes) + begin + if claimant.nil? + fail NoClaimantError, message_attributes[:appeal_id] + elsif message_attributes[:participant_id] == "" || message_attributes[:participant_id].nil? + fail NoParticipantIdError, message_attributes[:appeal_id] + elsif appeal.veteran_appellant_deceased? + message_attributes[:status] = "Failure Due to Deceased" + else + message_attributes[:status] = "Success" + end + rescue StandardError => error + Rails.logger.error("#{error.message}\n#{error.backtrace.join("\n")}") + message_attributes[:status] = error.status + end + message_attributes end + # Public: Updates/creates appeal state based on event type + # + # appeal - appeal that was found in appeal_mapper + # event - The module that is being triggered to send a notification + # + # Examples + # + # AppellantNotification.update_appeal_state(appeal, "hearing_postponed") + # # => A new appeal state is created if it doesn't exist + # or the existing appeal state is updated, then appeal_state.hearing_postponed becomes true + + # rubocop:disable Metrics/AbcSize + def self.update_appeal_state(appeal, event) + appeal_type = appeal.class.to_s + appeal_state = AppealState.find_by(appeal_id: appeal.id, appeal_type: appeal_type) || + AppealState.create!(appeal_id: appeal.id, appeal_type: appeal_type) + case event + when "decision_mailed" + appeal_state.update!( + decision_mailed: true, + appeal_docketed: false, + hearing_postponed: false, + hearing_withdrawn: false, + hearing_scheduled: false, + vso_ihp_pending: false, + vso_ihp_complete: false, + privacy_act_pending: false, + privacy_act_complete: false + ) + when "appeal_docketed" + appeal_state.update!(appeal_docketed: true) + when "appeal_cancelled" + appeal_state.update!( + decision_mailed: false, + appeal_docketed: false, + hearing_postponed: false, + hearing_withdrawn: false, + hearing_scheduled: false, + vso_ihp_pending: false, + vso_ihp_complete: false, + privacy_act_pending: false, + privacy_act_complete: false, + scheduled_in_error: false, + appeal_cancelled: true + ) + when "hearing_postponed" + appeal_state.update!(hearing_postponed: true, hearing_scheduled: false) + when "hearing_withdrawn" + appeal_state.update!(hearing_withdrawn: true, hearing_postponed: false, hearing_scheduled: false) + when "hearing_scheduled" + appeal_state.update!(hearing_scheduled: true, hearing_postponed: false, scheduled_in_error: false) + when "scheduled_in_error" + appeal_state.update!(scheduled_in_error: true, hearing_scheduled: false) + when "vso_ihp_pending" + appeal_state.update!(vso_ihp_pending: true, vso_ihp_complete: false) + when "vso_ihp_cancelled" + appeal_state.update!(vso_ihp_pending: false, vso_ihp_complete: false) + when "vso_ihp_complete" + # Only updates appeal state if ALL ihp tasks are completed + if appeal.tasks.open.where(type: IhpColocatedTask.name).empty? && + appeal.tasks.open.where(type: InformalHearingPresentationTask.name).empty? + appeal_state.update!(vso_ihp_complete: true, vso_ihp_pending: false) + end + when "privacy_act_pending" + appeal_state.update!(privacy_act_pending: true, privacy_act_complete: false) + when "privacy_act_complete" + # Only updates appeal state if ALL privacy act tasks are completed + open_tasks = appeal.tasks.open + if open_tasks.where(type: FoiaColocatedTask.name).empty? && + open_tasks.where(type: PrivacyActTask.name).empty? && + open_tasks.where(type: HearingAdminActionFoiaPrivacyRequestTask.name).empty? && + open_tasks.where(type: FoiaRequestMailTask.name).empty? && + open_tasks.where(type: PrivacyActRequestMailTask.name).empty? + appeal_state.update!(privacy_act_complete: true, privacy_act_pending: false) + end + when "privacy_act_cancelled" + # Only updates appeal state if ALL privacy act tasks are completed + open_tasks = appeal.tasks.open + if open_tasks.where(type: FoiaColocatedTask.name).empty? && open_tasks.where(type: PrivacyActTask.name).empty? && + open_tasks.where(type: HearingAdminActionFoiaPrivacyRequestTask.name).empty? && + open_tasks.where(type: FoiaRequestMailTask.name).empty? && + open_tasks.where(type: PrivacyActRequestMailTask.name).empty? + appeal_state.update!(privacy_act_pending: false) + end + end + end + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/AbcSize + # Public: Finds the appeal based on the id and type, then calls update_appeal_state to create/update appeal state + # + # appeal_id - id of appeal + # appeal_type - string of appeal object's class (e.g. "LegacyAppeal") + # event - The module that is being triggered to send a notification + # + # Examples + # + # AppellantNotification.appeal_mapper(1, "Appeal", "hearing_postponed") + # # => A new appeal state is created if it doesn't exist + # or the existing appeal state is updated, then appeal_state.hearing_postponed becomes true + + def self.appeal_mapper(appeal_id, appeal_type, event) + if appeal_type == "Appeal" + appeal = Appeal.find_by(id: appeal_id) + AppellantNotification.update_appeal_state(appeal, event) + elsif appeal_type == "LegacyAppeal" + appeal = LegacyAppeal.find_by(id: appeal_id) + AppellantNotification.update_appeal_state(appeal, event) + else + Rails.logger.error("Appeal type not supported for " + event) + end + end # Purpose: Method to check appeal state for statuses and send out a notification based on # which statuses are turned on in the appeal state # @@ -45,6 +170,7 @@ def self.handle_errors(appeal) # appeal_status (only used for quarterly notifications) # # Response: Create notification and return it to SendNotificationJob + # rubocop:disable Metrics/CyclomaticComplexity def self.notify_appellant( appeal, @@ -52,49 +178,57 @@ def self.notify_appellant( appeal_status = nil ) msg_bdy = create_payload(appeal, template_name, appeal_status) + appeal_docketed_event_enabled = FeatureToggle.enabled?(:appeal_docketed_event) + + return nil if template_name == "Appeal docketed" && + !appeal_docketed_event_enabled && + msg_bdy.appeal_type == "LegacyAppeal" - if template_name == "Appeal docketed" && msg_bdy.appeal_type == "LegacyAppeal" + if template_name == "Appeal docketed" && appeal_docketed_event_enabled && msg_bdy.appeal_type == "LegacyAppeal" Notification.create!( appeals_id: msg_bdy.appeal_id, appeals_type: msg_bdy.appeal_type, event_type: template_name, - notification_type: "Email and SMS", + notification_type: notification_type, participant_id: msg_bdy.participant_id, - event_date: Time.zone.today, - notifiable: appeal + event_date: Time.zone.today ) end SendNotificationJob.perform_later(msg_bdy.to_json) end + # rubocop:enable Metrics/CyclomaticComplexity def self.create_payload(appeal, template_name, appeal_status = nil) message_attributes = AppellantNotification.handle_errors(appeal) VANotifySendMessageTemplate.new(message_attributes, template_name, appeal_status) end - def self.get_claimant(appeal) - if appeal.is_a?(Appeal) - appeal.claimant - elsif appeal.is_a?(LegacyAppeal) - appeal.appellant_is_not_veteran ? appeal.person_for_appellant : appeal.veteran - end + def self.notification_type + notification_type = + if FeatureToggle.enabled?(:va_notify_email) && FeatureToggle.enabled?(:va_notify_sms) + "Email and SMS" + elsif FeatureToggle.enabled?(:va_notify_email) + "Email" + elsif FeatureToggle.enabled?(:va_notify_sms) + "SMS" + else + "None" + end + notification_type end - def self.error_handling_messages_and_attributes(appeal, claimant, message_attributes) - begin - if claimant.nil? - fail NoClaimantError, message_attributes[:appeal_id] - elsif message_attributes[:participant_id].blank? - fail NoParticipantIdError, message_attributes[:appeal_id] - elsif appeal.veteran_appellant_deceased? - message_attributes[:status] = "Failure Due to Deceased" - else - message_attributes[:status] = "Success" + def self.get_claimant(appeal) + appeal_type = appeal.class.to_s + participant_id = appeal.claimant_participant_id + claimant = + if appeal_type == "Appeal" + appeal.claimant + elsif appeal_type == "LegacyAppeal" + veteran = Veteran.find_by(participant_id: participant_id) + person = Person.find_by(participant_id: participant_id) + appeal.appellant_is_not_veteran ? person : veteran end - rescue StandardError => error - Rails.logger.error("#{error.message}\n#{error.backtrace.join("\n")}") - message_attributes[:status] = error.status - end - message_attributes + claimant end end +# rubocop:enable Metrics/ModuleLength diff --git a/app/models/prepend/va_notify/docket_hearing_held.rb b/app/models/prepend/va_notify/docket_hearing_held.rb deleted file mode 100644 index eeca47f8c7b..00000000000 --- a/app/models/prepend/va_notify/docket_hearing_held.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -# == Overview -# -# This module is used to intercept events triggered via the Daily Docket page to place a 'Held' -# disposition onto a hearing. -module DocketHearingHeld - # If a hearing is being assigned a disposition of 'Held' then this method will ensure that the - # hearing's appeal's appeal_states record has its hearing_scheduled attribute set back to false, - # as the appeal's latest milestone is no longer that its hearing has been scheduled, but rather that it's - # awaiting a decision. - # - # @return [AdvanceOnDocketMotion] - # If advance_on_docket_motion_attributes is non-nil. - # @see HearingsController#advance_on_docket_motion_params for information on what these params/attributes are. - # @return [nil] - # If advance_on_docket_motion_attributes is nil/blank. - def update_hearing - super_return_value = super - - if hearing_updates[:disposition] == Constants.HEARING_DISPOSITION_TYPES.held - hearing.appeal.appeal_state.hearing_held_appeal_state_update_action! - end - - super_return_value - end -end diff --git a/app/models/prepend/va_notify/docket_hearing_postponed.rb b/app/models/prepend/va_notify/docket_hearing_postponed.rb index c691869b0dd..ca792c7cb6f 100644 --- a/app/models/prepend/va_notify/docket_hearing_postponed.rb +++ b/app/models/prepend/va_notify/docket_hearing_postponed.rb @@ -4,13 +4,16 @@ # For postponed hearings from daily docket page for AMA appeals module DocketHearingPostponed extend AppellantNotification + # rubocop:disable all + @@template_name = "Postponement of hearing" + # rubocop:enable all # AMA Hearing Postponed from the Daily Docket # original method defined in app/models/hearings/forms/hearing_update_form.rb def update_hearing super_return_value = super if hearing_updates[:disposition] == Constants.HEARING_DISPOSITION_TYPES.postponed - AppellantNotification.notify_appellant(hearing.appeal, Constants.EVENT_TYPE_FILTERS.postponement_of_hearing) + AppellantNotification.notify_appellant(hearing.appeal, @@template_name) end super_return_value end diff --git a/app/models/prepend/va_notify/docket_hearing_withdrawn.rb b/app/models/prepend/va_notify/docket_hearing_withdrawn.rb index 096e894ad3c..fbc74bf29f7 100644 --- a/app/models/prepend/va_notify/docket_hearing_withdrawn.rb +++ b/app/models/prepend/va_notify/docket_hearing_withdrawn.rb @@ -4,13 +4,16 @@ # For withdrawn hearings from daily docket page for AMA appeals module DocketHearingWithdrawn extend AppellantNotification + # rubocop:disable all + @@template_name = "Withdrawal of hearing" + # rubocop:enable all # AMA Hearing Withdrawn from the Daily Docket # original method defined in app/models/hearings/forms/hearing_update_form.rb def update_hearing super_return_value = super if hearing_updates[:disposition] == Constants.HEARING_DISPOSITION_TYPES.cancelled - AppellantNotification.notify_appellant(hearing.appeal, Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing) + AppellantNotification.notify_appellant(hearing.appeal, @@template_name) end super_return_value end diff --git a/app/models/prepend/va_notify/hearing_held.rb b/app/models/prepend/va_notify/hearing_held.rb deleted file mode 100644 index e49a7a8455e..00000000000 --- a/app/models/prepend/va_notify/hearing_held.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -# == Overview -# -# This module is used to intercept events triggered either on the Daily Docket or Case Details pages -# that cause a hearing's state to shift (and by extension the appeal's state also). It is particularly -# set up to look for instances where a hearing is being marked with a "Held" disposition. -module HearingHeld - # Legacy Hearing Postponed from the Daily Docket - # original method defined in app/models/legacy_hearing.rb - def update_caseflow_and_vacols(hearing_hash) - original_disposition = vacols_record.hearing_disp - super_return_value = super - new_disposition = vacols_record.hearing_disp - if new_disposition == "H" && original_disposition != new_disposition - appeal = LegacyAppeal.find(appeal_id) - - appeal&.appeal_state&.hearing_held_appeal_state_update_action! - end - super_return_value - end - - # Legacy OR AMA Hearing Marked as "Held" from Queue - # original method defined in app/models/tasks/assign_hearing_disposition_task.rb - def update_hearing(hearing_hash) - super_return_value = super - - if hearing_hash[:disposition] == Constants.HEARING_DISPOSITION_TYPES.held - appeal.appeal_state.hearing_held_appeal_state_update_action! - end - - super_return_value - end - - # Purpose: Callback method when a hearing updates to also update appeal_states table - # - # Params: none - # - # Response: none - def update_appeal_states_on_hearing_held - appeal.appeal_state.hearing_held_appeal_state_update_action! if ama_hearing_held? || legacy_hearing_held? - end - - private - - # Checks to see if the current object is an instance of a Hearing, and if its disposition has - # been set to "Held". - # - # @return [Boolean] - # True if self is an AMA hearing and its disposition is set to "Held". False otherwise. - def ama_hearing_held? - is_a?(Hearing) && disposition == Constants.HEARING_DISPOSITION_TYPES.held - end - - # Checks to see if the current object is an instance of a LegacyHearing, and if its disposition has - # been set to "Held". - # - # @note The dispotion for a legacy hearing is located in the HEARSCHED table's hearing_disp column in - # in the VACOLS database. - # - # @return [Boolean] - # True if self is an AMA hearing and its disposition is set to "Held". False otherwise. - def legacy_hearing_held? - is_a?(LegacyHearing) && VACOLS::CaseHearing.find_by(hearing_pkseq: vacols_id)&.hearing_disp == "H" - end -end diff --git a/app/models/prepend/va_notify/hearing_postponed.rb b/app/models/prepend/va_notify/hearing_postponed.rb index 24beea63048..f6544033a5a 100644 --- a/app/models/prepend/va_notify/hearing_postponed.rb +++ b/app/models/prepend/va_notify/hearing_postponed.rb @@ -3,6 +3,9 @@ # Module to notify appellant if Hearing is Postponed module HearingPostponed extend AppellantNotification + # rubocop:disable all + @@template_name = "Postponement of hearing" + # rubocop:enable all # Legacy Hearing Postponed from the Daily Docket # original method defined in app/models/legacy_hearing.rb @@ -12,7 +15,7 @@ def update_caseflow_and_vacols(hearing_hash) new_disposition = vacols_record.hearing_disp if postponed? && original_disposition != new_disposition appeal = LegacyAppeal.find(appeal_id) - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.postponement_of_hearing) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -22,7 +25,7 @@ def update_caseflow_and_vacols(hearing_hash) def update_hearing(hearing_hash) super_return_value = super if hearing_hash[:disposition] == Constants.HEARING_DISPOSITION_TYPES.postponed && appeal.class.to_s == "Appeal" - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.postponement_of_hearing) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -32,15 +35,23 @@ def update_hearing(hearing_hash) # Params: none # # Response: none + # rubocop:disable Metrics/AbcSize def update_appeal_states_on_hearing_postponed if is_a?(LegacyHearing) if VACOLS::CaseHearing.find_by(hearing_pkseq: vacols_id)&.hearing_disp == "P" - appeal.appeal_state.hearing_postponed_appeal_state_update_action! + MetricsService.record("Updating HEARING_POSTPONED in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "hearing_postponed") + end end elsif is_a?(Hearing) if disposition == Constants.HEARING_DISPOSITION_TYPES.postponed - appeal.appeal_state.hearing_postponed_appeal_state_update_action! + MetricsService.record("Updating HEARING_POSTPONED in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "hearing_postponed") + end end end end + # rubocop:enable Metrics/AbcSize end diff --git a/app/models/prepend/va_notify/hearing_scheduled.rb b/app/models/prepend/va_notify/hearing_scheduled.rb index 8d08bb89b6a..c82855ae9a0 100644 --- a/app/models/prepend/va_notify/hearing_scheduled.rb +++ b/app/models/prepend/va_notify/hearing_scheduled.rb @@ -3,11 +3,14 @@ # Module to notify appellant if Hearing is Scheduled module HearingScheduled extend AppellantNotification + # rubocop:disable all + @@template_name = "Hearing scheduled" + # rubocop:enable all def create_hearing(task_values) # original method defined in app/models/tasks/schedule_hearing_task.rb super_return_value = super - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.hearing_scheduled) + AppellantNotification.notify_appellant(appeal, @@template_name) super_return_value end @@ -17,6 +20,9 @@ def create_hearing(task_values) # # Response: none def update_appeal_states_on_hearing_scheduled - appeal.appeal_state.hearing_scheduled_appeal_state_update_action! + MetricsService.record("Updating HEARING_SCHEDULED in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "hearing_scheduled") + end end end diff --git a/app/models/prepend/va_notify/hearing_scheduled_in_error.rb b/app/models/prepend/va_notify/hearing_scheduled_in_error.rb index 3bfb3e2d7cc..d7f7f91f536 100644 --- a/app/models/prepend/va_notify/hearing_scheduled_in_error.rb +++ b/app/models/prepend/va_notify/hearing_scheduled_in_error.rb @@ -11,15 +11,23 @@ module HearingScheduledInError # Params: none # # Response: none + # rubocop:disable Metrics/AbcSize def update_appeal_states_on_hearing_scheduled_in_error if is_a?(LegacyHearing) if VACOLS::CaseHearing.find_by(hearing_pkseq: vacols_id)&.hearing_disp == "E" - appeal.appeal_state.scheduled_in_error_appeal_state_update_action! + MetricsService.record("Updating SCHEDULED_IN_ERROR in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "scheduled_in_error") + end end elsif is_a?(Hearing) if disposition == Constants.HEARING_DISPOSITION_TYPES.scheduled_in_error - appeal.appeal_state.scheduled_in_error_appeal_state_update_action! + MetricsService.record("Updating SCHEDULED_IN_ERROR in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "scheduled_in_error") + end end end end + # rubocop:enable Metrics/AbcSize end diff --git a/app/models/prepend/va_notify/hearing_withdrawn.rb b/app/models/prepend/va_notify/hearing_withdrawn.rb index 489eae64dbb..82269ad8f03 100644 --- a/app/models/prepend/va_notify/hearing_withdrawn.rb +++ b/app/models/prepend/va_notify/hearing_withdrawn.rb @@ -3,13 +3,16 @@ # Module to notify appellant if Hearing is Withdrawn module HearingWithdrawn extend AppellantNotification + # rubocop:disable all + @@template_name = "Withdrawal of hearing" + # rubocop:enable all # Legacy OR AMA Hearing Withdrawn from Queue # original method defined in app/models/tasks/assign_hearing_disposition_task.rb def update_hearing(hearing_hash) super_return_value = super if hearing_hash[:disposition] == Constants.HEARING_DISPOSITION_TYPES.cancelled && appeal.class.to_s == "Appeal" - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -22,7 +25,7 @@ def update_caseflow_and_vacols(hearing_hash) new_disposition = vacols_record.hearing_disp if cancelled? && original_disposition != new_disposition appeal = LegacyAppeal.find(appeal_id) - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -32,15 +35,23 @@ def update_caseflow_and_vacols(hearing_hash) # Params: none # # Response: none + # rubocop:disable Metrics/AbcSize def update_appeal_states_on_hearing_withdrawn if is_a?(LegacyHearing) if VACOLS::CaseHearing.find_by(hearing_pkseq: vacols_id)&.hearing_disp == "C" - appeal.appeal_state.hearing_withdrawn_appeal_state_update_action! + MetricsService.record("Updating HEARING_WITHDRAWN in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "hearing_withdrawn") + end end elsif is_a?(Hearing) if disposition == Constants.HEARING_DISPOSITION_TYPES.cancelled - appeal.appeal_state.hearing_withdrawn_appeal_state_update_action! + MetricsService.record("Updating HEARING_WITHDRAWN in Appeal States Table for #{appeal.class} ID #{appeal.id}", + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "hearing_withdrawn") + end end end end + # rubocop:enable Metrics/AbcSize end diff --git a/app/models/prepend/va_notify/ihp_task_cancelled.rb b/app/models/prepend/va_notify/ihp_task_cancelled.rb index ae1d3f3722b..908cb8084c5 100644 --- a/app/models/prepend/va_notify/ihp_task_cancelled.rb +++ b/app/models/prepend/va_notify/ihp_task_cancelled.rb @@ -25,7 +25,12 @@ def update_appeal_state_when_ihp_cancelled if IHP_TYPE_TASKS.include?(type) && !IHP_TYPE_TASKS.include?(parent&.type) && status == Constants.TASK_STATUSES.cancelled - appeal.appeal_state.vso_ihp_cancelled_appeal_state_update_action! + MetricsService.record("Updating VSO_IHP_PENDING column to FALSE & VSO_IHP_COMPLETE column to FALSE in"\ + " Appeal States Table for #{appeal.class} ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "vso_ihp_cancelled") + end end end end diff --git a/app/models/prepend/va_notify/ihp_task_complete.rb b/app/models/prepend/va_notify/ihp_task_complete.rb index 92f2935a964..98f17167f1b 100644 --- a/app/models/prepend/va_notify/ihp_task_complete.rb +++ b/app/models/prepend/va_notify/ihp_task_complete.rb @@ -12,6 +12,9 @@ # within the Appeal States table updated to be TRUE. module IhpTaskComplete extend AppellantNotification + # rubocop:disable all + @@template_name = "VSO IHP complete" + # rubocop:enable all # All variants of IHP Tasks IHP_TYPE_TASKS = %w[IhpColocatedTask InformalHearingPresentationTask].freeze @@ -31,7 +34,7 @@ def update_from_params(params, user) "ID #{appeal.id}", service: nil, name: "AppellantNotification.notify_appellant") do - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.vso_ihp_complete) + AppellantNotification.notify_appellant(appeal, @@template_name) end end super_return_value @@ -48,7 +51,12 @@ def update_appeal_state_when_ihp_completed if IHP_TYPE_TASKS.include?(type) && !IHP_TYPE_TASKS.include?(parent&.type) && status == Constants.TASK_STATUSES.completed - appeal.appeal_state.vso_ihp_complete_appeal_state_update_action! + MetricsService.record("Updating VSO_IHP_COMPLETED column to TRUE & VSO_IHP_PENDING column to FALSE in Appeal"\ + " States Table for #{appeal.class} ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "vso_ihp_complete") + end end end end diff --git a/app/models/prepend/va_notify/ihp_task_pending.rb b/app/models/prepend/va_notify/ihp_task_pending.rb index 6271c77ca4e..5d6ea9d83eb 100644 --- a/app/models/prepend/va_notify/ihp_task_pending.rb +++ b/app/models/prepend/va_notify/ihp_task_pending.rb @@ -16,6 +16,9 @@ module IhpTaskPending extend AppellantNotification + # rubocop:disable all + @@template_name = "VSO IHP pending" + # rubocop:enable all # All variants of IHP Tasks IHP_TYPE_TASKS = %w[IhpColocatedTask InformalHearingPresentationTask].freeze @@ -35,7 +38,7 @@ def create_ihp_tasks! "for #{@parent.appeal.class} ID #{@parent.appeal.id}", service: nil, name: "AppellantNotification.notify_appellant") do - AppellantNotification.notify_appellant(@parent.appeal, Constants.EVENT_TYPE_FILTERS.vso_ihp_pending) + AppellantNotification.notify_appellant(@parent.appeal, @@template_name) end end super_return_value @@ -58,7 +61,7 @@ def create_from_params(params, user) "ID #{appeal.id}", service: nil, name: "AppellantNotification.notify_appellant") do - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.vso_ihp_pending) + AppellantNotification.notify_appellant(appeal, @@template_name) end end super_return_value @@ -73,7 +76,12 @@ def create_from_params(params, user) # Response: Update 'vso_ihp_pending' column to True def update_appeal_state_when_ihp_created if IHP_TYPE_TASKS.include?(type) - appeal.appeal_state.vso_ihp_pending_appeal_state_update_action! + MetricsService.record("Updating VSO_IHP_PENDING column to TRUE & VSO_IHP_COMPLETE column to FALSE in"\ + " Appeal States Table for #{appeal.class} ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "vso_ihp_pending") + end end end end diff --git a/app/models/prepend/va_notify/privacy_act_cancelled.rb b/app/models/prepend/va_notify/privacy_act_cancelled.rb index 1e0d9ba6119..68735c1509b 100644 --- a/app/models/prepend/va_notify/privacy_act_cancelled.rb +++ b/app/models/prepend/va_notify/privacy_act_cancelled.rb @@ -18,7 +18,12 @@ def update_appeal_state_when_privacy_act_cancelled if PRIVACY_ACT_TASKS.include?(type) && !PRIVACY_ACT_TASKS.include?(parent&.type) && status == Constants.TASK_STATUSES.cancelled - appeal.appeal_state.privacy_act_cancelled_appeal_state_update_action! + MetricsService.record("Updating PRIVACY_ACT_PENDING column in Appeal States Table to FALSE "\ + "for #{appeal.class} ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "privacy_act_cancelled") + end end end end diff --git a/app/models/prepend/va_notify/privacy_act_complete.rb b/app/models/prepend/va_notify/privacy_act_complete.rb index f07e0f432e4..16ceabbaa59 100644 --- a/app/models/prepend/va_notify/privacy_act_complete.rb +++ b/app/models/prepend/va_notify/privacy_act_complete.rb @@ -3,7 +3,9 @@ # Module to notify appellant if Privacy Act Request is Completed module PrivacyActComplete extend AppellantNotification - + # rubocop:disable all + @@template_name = "Privacy Act request complete" + # rubocop:enable all PRIVACY_ACT_TASKS = %w[FoiaColocatedTask PrivacyActTask HearingAdminActionFoiaPrivacyRequestTask PrivacyActRequestMailTask FoiaRequestMailTask].freeze @@ -14,7 +16,7 @@ def update_status_if_children_tasks_are_closed(child_task) (type.to_s.include?("PrivacyAct") && !parent&.type.to_s.include?("PrivacyAct"))) && status == Constants.TASK_STATUSES.completed # appellant notification call - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -25,7 +27,7 @@ def update_with_instructions(params) super_return_value = super if type.to_s == "PrivacyActTask" && assigned_to_type == "Organization" && status == Constants.TASK_STATUSES.completed - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete) + AppellantNotification.notify_appellant(appeal, @@template_name) end super_return_value end @@ -34,7 +36,13 @@ def update_appeal_state_when_privacy_act_complete if PRIVACY_ACT_TASKS.include?(type) && !PRIVACY_ACT_TASKS.include?(parent&.type) && status == Constants.TASK_STATUSES.completed - appeal.appeal_state.privacy_act_complete_appeal_state_update_action! + MetricsService.record("updating PRIVACY_ACT_COMPLETE column to true and + PRIVACY_ACT_PENDING column in Appeal States Table to FALSE "\ + "for #{appeal.class} ID #{appeal.id} if no pending Privacy Acts exist", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "privacy_act_complete") + end end end end diff --git a/app/models/prepend/va_notify/privacy_act_pending.rb b/app/models/prepend/va_notify/privacy_act_pending.rb index 81e95cdf55f..1e5b34b4e67 100644 --- a/app/models/prepend/va_notify/privacy_act_pending.rb +++ b/app/models/prepend/va_notify/privacy_act_pending.rb @@ -3,7 +3,9 @@ # Module to notify appellant if Privacy Act Request is Pending module PrivacyActPending extend AppellantNotification - + # rubocop:disable all + @@template_name = "Privacy Act request pending" + # rubocop:enable all PRIVACY_ACT_TASKS = %w[FoiaColocatedTask PrivacyActTask HearingAdminActionFoiaPrivacyRequestTask PrivacyActRequestMailTask FoiaRequestMailTask].freeze @@ -11,7 +13,17 @@ module PrivacyActPending def create_privacy_act_task # original method defined in app/models/tasks/foia_colocated_task.rb super_return_value = super - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending) + AppellantNotification.notify_appellant(appeal, @@template_name) + super_return_value + end + + # for foia/privacy act mail tasks + # original method defined in app/models/mail_task.rb + def create_twin_of_type(params) + super_return_value = super + if params[:type] == "PrivacyActRequestMailTask" || params[:type] == "FoiaRequestMailTask" + AppellantNotification.notify_appellant(appeal, @@template_name) + end super_return_value end @@ -19,32 +31,22 @@ def create_privacy_act_task # original method defined in app/models/task.rb def create_child_task(parent, current_user, params) super_return_value = super - if organization_assigned_privacy_task?(params) || - privacy_act_mail_task?(params) || - valid_hearing_admin_foia_privacy_request?(params, parent) - AppellantNotification.notify_appellant(parent.appeal, - Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending) + if (params[:type] == "PrivacyActTask" && params[:assigned_to_type].include?("Organization")) || + (params[:type] == "HearingAdminActionFoiaPrivacyRequestTask" && parent.type == "ScheduleHearingTask") + AppellantNotification.notify_appellant(parent.appeal, @@template_name) end super_return_value end def update_appeal_state_when_privacy_act_created if PRIVACY_ACT_TASKS.include?(type) && !PRIVACY_ACT_TASKS.include?(parent&.type) - appeal.appeal_state.privacy_act_pending_appeal_state_update_action! + MetricsService.record("Updating PRIVACY_ACT_PENDING column in Appeal States Table to TRUE and + PRIVACY_ACT_COMPLETE to FALSE "\ + "for #{appeal.class} ID #{appeal.id}", + service: nil, + name: "AppellantNotification.appeal_mapper") do + AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "privacy_act_pending") + end end end - - private - - def privacy_act_mail_task?(params) - params[:type] == "PrivacyActRequestMailTask" || params[:type] == "FoiaRequestMailTask" - end - - def organization_assigned_privacy_task?(params) - params[:type] == "PrivacyActTask" && params[:assigned_to_type].include?("Organization") - end - - def valid_hearing_admin_foia_privacy_request?(params, parent) - params[:type] == "HearingAdminActionFoiaPrivacyRequestTask" && parent.type == "ScheduleHearingTask" - end end diff --git a/app/models/tasks/assign_hearing_disposition_task.rb b/app/models/tasks/assign_hearing_disposition_task.rb index a501e32e7d9..d29e63cbbc9 100644 --- a/app/models/tasks/assign_hearing_disposition_task.rb +++ b/app/models/tasks/assign_hearing_disposition_task.rb @@ -23,7 +23,6 @@ class AssignHearingDispositionTask < Task prepend HearingWithdrawn prepend HearingPostponed prepend HearingScheduledInError - prepend HearingHeld validates :parent, presence: true, parentTask: { task_type: HearingTask }, on: :create delegate :hearing, to: :hearing_task, allow_nil: true diff --git a/app/models/tasks/distribution_task.rb b/app/models/tasks/distribution_task.rb index 2baa1dcb84d..ce02e513ed4 100644 --- a/app/models/tasks/distribution_task.rb +++ b/app/models/tasks/distribution_task.rb @@ -14,8 +14,6 @@ class DistributionTask < Task before_validation :set_assignee - after_update :update_affinity_start_date, if: :assigned_affinity_start_date? - def actions_available?(user) SpecialCaseMovementTeam.singleton.user_has_access?(user) end @@ -61,15 +59,4 @@ def visible_blocking_tasks def set_assignee self.assigned_to ||= Bva.singleton end - - def update_affinity_start_date - # update affinity start date with instructions - appeal.appeal_affinity.update!(affinity_start_date: nil) - instructions.push("Appeal affinity start date value was removed.") - save! - end - - def assigned_affinity_start_date? - saved_change_to_attribute?("status") && status == "assigned" && appeal.appeal_affinity&.affinity_start_date - end end diff --git a/app/models/tasks/hearing_mail_tasks/hearing_postponement_request_mail_task.rb b/app/models/tasks/hearing_mail_tasks/hearing_postponement_request_mail_task.rb index 1d898787a6c..9a81594a77c 100644 --- a/app/models/tasks/hearing_mail_tasks/hearing_postponement_request_mail_task.rb +++ b/app/models/tasks/hearing_mail_tasks/hearing_postponement_request_mail_task.rb @@ -143,7 +143,7 @@ def reschedule( disposition_task = AssignHearingDispositionTask .create_assign_hearing_disposition_task!(appeal, new_hearing_task, new_hearing) - AppellantNotification.notify_appellant(appeal, Constants.EVENT_TYPE_FILTERS.hearing_scheduled) + AppellantNotification.notify_appellant(appeal, "Hearing scheduled") [new_hearing_task, disposition_task] end diff --git a/app/models/vacols/case.rb b/app/models/vacols/case.rb index badae5d4528..2977fd64eb6 100644 --- a/app/models/vacols/case.rb +++ b/app/models/vacols/case.rb @@ -15,10 +15,8 @@ class VACOLS::Case < VACOLS::Record has_many :decass, foreign_key: :defolder has_one :staff, foreign_key: :slogid, primary_key: :bfcurloc has_many :priorloc, foreign_key: :lockey - has_many :mail, foreign_key: :mlfolder has_many :decision_quality_reviews, foreign_key: :qrfolder - - has_one :appeal_affinity, as: :case + has_many :mail, foreign_key: :mlfolder class InvalidLocationError < StandardError; end diff --git a/app/models/vacols/case_docket.rb b/app/models/vacols/case_docket.rb index 02c0062f55d..6c73c806d80 100644 --- a/app/models/vacols/case_docket.rb +++ b/app/models/vacols/case_docket.rb @@ -107,7 +107,7 @@ class DocketNumberCentennialLoop < StandardError; end select BFKEY, BFDLOOUT, VLJ from ( select BFKEY, BFDLOOUT, - VLJ_HEARINGS.VLJ + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ from ( #{SELECT_READY_APPEALS} and (BFAC = '7' or AOD = '1') @@ -121,7 +121,7 @@ class DocketNumberCentennialLoop < StandardError; end select BFKEY, BFD19, BFDLOOUT, VLJ from ( select BFKEY, BFD19, BFDLOOUT, - VLJ_HEARINGS.VLJ + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ from ( #{SELECT_READY_APPEALS} and (BFAC = '7' or AOD = '1') @@ -136,7 +136,7 @@ class DocketNumberCentennialLoop < StandardError; end select BFKEY, BFDLOOUT, VLJ, DOCKET_INDEX from ( select BFKEY, BFDLOOUT, rownum DOCKET_INDEX, - VLJ_HEARINGS.VLJ + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ from ( #{SELECT_READY_APPEALS} and BFAC <> '7' and AOD = '0' @@ -150,7 +150,7 @@ class DocketNumberCentennialLoop < StandardError; end select BFKEY, BFD19, BFDLOOUT, VLJ, DOCKET_INDEX from ( select BFKEY, BFD19, BFDLOOUT, rownum DOCKET_INDEX, - VLJ_HEARINGS.VLJ + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ from ( #{SELECT_READY_APPEALS} and BFAC <> '7' and AOD = '0' @@ -169,7 +169,7 @@ class DocketNumberCentennialLoop < StandardError; end case when APPEALS.BFAC = '7' then 1 else 0 end CAVC from ( select BFKEY, BRIEFF.TINUM, BFD19, BFDLOOUT, BFAC, BFCORKEY, AOD, BFCORLID, - VLJ_HEARINGS.VLJ + case when BFHINES is null or BFHINES <> 'GP' then VLJ_HEARINGS.VLJ end VLJ from ( #{SELECT_READY_APPEALS_ADDITIONAL_COLS} ) BRIEFF diff --git a/app/models/vanotify/notification.rb b/app/models/vanotify/notification.rb index 7e40f347af9..9607ae597cb 100644 --- a/app/models/vanotify/notification.rb +++ b/app/models/vanotify/notification.rb @@ -1,9 +1,5 @@ # frozen_string_literal: true class Notification < CaseflowRecord - belongs_to :notifiable, polymorphic: true - - alias appeal notifiable - self.ignored_columns = ["notification_events_id"] end diff --git a/app/queries/appeals_ready_for_distribution.rb b/app/queries/appeals_ready_for_distribution.rb index 703153f8310..e977a25968c 100644 --- a/app/queries/appeals_ready_for_distribution.rb +++ b/app/queries/appeals_ready_for_distribution.rb @@ -11,8 +11,7 @@ class AppealsReadyForDistribution ready_for_distribution_at: "Ready for Distribution at", hearing_judge: "Hearing Judge", veteran_file_number: "Veteran File number", - veteran_name: "Veteran", - affinity_start_date: "Affinity Start Date" + veteran_name: "Veteran" }.freeze def self.generate_rows(record) @@ -53,9 +52,11 @@ def self.legacy_rows(appeals, docket) 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") - + hearing_judge = if vlj_name.empty? + nil + else + vlj_name + end { docket_number: appeal["tinum"], docket: docket.to_s, @@ -65,8 +66,7 @@ def self.legacy_rows(appeals, docket) ready_for_distribution_at: appeal["bfdloout"], hearing_judge: hearing_judge, veteran_file_number: appeal["ssn"] || appeal["bfcorlid"], - veteran_name: veteran_name, - affinity_start_date: appeal_affinity&.affinity_start_date + veteran_name: veteran_name } end end @@ -92,8 +92,8 @@ def self.ama_rows(appeals, docket) ready_for_distribution_at: ready_for_distribution_at, hearing_judge: hearing_judge, veteran_file_number: appeal.veteran_file_number, - veteran_name: appeal.veteran&.name.to_s, - affinity_start_date: appeal.appeal_affinity&.affinity_start_date + veteran_name: appeal.veteran&.name.to_s + } end end diff --git a/app/queries/appeals_updated_since_query.rb b/app/queries/appeals_updated_since_query.rb index afe3819b5b3..0e1bc75989d 100644 --- a/app/queries/appeals_updated_since_query.rb +++ b/app/queries/appeals_updated_since_query.rb @@ -18,12 +18,10 @@ def call # or `scope :updated_since_for_appeals` to the model, esp. if the ETL::Appeal table uses the model's data. SKIP_ASSOCIATIONS = %w[ versions - appeal_affinity appeal_views claims_folder_searches job_notes nod_date_updates - notifications record_synced_by_job request_decision_issues request_issues_updates diff --git a/app/queries/hearing_request_distribution_query.rb b/app/queries/hearing_request_distribution_query.rb index c03c7aa6890..ec495b2f761 100644 --- a/app/queries/hearing_request_distribution_query.rb +++ b/app/queries/hearing_request_distribution_query.rb @@ -99,7 +99,7 @@ def generate_ama_not_genpop_non_aod_hearing_query(base_relation) elsif CaseDistributionLever.ama_hearing_case_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .none end @@ -122,7 +122,7 @@ def generate_ama_not_genpop_aod_hearing_query(base_relation) elsif CaseDistributionLever.ama_hearing_case_aod_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .none end @@ -134,18 +134,18 @@ def generate_ama_only_genpop_non_aod_hearing_query(base_relation) if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.ama_hearing_case_affinity_days) base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .ama_non_aod_hearing_appeals .expired_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 - .with_appeal_affinities + .join_distribution_tasks .none elsif CaseDistributionLever.ama_hearing_case_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .with_held_hearings .ama_non_aod_hearing_appeals end @@ -158,18 +158,18 @@ def generate_ama_only_genpop_aod_hearing_query(base_relation) if case_affinity_days_lever_value_is_selected?(CaseDistributionLever.ama_hearing_case_aod_affinity_days) base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .ama_aod_hearing_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 .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .none elsif CaseDistributionLever.ama_hearing_case_aod_affinity_days == Constants.ACD_LEVERS.omit base_relation .most_recent_hearings - .with_appeal_affinities + .join_distribution_tasks .with_held_hearings .ama_aod_hearing_appeals end diff --git a/app/services/external_api/va_notify_service.rb b/app/services/external_api/va_notify_service.rb index 5b621763b1d..4bd3d1a3e10 100644 --- a/app/services/external_api/va_notify_service.rb +++ b/app/services/external_api/va_notify_service.rb @@ -33,12 +33,12 @@ class << self # Return: email_response: JSON response from VA Notify API # rubocop:disable Metrics/ParameterLists def send_email_notifications( - participant_id:, - notification_id:, - email_template_id:, - first_name:, - docket_number:, - status: "" + participant_id, + notification_id, + email_template_id, + first_name, + docket_number, + status = "" ) email_response = send_va_notify_request( email_request(participant_id, notification_id, email_template_id, first_name, docket_number, status) @@ -46,7 +46,7 @@ def send_email_notifications( log_info(email_response) email_response end - + # rubocop:enable Metrics/ParameterLists # Purpose: Send the sms notifications # # Params: Details from appeal for notification @@ -58,14 +58,8 @@ def send_email_notifications( # status: appeal status for quarterly notification (not necessary for other notifications) # Return: sms_response: JSON response from VA Notify API - def send_sms_notifications( - participant_id:, - notification_id:, - sms_template_id:, - first_name:, - docket_number:, - status: "" - ) + # rubocop:disable Metrics/ParameterLists + def send_sms_notifications(participant_id, notification_id, sms_template_id, first_name, docket_number, status = "") sms_response = send_va_notify_request( sms_request(participant_id, notification_id, sms_template_id, first_name, docket_number, status) ) diff --git a/app/views/explain/_task_tree.html.erb b/app/views/explain/_task_tree.html.erb index b5c723726e6..ba7236db6c9 100644 --- a/app/views/explain/_task_tree.html.erb +++ b/app/views/explain/_task_tree.html.erb @@ -41,9 +41,6 @@
la.location_history.map(&:summary) <% end %> -<% if appeal_affinity&.affinity_start_date %> -

Affinity Start Date: <%= appeal_affinity&.affinity_start_date&.strftime('%F %T %z') %>

-<% end %>
<%= task_tree_as_text %>
error save_rescued_error!(error.to_s) raise error - ensure - cleanup_up_file + end + + # We have to always download the file from s3 to make sure it exists locally + # instead of storing it on the server and relying that it will be there + def pdf_location + S3Service.fetch_file(s3_location, output_location) + output_location + end + + def source + "BVA" + end + + def document_type_id + Document.type_id(document_type) + end + + def cache_file + S3Service.store_file(s3_location, Base64.decode64(document.file)) end private @@ -46,4 +63,43 @@ def update_in_vbms! document.update!(uploaded_to_vbms_at: Time.zone.now) end + + def set_processed_at_to_current_time + document.update!(processed_at: Time.zone.now) + end + + def save_rescued_error!(error) + document.update!(error: error, document_version_reference_id: nil) + end + + def s3_location + "#{s3_bucket_by_doc_type}/#{pdf_name}" + end + + def output_location + File.join(Rails.root, "tmp", "pdfs", pdf_name) + end + + def pdf_name + "veteran-#{file_number}-doc-#{document.id}.pdf" + end + + def file_number + document.veteran_file_number + end + + # Purpose: Get the s3_sub_bucket based on the document type + # S3_SUB_BUCKET was previously a constant defined for this class. + # + # Params: None + # + # Return: string for the sub-bucket + def s3_bucket_by_doc_type + case document_type + when "BVA Case Notifications" + "notification-reports" + else + "idt-uploaded-documents" + end + end end diff --git a/app/workflows/upload_document_to_vbms.rb b/app/workflows/upload_document_to_vbms.rb index 02aee5035f9..c4cadde87ed 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -19,8 +19,25 @@ def call rescue StandardError => error save_rescued_error!(error.to_s) raise error - ensure - cleanup_up_file + end + + # We have to always download the file from s3 to make sure it exists locally + # instead of storing it on the server and relying that it will be there + def pdf_location + S3Service.fetch_file(s3_location, output_location) + output_location + end + + def source + "BVA" + end + + def document_type_id + Document.type_id(document_type) + end + + def cache_file + S3Service.store_file(s3_location, Base64.decode64(document.file)) end private @@ -47,4 +64,48 @@ def upload_to_vbms! document.update!(uploaded_to_vbms_at: Time.zone.now) end + + def set_processed_at_to_current_time + document.update!(processed_at: Time.zone.now) + end + + def save_rescued_error!(error) + document.update!(error: error) + end + + def s3_location + "#{s3_bucket_by_doc_type}/#{pdf_name}" + end + + def output_location + File.join(Rails.root, "tmp", "pdfs", pdf_name) + end + + def pdf_name + "veteran-#{file_number}-doc-#{document.id}.pdf" + end + + def file_number + document.veteran_file_number + end + + def log_info(info_message) + uuid = SecureRandom.uuid + Rails.logger.info("#{info_message} ID: #{uuid}") + end + + # Purpose: Get the s3_sub_bucket based on the document type + # S3_SUB_BUCKET was previously a constant defined for this class. + # + # Params: None + # + # Return: string for the sub-bucket + def s3_bucket_by_doc_type + case document_type + when "BVA Case Notifications" + "notification-reports" + else + "idt-uploaded-documents" + end + end end diff --git a/client/app/nonComp/components/NonCompTabs.jsx b/client/app/nonComp/components/NonCompTabs.jsx index f040bb88b8e..6350f5c69fe 100644 --- a/client/app/nonComp/components/NonCompTabs.jsx +++ b/client/app/nonComp/components/NonCompTabs.jsx @@ -52,7 +52,8 @@ const NonCompTabsUnconnected = (props) => { filterableTaskIssueTypes={props.taskFilterDetails.incomplete_issue_types} description={COPY.VHA_INCOMPLETE_TAB_DESCRIPTION} tabName="incomplete" - predefinedColumns={{ includeDaysWaiting: true }} /> + predefinedColumns={{ includeDaysWaiting: true, + defaultSortIdx: 3 }} /> }, in_progress: { label: 'In progress tasks', @@ -63,7 +64,8 @@ const NonCompTabsUnconnected = (props) => { {...(isVhaBusinessLine ? { onHistoryUpdate } : {})} filterableTaskTypes={props.taskFilterDetails.in_progress} filterableTaskIssueTypes={props.taskFilterDetails.in_progress_issue_types} - predefinedColumns={{ includeDaysWaiting: true }} /> + predefinedColumns={{ includeDaysWaiting: true, + defaultSortIdx: 3 }} /> }, completed: { label: 'Completed tasks', @@ -75,7 +77,8 @@ const NonCompTabsUnconnected = (props) => { filterableTaskTypes={props.taskFilterDetails.completed} filterableTaskIssueTypes={props.taskFilterDetails.completed_issue_types} description={COPY.QUEUE_PAGE_COMPLETE_LAST_SEVEN_DAYS_TASKS_DESCRIPTION} - predefinedColumns={{ includeCompletedDate: true }} /> + predefinedColumns={{ includeCompletedDate: true, + defaultSortIdx: 3 }} /> } }; diff --git a/client/app/queue/AssignedCasesPage.jsx b/client/app/queue/AssignedCasesPage.jsx index 0947b9d1e31..53abcda99bd 100644 --- a/client/app/queue/AssignedCasesPage.jsx +++ b/client/app/queue/AssignedCasesPage.jsx @@ -18,7 +18,6 @@ import { import Alert from '../components/Alert'; import COPY from '../../COPY'; -import { DEFAULT_QUEUE_TABLE_SORT } from './constants'; /** * Component showing the cases assigned to a specific attorney referenced by `attorneyId`. @@ -122,8 +121,7 @@ class AssignedCasesPage extends React.Component { includeReaderLink includeNewDocsIcon tasks={this.props.tasksOfAttorney} - userId={attorneyId} - defaultSort={DEFAULT_QUEUE_TABLE_SORT} /> + userId={attorneyId} /> ; } } diff --git a/client/app/queue/UnassignedCasesPage.jsx b/client/app/queue/UnassignedCasesPage.jsx index 2c2230feee6..a09a7f0861f 100644 --- a/client/app/queue/UnassignedCasesPage.jsx +++ b/client/app/queue/UnassignedCasesPage.jsx @@ -29,7 +29,6 @@ import Alert from '../components/Alert'; import LoadingContainer from '../components/LoadingContainer'; import { LOGO_COLORS } from '../constants/AppConstants'; import { css } from 'glamor'; -import { DEFAULT_QUEUE_TABLE_SORT } from './constants'; const assignSectionStyling = css({ marginTop: '30px' }); const loadingContainerStyling = css({ marginTop: '-2em' }); @@ -109,7 +108,6 @@ class UnassignedCasesPage extends React.PureComponent { includeNewDocsIcon tasks={this.props.tasks} userId={userId} - defaultSort={DEFAULT_QUEUE_TABLE_SORT} {...(userIsCamoEmployee ? { preserveQueueFilter: true } : {})} /> } diff --git a/client/app/queue/components/TaskTable.jsx b/client/app/queue/components/TaskTable.jsx index f5d84a4b422..2da3bb42f86 100644 --- a/client/app/queue/components/TaskTable.jsx +++ b/client/app/queue/components/TaskTable.jsx @@ -113,26 +113,34 @@ export class TaskTableUnconnected extends React.PureComponent { this.caseReaderLinkColumn() ])), ['order'], ['desc']); - getDefaultSortHash = () => { - if (this.props.defaultSort) { - return this.props.defaultSort; + getDefaultSortableColumn = () => { + if (this.props.defaultSortIdx) { + return this.props.defaultSortIdx; } + const index = _.findIndex(this.getQueueColumns(), + (column) => column.header === COPY.CASE_LIST_TABLE_APPEAL_TYPE_COLUMN_TITLE); + + if (index >= 0) { + return index; + } + + return _.findIndex(this.getQueueColumns(), (column) => column.getSortValue); } - render = () => - (this.taskHasDASRecord(task) || !this.props.requireDasRecord) ? null : 'usa-input-error'} - taskPagesApiEndpoint={this.props.taskPagesApiEndpoint} - useTaskPagesApi={this.props.useTaskPagesApi} - tabPaginationOptions={this.props.tabPaginationOptions} - />; + render = () => + this.taskHasDASRecord(task) || !this.props.requireDasRecord ? null : 'usa-input-error'} + taskPagesApiEndpoint={this.props.taskPagesApiEndpoint} + useTaskPagesApi={this.props.useTaskPagesApi} + tabPaginationOptions={this.props.tabPaginationOptions} + />; } TaskTableUnconnected.propTypes = { @@ -155,10 +163,7 @@ TaskTableUnconnected.propTypes = { includeReaderLink: PropTypes.bool, includeNewDocsIcon: PropTypes.bool, customColumns: PropTypes.array, - defaultSort: PropTypes.shape({ - sortColName: PropTypes.string, - sortAscending: PropTypes.bool - }), + defaultSortIdx: PropTypes.number, getKeyForRow: PropTypes.func, taskPagesApiEndpoint: PropTypes.string, useTaskPagesApi: PropTypes.bool, diff --git a/client/app/queue/constants.js b/client/app/queue/constants.js index c7afb3183e9..fdb3192709e 100644 --- a/client/app/queue/constants.js +++ b/client/app/queue/constants.js @@ -11,7 +11,6 @@ import { COLORS as COMMON_COLORS } from '@department-of-veterans-affairs/caseflo import COPY from '../../COPY'; import VACOLS_COLUMN_MAX_LENGTHS from '../../constants/VACOLS_COLUMN_MAX_LENGTHS'; import LEGACY_APPEAL_TYPES_BY_ID from '../../constants/LEGACY_APPEAL_TYPES_BY_ID'; -import { DEFAULT_SORTING_COLUMN_KEY, DEFAULT_SORTING_DIRECTION_KEY, COLUMNS } from '../../constants/QUEUE_CONFIG'; export const COLORS = { QUEUE_LOGO_PRIMARY: '#11598D', @@ -291,9 +290,3 @@ export const DECISION_SPECIAL_ISSUES = [ requiresJustification: false } ]; - -export const DEFAULT_QUEUE_TABLE_SORT = { - [DEFAULT_SORTING_COLUMN_KEY]: COLUMNS.APPEAL_TYPE.name, - [DEFAULT_SORTING_DIRECTION_KEY]: true -}; - diff --git a/client/constants/QUARTERLY_STATUSES.json b/client/constants/QUARTERLY_STATUSES.json index e6df95484e1..0db4da12c4d 100644 --- a/client/constants/QUARTERLY_STATUSES.json +++ b/client/constants/QUARTERLY_STATUSES.json @@ -6,5 +6,5 @@ "ihp_pending": "VSO IHP Pending", "hearing_to_be_rescheduled": "Hearing to be Rescheduled", "hearing_to_be_rescheduled_privacy_pending": "Hearing to be Rescheduled / Privacy Act Pending", - "appeal_docketed": "docketed" + "appeal_docketed": "Appeal Docketed" } diff --git a/client/constants/REGIONAL_OFFICE_FACILITY_ADDRESS.json b/client/constants/REGIONAL_OFFICE_FACILITY_ADDRESS.json index 69e4ba51be3..f3b6b2535c9 100644 --- a/client/constants/REGIONAL_OFFICE_FACILITY_ADDRESS.json +++ b/client/constants/REGIONAL_OFFICE_FACILITY_ADDRESS.json @@ -442,6 +442,15 @@ "zip" : "89086", "timezone" : "America/Los_Angeles" }, + "vc_0505V" : { + "address_1" : "7455 W. Washington Ave.", + "address_2" : null, + "address_3" : null, + "city" : "Las Vegas", + "state" : "NV", + "zip" : "89128", + "timezone" : "America/Los_Angeles" + }, "vba_355" : { "address_1" : "50 Carr 165", "address_2" : null, diff --git a/client/constants/REGIONAL_OFFICE_INFORMATION.json b/client/constants/REGIONAL_OFFICE_INFORMATION.json index 1483d4ce0ca..c2cf28a682d 100644 --- a/client/constants/REGIONAL_OFFICE_INFORMATION.json +++ b/client/constants/REGIONAL_OFFICE_INFORMATION.json @@ -530,7 +530,7 @@ "timezone": "America/Los_Angeles", "hold_hearings": true, "facility_locator_id": "vba_354", - "alternate_locations": ["vha_593"] + "alternate_locations": ["vha_593", "vc_0505V"] }, "RO55": { "label": "San Juan regional office", diff --git a/client/test/app/hearings/components/__snapshots__/ScheduleVeteran.test.js.snap b/client/test/app/hearings/components/__snapshots__/ScheduleVeteran.test.js.snap index bd52088f5bd..aa7d6523ec9 100644 --- a/client/test/app/hearings/components/__snapshots__/ScheduleVeteran.test.js.snap +++ b/client/test/app/hearings/components/__snapshots__/ScheduleVeteran.test.js.snap @@ -3980,6 +3980,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -4858,6 +4859,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -5806,6 +5808,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -6758,6 +6761,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -7685,6 +7689,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -8601,6 +8606,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -9577,6 +9583,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -10493,6 +10500,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -11477,6 +11485,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -12393,6 +12402,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -13393,6 +13403,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -14309,6 +14320,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -15337,6 +15349,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -16345,6 +16358,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -17408,6 +17422,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -18324,6 +18339,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -19290,6 +19306,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -20206,6 +20223,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -21183,6 +21201,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -22099,6 +22118,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -71297,6 +71317,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -72174,6 +72195,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -73097,6 +73119,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -74024,6 +74047,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -74926,6 +74950,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -75842,6 +75867,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -76793,6 +76819,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -77709,6 +77736,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -78668,6 +78696,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -79584,6 +79613,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -80534,6 +80564,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -81450,6 +81481,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -82451,6 +82483,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -83434,6 +83467,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -84472,6 +84506,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -85388,6 +85423,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -86329,6 +86365,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -87245,6 +87282,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -88197,6 +88235,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -89113,6 +89152,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -94019,6 +94059,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -94897,6 +94938,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -95845,6 +95887,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -96797,6 +96840,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -97724,6 +97768,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -98640,6 +98685,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -99616,6 +99662,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -100532,6 +100579,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -101516,6 +101564,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -102432,6 +102481,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -103432,6 +103482,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -104348,6 +104399,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -105376,6 +105428,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -106384,6 +106437,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -107447,6 +107501,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -108363,6 +108418,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -109329,6 +109385,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -110245,6 +110302,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -111222,6 +111280,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -112138,6 +112197,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -132311,6 +132371,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -133189,6 +133250,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -134137,6 +134199,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -135089,6 +135152,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -136016,6 +136080,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -136932,6 +136997,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -137908,6 +137974,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -138824,6 +138891,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -139808,6 +139876,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -140724,6 +140793,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -141724,6 +141794,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -142640,6 +142711,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -143668,6 +143740,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -144676,6 +144749,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -145739,6 +145813,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -146655,6 +146730,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -147621,6 +147697,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -148537,6 +148614,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -149514,6 +149592,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -150430,6 +150509,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -169660,6 +169740,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -170538,6 +170619,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -171486,6 +171568,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -172438,6 +172521,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -173365,6 +173449,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -174281,6 +174366,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -175257,6 +175343,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -176173,6 +176260,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -177157,6 +177245,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -178073,6 +178162,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -179073,6 +179163,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -179989,6 +180080,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -181017,6 +181109,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -182025,6 +182118,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -183088,6 +183182,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -184004,6 +184099,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -184970,6 +185066,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -185886,6 +185983,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -186863,6 +186961,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -187779,6 +187878,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -207948,6 +208048,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -208826,6 +208927,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -209774,6 +209876,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -210726,6 +210829,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -211653,6 +211757,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -212569,6 +212674,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -213545,6 +213651,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -214461,6 +214568,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -215445,6 +215553,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -216361,6 +216470,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -217361,6 +217471,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -218277,6 +218388,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -219305,6 +219417,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -220313,6 +220426,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -221376,6 +221490,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -222292,6 +222407,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -223258,6 +223374,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -224174,6 +224291,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -225151,6 +225269,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -226067,6 +226186,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -245208,6 +245328,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -246086,6 +246207,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -247034,6 +247156,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -247986,6 +248109,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -248913,6 +249037,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -249829,6 +249954,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -250805,6 +250931,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -251721,6 +251848,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -252705,6 +252833,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -253621,6 +253750,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -254621,6 +254751,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -255537,6 +255668,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -256565,6 +256697,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -257573,6 +257706,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -258636,6 +258770,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -259552,6 +259687,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -260518,6 +260654,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -261434,6 +261571,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -262411,6 +262549,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -263327,6 +263466,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -282430,6 +282570,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -283309,6 +283450,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -284257,6 +284399,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -285209,6 +285352,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -286136,6 +286280,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -287052,6 +287197,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -288028,6 +288174,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -288944,6 +289091,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -289928,6 +290076,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -290844,6 +290993,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -291844,6 +291994,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -292760,6 +292911,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -293788,6 +293940,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -294796,6 +294949,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -295859,6 +296013,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -296775,6 +296930,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -297741,6 +297897,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -298657,6 +298814,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -299634,6 +299792,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -300550,6 +300709,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -313104,6 +313264,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -313982,6 +314143,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -314930,6 +315092,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -315882,6 +316045,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -316809,6 +316973,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -317725,6 +317890,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -318701,6 +318867,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -319617,6 +319784,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -320601,6 +320769,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -321517,6 +321686,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -322517,6 +322687,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -323433,6 +323604,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -324461,6 +324633,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -325469,6 +325642,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -326532,6 +326706,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -327448,6 +327623,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -328414,6 +328590,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -329330,6 +329507,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -330307,6 +330485,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -331223,6 +331402,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -381937,6 +382117,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -382815,6 +382996,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -383763,6 +383945,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -384715,6 +384898,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -385642,6 +385826,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -386558,6 +386743,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -387534,6 +387720,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -388450,6 +388637,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -389434,6 +389622,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -390350,6 +390539,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -391350,6 +391540,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -392266,6 +392457,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -393294,6 +393486,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -394302,6 +394495,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -395365,6 +395559,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -396281,6 +396476,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -397247,6 +397443,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -398163,6 +398360,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -399140,6 +399338,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -400056,6 +400255,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -450416,6 +450616,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -451294,6 +451495,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -452242,6 +452444,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -453194,6 +453397,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -454121,6 +454325,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -455037,6 +455242,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -456013,6 +456219,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -456929,6 +457136,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -457913,6 +458121,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -458829,6 +459038,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -459829,6 +460039,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -460745,6 +460956,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -461773,6 +461985,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -462781,6 +462994,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -463844,6 +464058,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -464760,6 +464975,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -465726,6 +465942,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -466642,6 +466859,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -467619,6 +467837,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -468535,6 +468754,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -488846,6 +489066,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -489723,6 +489944,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -490646,6 +490868,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -491573,6 +491796,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -492475,6 +492699,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -493391,6 +493616,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -494342,6 +494568,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -495258,6 +495485,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -496217,6 +496445,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -497133,6 +497362,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -498083,6 +498313,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -498999,6 +499230,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -500000,6 +500232,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -500983,6 +501216,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -502021,6 +502255,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -502937,6 +503172,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -503878,6 +504114,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -504794,6 +505031,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -505746,6 +505984,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -506662,6 +506901,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", diff --git a/client/test/app/hearings/components/__snapshots__/ScheduleVeteranForm.test.js.snap b/client/test/app/hearings/components/__snapshots__/ScheduleVeteranForm.test.js.snap index 3ff656a68fc..df6381df3f8 100644 --- a/client/test/app/hearings/components/__snapshots__/ScheduleVeteranForm.test.js.snap +++ b/client/test/app/hearings/components/__snapshots__/ScheduleVeteranForm.test.js.snap @@ -3402,6 +3402,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -4279,6 +4280,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -5202,6 +5204,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -6129,6 +6132,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -7031,6 +7035,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -7947,6 +7952,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -8898,6 +8904,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -9814,6 +9821,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -10773,6 +10781,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -11689,6 +11698,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -12639,6 +12649,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -13555,6 +13566,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -14556,6 +14568,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -15539,6 +15552,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -16577,6 +16591,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -17493,6 +17508,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -18434,6 +18450,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -19350,6 +19367,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -20302,6 +20320,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -21218,6 +21237,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -24855,6 +24875,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -25733,6 +25754,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -26681,6 +26703,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -27633,6 +27656,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -28560,6 +28584,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -29476,6 +29501,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -30452,6 +30478,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -31368,6 +31395,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -32352,6 +32380,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -33268,6 +33297,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -34268,6 +34298,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -35184,6 +35215,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -36212,6 +36244,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -37220,6 +37253,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -38283,6 +38317,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -39199,6 +39234,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -40165,6 +40201,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -41081,6 +41118,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -42058,6 +42096,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -42974,6 +43013,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -61574,6 +61614,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -62452,6 +62493,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -63400,6 +63442,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -64352,6 +64395,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -65279,6 +65323,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -66195,6 +66240,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -67171,6 +67217,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -68087,6 +68134,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -69071,6 +69119,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -69987,6 +70036,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -70987,6 +71037,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -71903,6 +71954,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -72931,6 +72983,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -73939,6 +73992,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -75002,6 +75056,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -75918,6 +75973,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -76884,6 +76940,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -77800,6 +77857,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -78777,6 +78835,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -79693,6 +79752,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -89362,6 +89422,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -90240,6 +90301,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -91172,6 +91234,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -92124,6 +92187,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -93051,6 +93115,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -93967,6 +94032,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -94943,6 +95009,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -95859,6 +95926,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -96843,6 +96911,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -97759,6 +97828,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -98759,6 +98829,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -99675,6 +99746,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -100703,6 +100775,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -101711,6 +101784,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -102774,6 +102848,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -103690,6 +103765,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -104656,6 +104732,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -105572,6 +105649,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -106549,6 +106627,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -107465,6 +107544,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -145298,6 +145378,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -146176,6 +146257,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -147124,6 +147206,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -148076,6 +148159,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -149003,6 +149087,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -149919,6 +150004,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -150895,6 +150981,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -151811,6 +151898,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -152795,6 +152883,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -153711,6 +153800,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -154711,6 +154801,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -155627,6 +155718,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -156655,6 +156747,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -157663,6 +157756,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -158726,6 +158820,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -159642,6 +159737,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -160608,6 +160704,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -161524,6 +161621,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -162501,6 +162599,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -163417,6 +163516,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -172979,6 +173079,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -173857,6 +173958,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -174805,6 +174907,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -175757,6 +175860,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -176684,6 +176788,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -177600,6 +177705,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -178576,6 +178682,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -179492,6 +179599,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -180476,6 +180584,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -181392,6 +181501,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -182392,6 +182502,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -183308,6 +183419,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -184336,6 +184448,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -185344,6 +185457,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -186407,6 +186521,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -187323,6 +187438,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -188289,6 +188405,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -189205,6 +189322,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -190182,6 +190300,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -191098,6 +191217,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -200630,6 +200750,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -201507,6 +201628,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -202430,6 +202552,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -203357,6 +203480,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -204259,6 +204383,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -205175,6 +205300,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -206126,6 +206252,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -207042,6 +207169,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -208001,6 +208129,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -208917,6 +209046,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -209867,6 +209997,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -210783,6 +210914,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -211784,6 +211916,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -212767,6 +212900,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -213805,6 +213939,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -214721,6 +214856,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -215662,6 +215798,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -216578,6 +216715,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -217530,6 +217668,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -218446,6 +218585,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -222052,6 +222192,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -222929,6 +223070,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -223852,6 +223994,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -224779,6 +224922,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -225681,6 +225825,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -226597,6 +226742,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -227548,6 +227694,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -228464,6 +228611,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -229423,6 +229571,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -230339,6 +230488,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -231289,6 +231439,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -232205,6 +232356,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -233206,6 +233358,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -234189,6 +234342,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -235227,6 +235381,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -236143,6 +236298,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -237084,6 +237240,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -238000,6 +238157,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -238952,6 +239110,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", @@ -239868,6 +240027,7 @@ SAN FRANCISCO, CA 94103 "value": Object { "alternate_locations": Array [ "vha_593", + "vc_0505V", ], "city": "Reno", "facility_locator_id": "vba_354", diff --git a/client/test/data/regionalOfficesJsonResponse.json b/client/test/data/regionalOfficesJsonResponse.json index 2f0b382b809..479681c28ce 100644 --- a/client/test/data/regionalOfficesJsonResponse.json +++ b/client/test/data/regionalOfficesJsonResponse.json @@ -552,7 +552,7 @@ "timezone": "America/Los_Angeles", "state": "NV", "alternate_locations": [ - "vha_593" + "vha_593", "vc_0505V" ], "facility_locator_id": "vba_354", "city": "Reno" diff --git a/config/environments/development.rb b/config/environments/development.rb index e27e16487b1..3d5d43787e7 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -128,6 +128,9 @@ # One time Appeal States migration for Legacy & AMA Appeal Batch Sizes ENV["STATE_MIGRATION_JOB_BATCH_SIZE"] ||= "1000" + # Quarterly Notifications Batch Sizes + ENV["QUARTERLY_NOTIFICATIONS_JOB_BATCH_SIZE"] ||= "1000" + # Travel Board Sync Batch Size ENV["TRAVEL_BOARD_HEARING_SYNC_BATCH_LIMIT"] ||= "250" diff --git a/config/environments/test.rb b/config/environments/test.rb index 83e3a687dd0..df91ac33a6f 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -128,6 +128,9 @@ # One time Appeal States migration for Legacy & AMA Appeal Batch Sizes ENV["STATE_MIGRATION_JOB_BATCH_SIZE"] ||= "1000" + # Quarterly Notifications Batch Sizes + ENV["QUARTERLY_NOTIFICATIONS_JOB_BATCH_SIZE"] ||= "1000" + # Travel Board Sync Batch Size ENV["TRAVEL_BOARD_HEARING_SYNC_BATCH_LIMIT"] ||= "250" diff --git a/config/initializers/deploy_env.rb b/config/initializers/deploy_env.rb index 9d7045acc90..18ebb0c51a9 100644 --- a/config/initializers/deploy_env.rb +++ b/config/initializers/deploy_env.rb @@ -1,15 +1,13 @@ module Rails class EnvironmentNotFound < StandardError; end - DEPLOY_ENV = { - "uat" => :uat, - "preprod" => :preprod, - "prodtest" => :prodtest, - "prod" => :prod - }.freeze - def self.deploy_env?(environment) - deploy_env = DEPLOY_ENV[ENV["DEPLOY_ENV"]] || :demo + deploy_env = { + "uat" => :uat, + "preprod" => :preprod, + "prodtest" => :prodtest, + "prod" => :prod + }[ENV["DEPLOY_ENV"]] || :demo deploy_env == environment end @@ -25,8 +23,4 @@ def self.current_env def self.deploy_env current_env end - - def self.in_upper_env? - current_env == DEPLOY_ENV["prod"] || current_env == DEPLOY_ENV["prodtest"] - end end diff --git a/config/initializers/rswag_api.rb b/config/initializers/rswag_api.rb deleted file mode 100644 index 8d214218383..00000000000 --- a/config/initializers/rswag_api.rb +++ /dev/null @@ -1,21 +0,0 @@ -Rswag::Api.configure do |c| - - # Specify a root folder where Swagger JSON files are located - # This is used by the Swagger middleware to serve requests for API descriptions - # NOTE: If you're using rswag-specs to generate Swagger, you'll need to ensure - # that it's configured to generate files in the same folder - c.openapi_root = Rails.root.join('app/controllers/swagger').to_s - - # Inject a lambda function to alter the returned Swagger prior to serialization - # The function will have access to the rack env for the current request - # For example, you could leverage this to dynamically assign the "host" property - # - #c.swagger_filter = lambda { |swagger, env| swagger['host'] = env['HTTP_HOST'] } -end - -# Overwriting this method from rswag_api so that Date is whitelisted when loading YAML files -Rswag::Api::Middleware.module_eval do - def load_yaml(filename) - YAML.safe_load(File.read(filename), [Symbol, Date, Time]) - end -end diff --git a/config/initializers/rswag_ui.rb b/config/initializers/rswag_ui.rb deleted file mode 100644 index 281a88741ea..00000000000 --- a/config/initializers/rswag_ui.rb +++ /dev/null @@ -1,27 +0,0 @@ -Rswag::Ui.configure do |c| - - # List the Swagger endpoints that you want to be documented through the - # swagger-ui. The first parameter is the path (absolute or relative to the UI - # host) to the corresponding endpoint and the second is a title that will be - # displayed in the document selector. - # NOTE: If you're using rspec-api to expose Swagger files - # (under openapi_root) as JSON or YAML endpoints, then the list below should - # correspond to the relative paths for those endpoints. - - # The API V1, API V2, and API V3 swagger files are the rswag generated files - - unless Rails.in_upper_env? - # c.openapi_endpoint '/api-docs/v1/swagger.yaml', 'API V1' - c.openapi_endpoint '/api-docs/cmp/swagger.yaml', 'API V1: Correspondence CMP Integration' - # c.openapi_endpoint '/api-docs/v2/swagger.yaml', 'API V2' - # c.openapi_endpoint '/api-docs/v3/swagger.yaml', 'API V3' - c.openapi_endpoint '/api-docs/v3/ama_issues.yaml', 'API V3: AMA Request Issues' - c.openapi_endpoint '/api-docs/v3/decision_reviews.yaml', 'API V3: Decision Reviews' - c.openapi_endpoint '/api-docs/v3/vacols_issues.yaml', 'API V3: VACOLS Issues' - c.openapi_endpoint '/api-docs/idt/swagger.yaml', 'IDT-Caseflow-Package Manager Bridge API' - end - - # Add Basic Auth in case your API is private - # c.basic_auth_enabled = true - # c.basic_auth_credentials 'username', 'password' -end diff --git a/config/initializers/shoryuken.rb b/config/initializers/shoryuken.rb index 4d1061d0e96..759c3d8d35c 100644 --- a/config/initializers/shoryuken.rb +++ b/config/initializers/shoryuken.rb @@ -1,7 +1,6 @@ require "#{Rails.root}/app/jobs/middleware/job_monitoring_middleware" require "#{Rails.root}/app/jobs/middleware/job_request_store_middleware" require "#{Rails.root}/app/jobs/middleware/job_sentry_scope_middleware" -require "#{Rails.root}/app/jobs/middleware/job_message_deletion_middleware" # set up default exponential backoff parameters ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper @@ -33,6 +32,5 @@ chain.add JobMonitoringMiddleware chain.add JobRequestStoreMiddleware chain.add JobSentryScopeMiddleware - chain.add JobMessageDeletionMiddleware end end diff --git a/config/routes.rb b/config/routes.rb index 246eefdde53..72c96b31fb8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,4 @@ Rails.application.routes.draw do - mount Rswag::Ui::Engine => '/api-docs' - mount Rswag::Api::Engine => '/api-docs' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". @@ -49,7 +47,6 @@ resources :jobs, only: :create post 'mpi', to: 'mpi#veteran_updates' post 'va_notify_update', to: 'va_notify#notifications_update' - post 'cmp', to: 'cmp#upload' end namespace :v2 do resources :appeals, only: :index @@ -83,9 +80,9 @@ end namespace :docs do namespace :v3, defaults: { format: 'json' } do - get 'decision_reviews', to: redirect('api-docs/v3/decision_reviews.yaml') - get "ama_issues", to: redirect('api-docs/v3/ama_issues.yaml') - get "vacols_issues", to: redirect('api-docs/v3/vacols_issues.yaml') + get 'decision_reviews', to: 'docs#decision_reviews' + get "ama_issues", to: "docs#ama_issues" + get "vacols_issues", to: "docs#vacols_issues" end end get "metadata", to: 'metadata#index' diff --git a/db/migrate/20231218144043_add_sms_response_content_and_sms_response_time_to_notifications.rb b/db/migrate/20231218144043_add_sms_response_content_and_sms_response_time_to_notifications.rb deleted file mode 100644 index d4f6eba36ba..00000000000 --- a/db/migrate/20231218144043_add_sms_response_content_and_sms_response_time_to_notifications.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddSmsResponseContentAndSmsResponseTimeToNotifications < ActiveRecord::Migration[5.2] - def change - add_column :notifications, :sms_response_content, :string, comment: "Message body of the sms notification response." - add_column :notifications, :sms_response_time, :datetime, comment: "Date and Time of the sms notification response." - end -end diff --git a/db/migrate/20240423172438_add_polymorphic_appeal_association_to_notifications_table.rb b/db/migrate/20240423172438_add_polymorphic_appeal_association_to_notifications_table.rb deleted file mode 100644 index 796023d693e..00000000000 --- a/db/migrate/20240423172438_add_polymorphic_appeal_association_to_notifications_table.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddPolymorphicAppealAssociationToNotificationsTable < Caseflow::Migration - disable_ddl_transaction! - - def change - add_reference :notifications, :notifiable, polymorphic: true, index: false - end -end diff --git a/db/migrate/20240423180432_add_index_to_polymorphic_appeal_association_in_notification_table.rb b/db/migrate/20240423180432_add_index_to_polymorphic_appeal_association_in_notification_table.rb deleted file mode 100644 index e39aef226bc..00000000000 --- a/db/migrate/20240423180432_add_index_to_polymorphic_appeal_association_in_notification_table.rb +++ /dev/null @@ -1,10 +0,0 @@ -class AddIndexToPolymorphicAppealAssociationInNotificationTable < ActiveRecord::Migration[6.0] - disable_ddl_transaction! - - def change - add_index :notifications, - [:notifiable_type, :notifiable_id], - name: "index_notifications_on_notifiable_type_and_notifiable_id", - algorithm: :concurrently - end -end diff --git a/db/migrate/20240501180157_create_appeal_affinity.rb b/db/migrate/20240501180157_create_appeal_affinity.rb deleted file mode 100644 index d843be194bf..00000000000 --- a/db/migrate/20240501180157_create_appeal_affinity.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateAppealAffinity < ActiveRecord::Migration[6.0] - def change - create_table :appeal_affinities do |t| - t.string :case_id, null: false, comment: "Appeal UUID for AMA or BRIEFF.BFKEY for Legacy" - t.string :case_type, null: false, comment: "Appeal type for ActiveRecord Associations" - t.string :docket, null: false, comment: "The docket of the appeal" - t.boolean :priority, null: false, comment: "Priority status (true/false)" - t.datetime :affinity_start_date, comment: "The date from which to calculate an appeal's affinity window" - t.references :distribution, foreign_key: true, null: true, comment: "The distribution which caused the affinity start date to be set, if by a distribution" - - t.timestamps - - t.index ["case_id", "case_type"], unique: true - end - end -end diff --git a/db/migrate/20240525120005_create_job_execution_times.rb b/db/migrate/20240525120005_create_job_execution_times.rb deleted file mode 100644 index 3d5b98ab817..00000000000 --- a/db/migrate/20240525120005_create_job_execution_times.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -# Add table to track the Time a Job was Last Executed -class CreateJobExecutionTimes < Caseflow::Migration - def change - create_table :job_execution_times, id: :serial do |t| - t.string "job_name", comment: "Name of the Job whose Last Execution Time is being tracked", index: {unique: true} - t.datetime "last_executed_at", comment: "DateTime value when the Job was Last Executed" - end - end -end diff --git a/db/schema.rb b/db/schema.rb index 59400b85aea..82fda974272 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_05_25_120005) do +ActiveRecord::Schema.define(version: 2024_05_01_180157) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -78,19 +78,6 @@ t.string "vbms_id" end - create_table "appeal_affinities", force: :cascade do |t| - t.datetime "affinity_start_date", comment: "The date from which to calculate an appeal's affinity window" - t.string "case_id", null: false, comment: "Appeal UUID for AMA or BRIEFF.BFKEY for Legacy" - t.string "case_type", null: false, comment: "Appeal type for ActiveRecord Associations" - t.datetime "created_at", precision: 6, null: false - t.bigint "distribution_id", comment: "The distribution which caused the affinity start date to be set, if by a distribution" - t.string "docket", null: false, comment: "The docket of the appeal" - t.boolean "priority", null: false, comment: "Priority status (true/false)" - t.datetime "updated_at", precision: 6, null: false - t.index ["case_id", "case_type"], name: "index_appeal_affinities_on_case_id_and_case_type", unique: true - t.index ["distribution_id"], name: "index_appeal_affinities_on_distribution_id" - end - create_table "appeal_series", id: :serial, force: :cascade do |t| t.datetime "created_at" t.boolean "incomplete", default: false @@ -1146,12 +1133,6 @@ t.index ["veteran_id"], name: "index_intakes_on_veteran_id" end - create_table "job_execution_times", id: :serial, force: :cascade do |t| - t.string "job_name", comment: "Name of the Job whose Last Execution Time is being tracked" - t.datetime "last_executed_at", comment: "DateTime value when the Job was Last Executed" - t.index ["job_name"], name: "index_job_execution_times_on_job_name", unique: true - end - create_table "job_notes", force: :cascade do |t| t.datetime "created_at", null: false, comment: "Default created_at/updated_at" t.bigint "job_id", null: false, comment: "The job to which the note applies" @@ -1393,8 +1374,6 @@ t.string "email_notification_status", comment: "Status of the Email Notification" t.date "event_date", null: false, comment: "Date of Event" t.string "event_type", null: false, comment: "Type of Event" - t.bigint "notifiable_id" - t.string "notifiable_type" t.text "notification_content", comment: "Full Text Content of Notification" t.string "notification_type", null: false, comment: "Type of Notification that was created" t.datetime "notified_at", comment: "Time Notification was created" @@ -1404,13 +1383,10 @@ t.string "sms_notification_content", comment: "Full SMS Text Content of Notification" t.string "sms_notification_external_id", comment: "VA Notify Notification Id for the sms notification send through their API " t.string "sms_notification_status", comment: "Status of SMS/Text Notification" - t.string "sms_response_content", comment: "Message body of the sms notification response." - t.datetime "sms_response_time", comment: "Date and Time of the sms notification response." t.datetime "updated_at", comment: "TImestamp of when Notification was Updated" t.index ["appeals_id", "appeals_type"], name: "index_appeals_notifications_on_appeals_id_and_appeals_type" t.index ["email_notification_external_id"], name: "index_notifications_on_email_notification_external_id" t.index ["email_notification_status"], name: "index_notifications_on_email_notification_status" - t.index ["notifiable_type", "notifiable_id"], name: "index_notifications_on_notifiable_type_and_notifiable_id" t.index ["participant_id"], name: "index_participant_id" t.index ["sms_notification_external_id"], name: "index_notifications_on_sms_notification_external_id" t.index ["sms_notification_status"], name: "index_notifications_on_sms_notification_status" @@ -2181,7 +2157,6 @@ add_foreign_key "allocations", "schedule_periods" add_foreign_key "annotations", "users" add_foreign_key "api_views", "api_keys" - add_foreign_key "appeal_affinities", "distributions" add_foreign_key "appeal_states", "users", column: "created_by_id" add_foreign_key "appeal_states", "users", column: "updated_by_id" add_foreign_key "appeal_views", "users" diff --git a/db/seeds/ama_affinity_cases.rb b/db/seeds/ama_affinity_cases.rb index 866334453bc..4cc75b49aa5 100644 --- a/db/seeds/ama_affinity_cases.rb +++ b/db/seeds/ama_affinity_cases.rb @@ -12,9 +12,8 @@ def initialize def seed! create_cda_admin_user - create_priority_affinity_cases - create_nonpriority_affinity_cases - create_set_of_affinity_cases + create_cavc_affinity_cases + create_hearing_affinity_cases end private @@ -42,8 +41,7 @@ def create_veteran def find_or_create_active_cda_admin_judge(css_id, full_name) User.find_by_css_id(css_id) || - create(:user, :judge, :admin_intake_role, :cda_control_admin, :bva_intake_admin, :team_admin, - :with_vacols_judge_record, css_id: css_id, full_name: full_name) + create(:user, :judge, :admin_intake_role, :cda_control_admin, :bva_intake_admin, :team_admin, css_id: css_id, full_name: full_name) end def create_cda_admin_user @@ -53,43 +51,30 @@ def create_cda_admin_user judge_team.add_user(user) end - def create_priority_affinity_cases + def create_cavc_affinity_cases judges_with_attorneys.each do |judge| - 2.times do + 3.times do create_case_ready_for_less_than_cavc_affinty_days(judge) - create_case_ready_for_less_than_aod_hearing_affinity_days(judge) create_case_ready_for_more_than_cavc_affinty_days(judge) - create_case_ready_for_more_than_aod_hearing_affinity_days(judge) end end end - def create_nonpriority_affinity_cases + def create_hearing_affinity_cases judges_with_attorneys.each do |judge| - 2.times do + 3.times do create_case_ready_for_less_than_hearing_affinity_days(judge) create_case_ready_for_more_than_hearing_affinity_days(judge) end end end - def create_set_of_affinity_cases - judges_with_attorneys.each do |judge| - create_ama_affinity_cases_set(judge, (4.years + 1.week)) - create_ama_affinity_cases_set(judge, 3.years) - end - 2.times do - create_ama_affinity_cases_set(User.find_by_css_id("BVABDANIEL"), 1.year) - end - end - def judges_with_attorneys # use judges with attorneys to minimize how many cases are distributed when testing because the # alternative_batch_size is higher than the batch_size for most judge teams @judges_with_attorneys ||= JudgeTeam.all.reject { |jt| jt.attorneys.empty? }.map(&:judge).compact end - # rubocop:disable Metrics/AbcSize def create_case_ready_for_less_than_cavc_affinty_days(judge) attorney = JudgeTeam.for_judge(judge).attorneys&.filter(&:attorney_in_vacols?)&.first || create(:user, :with_vacols_attorney_record) @@ -121,7 +106,6 @@ def create_case_ready_for_less_than_cavc_affinty_days(judge) # complete the CAVC task and make the appeal ready to distribute remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -156,7 +140,6 @@ def create_case_ready_for_more_than_cavc_affinty_days(judge) # complete the CAVC task and make the appeal ready to distribute remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -180,37 +163,6 @@ def create_case_ready_for_less_than_hearing_affinity_days(judge) # set the distribution task to assigned, if it was not already dist_task = appeal.tasks.where(type: DistributionTask.name).first dist_task.assigned! unless dist_task.assigned? - create(:appeal_affinity, appeal: appeal) - - Timecop.return - end - - def create_case_ready_for_less_than_aod_hearing_affinity_days(judge) - # set system time and create the appeal - Timecop.travel(4.years.ago) - appeal = create(:appeal, :hearing_docket, :with_post_intake_tasks, veteran: create_veteran) - - # travel to when the hearing was held, then create the held hearing and post-hearing tasks: - # add 91 days for the amount of time the post-hearing tasks are open and remove 7 to make the case ready - # for less than the hearing affinity days value - Timecop.return - Timecop.travel((91 + CaseDistributionLever.ama_hearing_case_aod_affinity_days - 7).days.ago) - create(:hearing, :held, appeal: appeal, judge: judge, adding_user: User.system_user) - - # travel to when the tasks will auto-complete and complete them - Timecop.travel(91.days.from_now) - appeal.tasks.where(type: AssignHearingDispositionTask.name).first.children.map(&:completed!) - - # created granted AOD motion to make this priority - create(:advance_on_docket_motion, appeal: appeal, granted: true, person_id: appeal.claimant.person.id, - reason: Constants.AOD_REASONS.financial_distress, user: User.system_user) - - # set the distribution task to assigned, if it was not already - dist_task = appeal.tasks.where(type: DistributionTask.name).first - dist_task.assigned! unless dist_task.assigned? - create(:appeal_affinity, appeal: appeal) - - Timecop.return end def create_case_ready_for_more_than_hearing_affinity_days(judge) @@ -232,116 +184,6 @@ def create_case_ready_for_more_than_hearing_affinity_days(judge) # set the distribution task to assigned, if it was not already dist_task = appeal.tasks.where(type: DistributionTask.name).first dist_task.assigned! unless dist_task.assigned? - create(:appeal_affinity, appeal: appeal) - - Timecop.return - end - - def create_case_ready_for_more_than_aod_hearing_affinity_days(judge) - # set system time and create the appeal - Timecop.travel(4.years.ago) - appeal = create(:appeal, :hearing_docket, :with_post_intake_tasks, veteran: create_veteran) - - # travel to when the hearing was held, then create the held hearing and post-hearing tasks: - # add 91 days for the amount of time the post-hearing tasks are open and add 7 more to make the case ready - # for more than the hearing affinity days value - Timecop.return - Timecop.travel((91 + CaseDistributionLever.ama_hearing_case_aod_affinity_days + 7).days.ago) - create(:hearing, :held, appeal: appeal, judge: judge, adding_user: User.system_user) - - # travel to when the tasks will auto-complete and complete them - Timecop.travel(91.days.from_now) - appeal.tasks.where(type: AssignHearingDispositionTask.name).first.children.map(&:completed!) - - # created granted AOD motion to make this priority - create(:advance_on_docket_motion, appeal: appeal, granted: true, person_id: appeal.claimant.person.id, - reason: Constants.AOD_REASONS.financial_distress, user: User.system_user) - - # set the distribution task to assigned, if it was not already - dist_task = appeal.tasks.where(type: DistributionTask.name).first - dist_task.assigned! unless dist_task.assigned? - create(:appeal_affinity, appeal: appeal) - - Timecop.return - end - - def create_ama_affinity_cases_set(judge, years_old) - attorney = JudgeTeam.for_judge(judge).attorneys&.filter(&:attorney_in_vacols?)&.first || - create(:user, :with_vacols_attorney_record) - - Timecop.travel(years_old.ago) - - direct_review_appeal = create(:appeal, :direct_review_docket, :ready_for_distribution, associated_judge: judge, veteran: create_veteran) - evidence_submission_appeal = create(:appeal, :evidence_submission_docket, :ready_for_distribution, associated_judge: judge, veteran: create_veteran) - hearing_appeal = create(:appeal, :hearing_docket, :with_post_intake_tasks, veteran: create_veteran) - hearing_aod_appeal = create(:appeal, :hearing_docket, :with_post_intake_tasks, veteran: create_veteran) - - # travel to when the hearing was held, then create the held hearing and post-hearing tasks: - # add 91 days for the amount of time the post-hearing tasks are open and add 7 more to make the case ready - # for more than the hearing affinity days value - Timecop.return - Timecop.travel(92.days.ago) - create(:hearing, :held, appeal: hearing_appeal, judge: judge, adding_user: User.system_user) - create(:hearing, :held, appeal: hearing_aod_appeal, judge: judge, adding_user: User.system_user) - - Timecop.travel(91.days.from_now) - hearing_appeal.tasks.where(type: AssignHearingDispositionTask.name).first.children.map(&:completed!) - hearing_aod_appeal.tasks.where(type: AssignHearingDispositionTask.name).first.children.map(&:completed!) - - # created granted AOD motion to make this priority - create(:advance_on_docket_motion, appeal: hearing_aod_appeal, granted: true, person_id: hearing_aod_appeal.claimant.person.id, - reason: Constants.AOD_REASONS.financial_distress, user: User.system_user) - - # set the distribution task to assigned, if it was not already - dist_task1 = hearing_appeal.tasks.where(type: DistributionTask.name).first - dist_task2 = hearing_aod_appeal.tasks.where(type: DistributionTask.name).first - dist_task1.assigned! unless dist_task1.assigned? - dist_task2.assigned! unless dist_task2.assigned? - - Timecop.return - Timecop.travel(years_old.ago) - - direct_review_cavc_appeal = create( - :appeal, - :dispatched, - :direct_review_docket, - associated_judge: judge, - associated_attorney: attorney, - veteran: create_veteran - ) - evidence_submission_cavc_appeal = create( - :appeal, - :dispatched, - :evidence_submission_docket, - associated_judge: judge, - associated_attorney: attorney, - veteran: create_veteran - ) - - hearing_cavc_appeal = create( - :appeal, - :dispatched, - :hearing_docket, - associated_judge: judge, - associated_attorney: attorney, - veteran: create_veteran - ) - - Timecop.travel(1.year.from_now) - - # remand_appeal will have no tasks completed on it - direct_review_cavc_remand = create(:cavc_remand, source_appeal: direct_review_cavc_appeal) - evidence_submission_cavc_remand = create(:cavc_remand, source_appeal: evidence_submission_cavc_appeal) - hearing_cavc_remand = create(:cavc_remand, source_appeal: hearing_cavc_appeal) - - # return system time back to now, then go to desired date where appeal will be ready for distribution - Timecop.return - - # complete the CAVC task and make the appeal ready to distribute - direct_review_cavc_remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - evidence_submission_cavc_remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - hearing_cavc_remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! end - # rubocop:enable Metrics/AbcSize end end diff --git a/db/seeds/appeals_for_affinity_calculation_updates.rb b/db/seeds/appeals_for_affinity_calculation_updates.rb deleted file mode 100644 index 0cc56aa0e4b..00000000000 --- a/db/seeds/appeals_for_affinity_calculation_updates.rb +++ /dev/null @@ -1,167 +0,0 @@ -# frozen_string_literal: true - -module Seeds - class AppealsForAffinityCalculationUpdates < Base - DISTRIBUTED_NONPRIORITY_RECEIPT_DATE = 1.year.ago - DISTRIBUTED_PRIORITY_RECEIPT_DATE = 1.week.ago - - def initialize - initial_id_values - end - - def seed! - RequestStore[:current_user] = User.system_user - - create_distributed_appeals_for_job_receipt_dates - - Timecop.travel(90.days.ago) do - create_ready_appeals_with_no_affinity_record - create_ready_appeals_with_affinity_no_start_date - # These are appeals with an expired affinity - create_ready_appeals_with_affinity - create_non_ready_appeals_with_affinity - end - # These are appeals with an unexpired affinity - create_ready_appeals_with_affinity - create_ready_appeals_no_affinity_to_be_created - end - - private - - def initial_id_values - @file_number ||= 950_000_000 - @participant_id ||= 950_000_000 - while Veteran.find_by(file_number: format("%09d", n: @file_number + 1)) || - VACOLS::Correspondent.find_by(ssn: format("%09d", n: @file_number + 1)) - @file_number += 2000 - @participant_id += 2000 - end - 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) - } - create(:veteran, params.merge(options)) - end - - def create_distributed_appeals_for_job_receipt_dates - Timecop.travel(4.days.ago) do - distribution = create(:distribution, :completed, judge: distributed_judge) - - direct_appeal = create(:appeal, :type_cavc_remand, :direct_review_docket, :assigned_to_judge, - associated_judge: distributed_judge, receipt_date: DISTRIBUTED_PRIORITY_RECEIPT_DATE, - veteran: create_veteran) - create(:distributed_case, appeal: direct_appeal, distribution: distribution) - - evidence_appeal = create(:appeal, :type_cavc_remand, :evidence_submission_docket, :assigned_to_judge, - associated_judge: distributed_judge, receipt_date: DISTRIBUTED_PRIORITY_RECEIPT_DATE, - veteran: create_veteran) - create(:distributed_case, appeal: evidence_appeal, distribution: distribution) - - priority_hearing_appeal = - create(:appeal, :advanced_on_docket_due_to_age, :hearing_docket, :assigned_to_judge, - associated_judge: distributed_judge, receipt_date: DISTRIBUTED_PRIORITY_RECEIPT_DATE, - veteran: create_veteran) - create(:hearing, :held, judge: distributed_judge, appeal: priority_hearing_appeal) - create(:distributed_case, appeal: priority_hearing_appeal, distribution: distribution) - - nonpriority_hearing_appeal = - create(:appeal, :hearing_docket, :assigned_to_judge, - associated_judge: distributed_judge, receipt_date: DISTRIBUTED_NONPRIORITY_RECEIPT_DATE, - veteran: create_veteran) - create(:hearing, :held, judge: distributed_judge, appeal: nonpriority_hearing_appeal) - create(:distributed_case, appeal: nonpriority_hearing_appeal, distribution: distribution) - end - end - - def create_ready_appeals_with_no_affinity_record - 2.times do - create(:appeal, :direct_review_docket, :type_cavc_remand, :ready_for_distribution, - veteran: create_veteran(first_name: "Vet", last_name: "NoAffinityRecord")) - create(:appeal, :evidence_submission_docket, :type_cavc_remand, :ready_for_distribution, - veteran: create_veteran(first_name: "Vet", last_name: "NoAffinityRecord")) - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, - veteran: create_veteran(first_name: "Vet", last_name: "NoAffinityRecord")) - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, - veteran: create_veteran(first_name: "Vet", last_name: "NoAffinityRecord")) - end - end - - def create_ready_appeals_with_affinity_no_start_date - 2.times do - create(:appeal, :direct_review_docket, :type_cavc_remand, :ready_for_distribution, - :with_appeal_affinity_no_start_date, - veteran: create_veteran(first_name: "VetWithAffinity", last_name: "NoStartDate")) - create(:appeal, :evidence_submission_docket, :type_cavc_remand, :ready_for_distribution, - :with_appeal_affinity_no_start_date, - veteran: create_veteran(first_name: "VetWithAffinity", last_name: "NoStartDate")) - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, - :held_hearing_and_ready_to_distribute, :with_appeal_affinity_no_start_date, - veteran: create_veteran(first_name: "VetWithAffinity", last_name: "NoStartDate")) - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, - :with_appeal_affinity_no_start_date, - veteran: create_veteran(first_name: "VetWithAffinity", last_name: "NoStartDate")) - end - end - - def create_ready_appeals_with_affinity - 2.times do - create(:appeal, :direct_review_docket, :type_cavc_remand, :ready_for_distribution, - :with_appeal_affinity, veteran: create_veteran(first_name: "VetWithAffinity", last_name: "StartDate")) - create(:appeal, :evidence_submission_docket, :type_cavc_remand, :ready_for_distribution, - :with_appeal_affinity, veteran: create_veteran(first_name: "VetWithAffinity", last_name: "StartDate")) - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, - :with_appeal_affinity, veteran: create_veteran(first_name: "VetWithAffinity", last_name: "StartDate")) - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, - :with_appeal_affinity, veteran: create_veteran(first_name: "VetWithAffinity", last_name: "StartDate")) - end - end - - def create_non_ready_appeals_with_affinity - 2.times do - create(:appeal, :direct_review_docket, :type_cavc_remand, :with_appeal_affinity, - veteran: create_veteran(first_name: "VetNotReady", last_name: "WithAffinity")) - create(:appeal, :evidence_submission_docket, :type_cavc_remand, :with_appeal_affinity, - veteran: create_veteran(first_name: "VetNotReady", last_name: "WithAffinity")) - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :with_appeal_affinity, - veteran: create_veteran(first_name: "VetNotReady", last_name: "WithAffinity")) - create(:appeal, :hearing_docket, :with_appeal_affinity, - veteran: create_veteran(first_name: "VetNotReady", last_name: "WithAffinity")) - end - end - - # The receipt date on these is the time of running the seed, so they shouldn't be selected when - # running the new job with the distribuion ID from the distributed cases created here - def create_ready_appeals_no_affinity_to_be_created - 5.times do - create(:appeal, :direct_review_docket, :type_cavc_remand, :ready_for_distribution, - veteran: create_veteran(first_name: "VetReady", last_name: "ShouldntGetAffinity")) - create(:appeal, :evidence_submission_docket, :type_cavc_remand, :ready_for_distribution, - veteran: create_veteran(first_name: "VetReady", last_name: "ShouldntGetAffinity")) - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, - veteran: create_veteran(first_name: "VetReady", last_name: "ShouldntGetAffinity")) - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, - veteran: create_veteran(first_name: "VetReady", last_name: "ShouldntGetAffinity")) - end - end - - def distributed_judge - judge = User.find_by(css_id: "AFFCALCJUDGE") || - create(:user, :judge, :with_vacols_judge_record, css_id: "AFFCALCJUDGE", - full_name: "Joe AffinityCalc Judge") - create_and_add_attorney_to_team(judge) if JudgeTeam.for_judge(judge).attorneys.empty? - judge - end - - # This will make this attorney's requested distributions only recieve 3 appeals (w/ default lever values) - def create_and_add_attorney_to_team(judge) - attorney = User.find_by(css_id: "AFFCALCATTY") || - create(:user, :with_vacols_attorney_record, css_id: "AFFCALCATTY", full_name: "Jane AffinityCalc Attorney") - JudgeTeam.for_judge(judge).add_user(attorney) - end - end -end diff --git a/db/seeds/case_distribution_levers.rb b/db/seeds/case_distribution_levers.rb index c1d4bc94f61..e74bc653d66 100644 --- a/db/seeds/case_distribution_levers.rb +++ b/db/seeds/case_distribution_levers.rb @@ -22,7 +22,7 @@ def seed! validate_levers_creation updated_levers.compact! - Rails.logger.info("#{updated_levers.count} levers updated: #{updated_levers}") if updated_levers.count > 0 + puts "#{updated_levers.count} levers updated: #{updated_levers}" if updated_levers.count > 0 end private @@ -46,11 +46,9 @@ def create_lever(lever) lever_group_order: lever[:lever_group_order] ) - unless lever.valid? - Rails.logger.error( "*********************************************") - Rails.logger.error(lever.errors.full_messages) - Rails.logger.error( "*********************************************") - end + puts "*********************************************" unless lever.valid? + puts lever.errors.full_messages unless lever.valid? + puts "*********************************************" unless lever.valid? end # For properties missing those were intentionally ignored so that they would not @@ -103,8 +101,8 @@ def validate_levers_creation levers = CaseDistributionLevers.levers.map { |lever| lever[:item] } existing_levers = CaseDistributionLever.all.map(&:item) - Rails.logger.info("#{CaseDistributionLever.count} levers exist") - Rails.logger.info("Levers not created #{levers - existing_levers}") if levers.length != existing_levers.length + puts "#{CaseDistributionLever.count} levers exist" + puts "Levers not created #{levers - existing_levers}" if levers.length != existing_levers.length end class << self @@ -691,7 +689,7 @@ def full_update(item) full_update_lever(lever) end - Rails.logger.info("Levers updated: #{levers_to_update.map { |lever| lever[:item] }}") + puts "Levers updated: #{levers_to_update.map { |lever| lever[:item] }}" end private @@ -725,11 +723,9 @@ def full_update_lever(lever) lever_group_order: lever[:lever_group_order] ) - unless lever.valid? - Rails.logger.error( "*********************************************") - Rails.logger.error(lever.errors.full_messages) - Rails.logger.error( "*********************************************") - end + puts "*********************************************" unless existing_lever.valid? + puts existing_lever.errors.full_messages unless existing_lever.valid? + puts "*********************************************" unless existing_lever.valid? end end end diff --git a/db/seeds/case_distribution_test_data.rb b/db/seeds/case_distribution_test_data.rb index 7b233db8322..7a250b81b10 100644 --- a/db/seeds/case_distribution_test_data.rb +++ b/db/seeds/case_distribution_test_data.rb @@ -160,27 +160,27 @@ def regional_office end # functions for creating appeals in batches - def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, receipt_date, appeal_affinity_start_date) + def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, receipt_date, distribution_task_assigned_at_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_aod_appeal(hearing_judge, receipt_date, appeal_affinity_start_date) + create_ama_hearing_held_aod_appeal(hearing_judge, receipt_date, distribution_task_assigned_at_date) end end - def create_create_legacy_appeals(number_of_appeals_to_create, receipt_date, appeal_affinity_start_date) + def create_create_legacy_appeals(number_of_appeals_to_create, receipt_date, distribution_task_assigned_at_date) number_of_appeals_to_create.times.each do - create_legacy_appeal(receipt_date, appeal_affinity_start_date) + create_legacy_appeal(receipt_date, distribution_task_assigned_at_date) end end - def create_direct_review_appeals(number_of_appeals_to_create, receipt_date, assigned_at_date) + def create_direct_review_appeals(number_of_appeals_to_create, receipt_date, distribution_task_assigned_at_date) number_of_appeals_to_create.times.each do - create_direct_review_appeal(receipt_date, assigned_at_date) + create_direct_review_appeal(receipt_date, distribution_task_assigned_at_date) end end # AMA HH AOD appeal creation functions - def create_ama_hearing_held_aod_appeal(hearing_judge, receipt_date, appeal_affinity_start_date) - Timecop.travel(appeal_affinity_start_date) + def create_ama_hearing_held_aod_appeal(hearing_judge, receipt_date, distribution_task_assigned_at_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :hearing_docket, @@ -188,7 +188,6 @@ def create_ama_hearing_held_aod_appeal(hearing_judge, receipt_date, appeal_affin :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, :tied_to_judge, - :with_appeal_affinity, veteran: create_veteran_for_ama_hearing_held_judge, receipt_date: receipt_date, tied_judge: hearing_judge, @@ -207,8 +206,8 @@ def create_veteran_for_ama_hearing_held_judge end # Legacy appeal creation functions - def create_legacy_appeal(receipt_date, appeal_affinity_start_date) - Timecop.travel(appeal_affinity_start_date) + def create_legacy_appeal(receipt_date, distribution_task_assigned_at_date) + Timecop.travel(distribution_task_assigned_at_date) veteran = create_veteran_for_legacy_inactive_admin_judge_team correspondent = create(:correspondent, @@ -267,8 +266,8 @@ def create_video_vacols_case(veteran, correspondent, judge, receipt_date) end # Direct review appeal creation functions - def create_direct_review_appeal(receipt_date, assigned_at_date) - Timecop.travel(assigned_at_date) + def create_direct_review_appeal(receipt_date, distributions_task_assigned_at_date) + Timecop.travel(distributions_task_assigned_at_date) create( :appeal, :direct_review_docket, diff --git a/db/seeds/cases_tied_to_judges_no_longer_with_board.rb b/db/seeds/cases_tied_to_judges_no_longer_with_board.rb index 528e1c4f24d..cceb652729c 100644 --- a/db/seeds/cases_tied_to_judges_no_longer_with_board.rb +++ b/db/seeds/cases_tied_to_judges_no_longer_with_board.rb @@ -397,7 +397,6 @@ def create_ama_appeals_ready_to_distribute_45_days(judge, veteran) :with_post_intake_tasks, :held_hearing_and_ready_to_distribute, :with_request_issues, - :with_appeal_affinity, issue_count: 1, tied_judge: judge, veteran: veteran, @@ -414,7 +413,6 @@ def create_ama_appeals_ready_to_distribute_65_days(judge, veteran) :with_post_intake_tasks, :held_hearing_and_ready_to_distribute, :with_request_issues, - :with_appeal_affinity, issue_count: 1, tied_judge: judge, veteran: veteran, diff --git a/db/seeds/demo_aod_hearing_case_lever_test_data.rb b/db/seeds/demo_aod_hearing_case_lever_test_data.rb index 52054a9a74c..c2212956bbf 100644 --- a/db/seeds/demo_aod_hearing_case_lever_test_data.rb +++ b/db/seeds/demo_aod_hearing_case_lever_test_data.rb @@ -63,33 +63,33 @@ def create_appeals create_direct_review_appeals(30, find_judge("NotHearingDocket"), 10.days.ago, 20.years.ago) end - def create_ama_hearing_held_aod_cavc_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_aod_cavc_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_aod_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_aod_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_cavc_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_cavc_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_direct_review_appeals(number_of_appeals_to_create, associated_judge, appeal_affinity_start_date, receipt_date) + def create_direct_review_appeals(number_of_appeals_to_create, associated_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_direct_review_appeal(associated_judge, appeal_affinity_start_date, receipt_date) + create_direct_review_appeal(associated_judge, distribution_task_assigned_at_date, receipt_date) end end @@ -187,8 +187,8 @@ def create_veteran(options = {}) # Appeal Creation Functions # AMA Hearing Held AOD and CAVC appeal creation functions - def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date + 1.day) + def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date + 1.day) ama_hearing_aod_cavc_appeal= create( :appeal, :hearing_docket, @@ -204,10 +204,9 @@ def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start associated_attorney: find_attorney("CAVCATNY") ) Timecop.return - Timecop.travel(appeal_affinity_start_date) + Timecop.travel(distribution_task_assigned_at_date) remand = create(:cavc_remand, source_appeal: ama_hearing_aod_cavc_appeal) remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -225,8 +224,8 @@ def create_attorney_for_ama_hearing_held_aod_cavc end # AMA Hearing Held AOD appeal creation functions - def create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_ama_hearing_held_aod_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :hearing_docket, @@ -234,7 +233,6 @@ def create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, :tied_to_judge, - :with_appeal_affinity, veteran: create_veteran_for_ama_hearing_held_aod_judge, receipt_date: receipt_date, tied_judge: hearing_judge, @@ -253,8 +251,8 @@ def create_veteran_for_ama_hearing_held_aod_judge end # AMA Hearing Held CAVC appeal creation functions - def create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date + 1.day) + def create_ama_hearing_held_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date + 1.day) ama_hearing_cavc_appeal = create( :appeal, :hearing_docket, @@ -269,10 +267,9 @@ def create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_dat associated_attorney: find_attorney("CAVCATNY") ) Timecop.return - Timecop.travel(appeal_affinity_start_date) + Timecop.travel(distribution_task_assigned_at_date) remand = create(:cavc_remand, source_appeal: ama_hearing_cavc_appeal) remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -286,15 +283,14 @@ def create_veteran_for_ama_hearing_held_cavc_judge end # AMA Hearing Held Non-AOD, Non-CAVC appeal creation functions - def create_ama_hearing_held_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_ama_hearing_held_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :hearing_docket, :with_post_intake_tasks, :held_hearing_and_ready_to_distribute, :tied_to_judge, - :with_appeal_affinity, veteran: create_veteran_for_ama_hearing_held_judge, receipt_date: receipt_date, tied_judge: hearing_judge, @@ -313,8 +309,8 @@ def create_veteran_for_ama_hearing_held_judge end # Direct review appeal creation functions - def create_direct_review_appeal(associated_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_direct_review_appeal(associated_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :direct_review_docket, diff --git a/db/seeds/demo_non_aod_hearing_case_lever_test_data.rb b/db/seeds/demo_non_aod_hearing_case_lever_test_data.rb index 238421d0a97..b8ef7f35817 100644 --- a/db/seeds/demo_non_aod_hearing_case_lever_test_data.rb +++ b/db/seeds/demo_non_aod_hearing_case_lever_test_data.rb @@ -69,33 +69,33 @@ def create_appeals end - def create_ama_hearing_held_aod_cavc_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_aod_cavc_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_aod_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_aod_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_aod_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_cavc_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_cavc_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_ama_hearing_held_appeals(number_of_appeals_to_create, hearing_judge, appeal_affinity_start_date, receipt_date) + def create_ama_hearing_held_appeals(number_of_appeals_to_create, hearing_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_ama_hearing_held_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) + create_ama_hearing_held_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) end end - def create_direct_review_appeals(number_of_appeals_to_create, associated_judge, appeal_affinity_start_date, receipt_date) + def create_direct_review_appeals(number_of_appeals_to_create, associated_judge, distribution_task_assigned_at_date, receipt_date) number_of_appeals_to_create.times.each do - create_direct_review_appeal(associated_judge, appeal_affinity_start_date, receipt_date) + create_direct_review_appeal(associated_judge, distribution_task_assigned_at_date, receipt_date) end end @@ -192,8 +192,8 @@ def create_veteran(options = {}) # Appeal Creation Functions # AMA Hearing Held AOD and CAVC appeal creation functions - def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date + 1.day) + def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date + 1.day) ama_hearing_aod_cavc_appeal= create( :appeal, :hearing_docket, @@ -209,10 +209,9 @@ def create_ama_hearing_held_aod_cavc_appeal(hearing_judge, appeal_affinity_start associated_attorney: find_attorney("CAVCATNY") ) Timecop.return - Timecop.travel(appeal_affinity_start_date) + Timecop.travel(distribution_task_assigned_at_date) remand = create(:cavc_remand, source_appeal: ama_hearing_aod_cavc_appeal) remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -226,8 +225,8 @@ def create_veteran_for_ama_hearing_held_aod_cavc_judge end # AMA Hearing Held AOD appeal creation functions - def create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_ama_hearing_held_aod_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :hearing_docket, @@ -235,7 +234,6 @@ def create_ama_hearing_held_aod_appeal(hearing_judge, appeal_affinity_start_date :advanced_on_docket_due_to_age, :held_hearing_and_ready_to_distribute, :tied_to_judge, - :with_appeal_affinity, veteran: create_veteran_for_ama_hearing_held_aod_judge, receipt_date: receipt_date, tied_judge: hearing_judge, @@ -254,8 +252,8 @@ def create_veteran_for_ama_hearing_held_aod_judge end # AMA Hearing Held CAVC appeal creation functions - def create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date + 1.day) + def create_ama_hearing_held_cavc_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date + 1.day) ama_hearing_cavc_appeal = create( :appeal, :hearing_docket, @@ -270,10 +268,9 @@ def create_ama_hearing_held_cavc_appeal(hearing_judge, appeal_affinity_start_dat associated_attorney: find_attorney("CAVCATNY") ) Timecop.return - Timecop.travel(appeal_affinity_start_date) + Timecop.travel(distribution_task_assigned_at_date) remand = create(:cavc_remand, source_appeal: ama_hearing_cavc_appeal) remand.remand_appeal.tasks.where(type: SendCavcRemandProcessedLetterTask.name).first.completed! - create(:appeal_affinity, appeal: remand.remand_appeal) Timecop.return end @@ -287,15 +284,14 @@ def create_veteran_for_ama_hearing_held_cavc_judge end # AMA Hearing Held Non-AOD, Non-CAVC appeal creation functions - def create_ama_hearing_held_appeal(hearing_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_ama_hearing_held_appeal(hearing_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :hearing_docket, :with_post_intake_tasks, :held_hearing_and_ready_to_distribute, :tied_to_judge, - :with_appeal_affinity, veteran: create_veteran_for_ama_hearing_held_judge, receipt_date: receipt_date, tied_judge: hearing_judge, @@ -314,8 +310,8 @@ def create_veteran_for_ama_hearing_held_judge end # Direct review appeal creation functions - def create_direct_review_appeal(associated_judge, appeal_affinity_start_date, receipt_date) - Timecop.travel(appeal_affinity_start_date) + def create_direct_review_appeal(associated_judge, distribution_task_assigned_at_date, receipt_date) + Timecop.travel(distribution_task_assigned_at_date) create( :appeal, :direct_review_docket, diff --git a/db/seeds/notification_events.rb b/db/seeds/notification_events.rb index ff50a4e760c..3b3ec85c49c 100644 --- a/db/seeds/notification_events.rb +++ b/db/seeds/notification_events.rb @@ -11,17 +11,17 @@ def seed! private def create_notification_events - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.quarterly_notification, email_template_id: "d9cf3926-d6b7-4ec7-ba06-a430741db68c", sms_template_id: "44ac639e-e90b-4423-8d7b-acfa8e5131d8") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, email_template_id: "ae2f0d17-247f-47ee-8f1a-b83a71e0f050", sms_template_id: "9953f7e8-80cb-4fe4-aaef-0309410c84e3") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, email_template_id: "8124f1e1-975b-41f5-ad07-af078f783106", sms_template_id: "78b50f00-6707-464b-b3f9-c87b3f8ed790") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_contested_claims, email_template_id: "dc4a0400-ee8f-4486-86d8-3b25ec7a43f3", sms_template_id: "ef418229-0c50-4fb1-8a3a-e134acc57bfc") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, email_template_id: "27bf814b-f065-4fc8-89af-ae1292db894e", sms_template_id: "c2798da3-4c7a-43ed-bc16-599329eaf7cc") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, email_template_id: "14b0022f-0431-485b-a188-15f104766ef4", sms_template_id: "ec310973-b013-4b71-ac12-2ac86fb5738a") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.postponement_of_hearing, email_template_id: "e36fe052-258f-42aa-8b3e-a9aca1cd1c2e", sms_template_id: "27f3aa08-91e2-4e77-9636-5f6cb6bc7574") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, email_template_id: "079ad556-ed04-4491-8661-19cd8b1c537d", sms_template_id: "69047f23-b161-441e-a155-0aeab62a886e") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, email_template_id: "5b7a4450-2d9d-44ad-8691-cc195e3aa5e4", sms_template_id: "48ec08e3-bf86-4329-af2c-943415396699") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, email_template_id: "33f1f441-325e-4825-adb3-3bde3393d79d", sms_template_id: "3adcbf09-827d-4d02-af28-864ab2e56b6f") - NotificationEvent.find_or_create_by(event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, email_template_id: "33496907-3292-48cb-8543-949023941b4a", sms_template_id: "02bc8052-1a8c-4e55-bb33-66bb2b50ad67") + NotificationEvent.find_or_create_by(event_type: "Quarterly Notification", email_template_id: "d9cf3926-d6b7-4ec7-ba06-a430741db68c", sms_template_id: "44ac639e-e90b-4423-8d7b-acfa8e5131d8") + NotificationEvent.find_or_create_by(event_type: "Appeal docketed", email_template_id: "ae2f0d17-247f-47ee-8f1a-b83a71e0f050", sms_template_id: "9953f7e8-80cb-4fe4-aaef-0309410c84e3") + NotificationEvent.find_or_create_by(event_type: "Appeal decision mailed (Non-contested claims)", email_template_id: "8124f1e1-975b-41f5-ad07-af078f783106", sms_template_id: "78b50f00-6707-464b-b3f9-c87b3f8ed790") + NotificationEvent.find_or_create_by(event_type: "Appeal decision mailed (Contested claims)", email_template_id: "dc4a0400-ee8f-4486-86d8-3b25ec7a43f3", sms_template_id: "ef418229-0c50-4fb1-8a3a-e134acc57bfc") + NotificationEvent.find_or_create_by(event_type: "Hearing scheduled", email_template_id: "27bf814b-f065-4fc8-89af-ae1292db894e", sms_template_id: "c2798da3-4c7a-43ed-bc16-599329eaf7cc") + NotificationEvent.find_or_create_by(event_type: "Withdrawal of hearing", email_template_id: "14b0022f-0431-485b-a188-15f104766ef4", sms_template_id: "ec310973-b013-4b71-ac12-2ac86fb5738a") + NotificationEvent.find_or_create_by(event_type: "Postponement of hearing", email_template_id: "e36fe052-258f-42aa-8b3e-a9aca1cd1c2e", sms_template_id: "27f3aa08-91e2-4e77-9636-5f6cb6bc7574") + NotificationEvent.find_or_create_by(event_type: "Privacy Act request pending", email_template_id: "079ad556-ed04-4491-8661-19cd8b1c537d", sms_template_id: "69047f23-b161-441e-a155-0aeab62a886e") + NotificationEvent.find_or_create_by(event_type: "Privacy Act request complete", email_template_id: "5b7a4450-2d9d-44ad-8691-cc195e3aa5e4", sms_template_id: "48ec08e3-bf86-4329-af2c-943415396699") + NotificationEvent.find_or_create_by(event_type: "VSO IHP pending", email_template_id: "33f1f441-325e-4825-adb3-3bde3393d79d", sms_template_id: "3adcbf09-827d-4d02-af28-864ab2e56b6f") + NotificationEvent.find_or_create_by(event_type: "VSO IHP complete", email_template_id: "33496907-3292-48cb-8543-949023941b4a", sms_template_id: "02bc8052-1a8c-4e55-bb33-66bb2b50ad67") # Following lines are fake uuids with no template NotificationEvent.find_or_create_by(event_type: "No Participant Id Found", email_template_id: "f54a9779-24b0-46a3-b2c1-494d42db0614", sms_template_id: "663c2b42-3381-46e4-9d48-f336d79901bc") NotificationEvent.find_or_create_by(event_type: "No Claimant Found", email_template_id: "ff871007-1f40-455d-beb3-5f2c71d065fc", sms_template_id: "364dd348-d577-44e8-82de-9fa000d6cd74") diff --git a/db/seeds/notifications.rb b/db/seeds/notifications.rb index cd74ebb7c12..2b9a057ebf3 100644 --- a/db/seeds/notifications.rb +++ b/db/seeds/notifications.rb @@ -275,213 +275,213 @@ def notification_content def create_notifications # Multiple Notifications for Legacy Appeal 2226048 - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "2226048", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Multiple Notifications for Legacy Appeal 2309289 - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "2309289", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Multiple Notifications for Legacy Appeal 2362049 - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "2362049", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Single Notification for Legacy Appeal 2591483 - Notification.create(appeals_id: "2591483", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2591483", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:appeal_docketed]) # Single Notification for Legacy Appeal 2687879 - Notification.create(appeals_id: "2687879", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2687879", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:appeal_docketed]) # Single Notification for Legacy Appeal 2727431 - Notification.create(appeals_id: "2727431", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2727431", appeals_type: "LegacyAppeal", event_date: 1.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:appeal_docketed]) # Multiple Notifications for AMA Appeal d31d7f91-91a0-46f8-b4bc-c57e139cee72 - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "d31d7f91-91a0-46f8-b4bc-c57e139cee72", appeals_type: "Appeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Multiple Notifications for AMA Appeal 25c4857b-3cc5-4497-a066-25be73aa4b6b - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "25c4857b-3cc5-4497-a066-25be73aa4b6b", appeals_type: "Appeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Multiple Notifications for AMA Appeal 7a060e04-1143-4e42-9ede-bdc42877f4f8 - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: notification_content[:appeal_docketed]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_scheduled]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_pending]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 5.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 5.days.ago, event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: notification_content[:privacy_act_complete]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 4.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 4.days.ago, event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: notification_content[:hearing_withdrawn]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 3.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 3.days.ago, event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_pending]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 2.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, notification_type: "Email and SMS", + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 2.days.ago, event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: notification_content[:vso_ihp_complete]) - Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 1.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + Notification.create(appeals_id: "7a060e04-1143-4e42-9ede-bdc42877f4f8", appeals_type: "Appeal", event_date: 1.days.ago, event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", notification_content: notification_content[:appeal_decision_mailed_non_contested], sms_notification_status: "permanent-failure") # Single Notification for AMA Appeal 952b6490-a10a-484b-a29b-31489e9a6e5a - Notification.create(appeals_id: "952b6490-a10a-484b-a29b-31489e9a6e5a", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "952b6490-a10a-484b-a29b-31489e9a6e5a", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "permanent-failure", notification_content: notification_content[:appeal_docketed]) # Single Notification for AMA Appeal fb3b029f-f07e-45bf-9277-809b44f7451a - Notification.create(appeals_id: "fb3b029f-f07e-45bf-9277-809b44f7451a", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "fb3b029f-f07e-45bf-9277-809b44f7451a", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "permanent-failure", notification_content: notification_content[:appeal_docketed]) # Single Notification for AMA Appeal 2b3afced-f698-4abe-84f9-6d44f26d20d4 - Notification.create(appeals_id: "2b3afced-f698-4abe-84f9-6d44f26d20d4", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "2b3afced-f698-4abe-84f9-6d44f26d20d4", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "permanent-failure", notification_content: notification_content[:appeal_docketed]) # Notifications of No Participant Id Found, No Claimant Found, and No External Id for Legacy Appeal 3565723 3565723 - Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No Participant Id Found", sms_notification_status: "No Participant Id Found") - Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No Claimant Found", sms_notification_status: "No Claimant Found") - Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "3565723", appeals_type: "LegacyAppeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No External Id", sms_notification_status: "No External Id") # Notifications of No Participant Id Found, No Claimant Found, and No External Id for AMA Appeal ea2303e9-2bab-472b-a653-94b71bca8ca3 3565723 - Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 8.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, notification_type: "Email and SMS", + Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 8.days.ago, event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No Participant Id Found", sms_notification_status: "No Participant Id Found") - Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 7.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, notification_type: "Email and SMS", + Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 7.days.ago, event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No Claimant Found", sms_notification_status: "No Claimant Found") - Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, notification_type: "Email and SMS", + Notification.create(appeals_id: "ea2303e9-2bab-472b-a653-94b71bca8ca3", appeals_type: "Appeal", event_date: 6.days.ago, event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "No External Id", sms_notification_status: "No External Id") end end diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index 08329f63cd6..b0e23c065bb 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -486,10 +486,4 @@ def ignorable? true end end - - class MaximumBatchSizeViolationError < StandardError - def initialize(msg = "The batch size of jobs must not exceed 10") - super(msg) - end - end end diff --git a/lib/fakes/va_notify_service.rb b/lib/fakes/va_notify_service.rb index 1dc5d00999a..5574ee91e3a 100644 --- a/lib/fakes/va_notify_service.rb +++ b/lib/fakes/va_notify_service.rb @@ -4,23 +4,23 @@ class Fakes::VANotifyService < ExternalApi::VANotifyService class << self # rubocop:disable Metrics/ParameterLists def send_email_notifications( - participant_id:, - notification_id:, - email_template_id:, - first_name:, - docket_number:, - status: "" + participant_id, + notification_id, + email_template_id, + first_name, + docket_number, + status = "" ) fake_notification_response(email_template_id) end def send_sms_notifications( - participant_id:, - notification_id:, - sms_template_id:, - first_name:, - docket_number:, - status: "" + participant_id, + notification_id, + sms_template_id, + first_name, + docket_number, + status = "" ) if participant_id.length.nil? return bad_participant_id_response diff --git a/lib/helpers/war_room.rb b/lib/helpers/war_room.rb index c660c20ddeb..ff837786af4 100644 --- a/lib/helpers/war_room.rb +++ b/lib/helpers/war_room.rb @@ -1,21 +1,14 @@ # frozen_string_literal: true -UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.freeze - module WarRoom def self.user # rubocop:disable Style/ClassVars - @@user ||= OpenStruct.new( - ip_address: "127.0.0.1", - station_id: "283", - css_id: "CSFLOW", - regional_office: "DSUSER" - ) + @@user ||= OpenStruct.new(ip_address: "127.0.0.1", station_id: "283", css_id: "CSFLOW", regional_office: "DSUSER") # rubocop:enable Style/ClassVars end class Outcode - def ama_run(identifier) + def ama_run(uuid_pass_in) # set current user RequestStore[:current_user] = OpenStruct.new( ip_address: "127.0.0.1", @@ -24,10 +17,12 @@ def ama_run(identifier) regional_office: "DSUSER" ) - appeal = find_ama_appeal(identifier) + uuid = uuid_pass_in + # set appeal parameter + appeal = Appeal.find_by_uuid(uuid) if appeal.nil? - puts("No appeal was found for that identifier. Aborting...") + puts("No appeal was found for that uuid. Aborting...") fail Interrupt end @@ -61,16 +56,6 @@ def legacy_run(vacols_id) FixFileNumberWizard.run(appeal: appeal) # need to do y or q end - - private - - def find_ama_appeal(identifier) - if identifier.match?(UUID_REGEX) - Appeal.find_by(uuid: identifier) - else - Appeal.find_by(veteran_file_number: identifier) - end - end end class OutcodeWithDuplicateVeteran @@ -101,6 +86,7 @@ def run_remediation_by_ama_appeals_uuid(uuid) def run_remediation_by_vacols_id(vacols_id) dvc = DuplicateVeteranChecker.new + dvc.run_remediation_by_vacols_id(vacols_id) end end diff --git a/lib/tasks/affinity_start_date.rake b/lib/tasks/affinity_start_date.rake deleted file mode 100644 index c4f378abcd4..00000000000 --- a/lib/tasks/affinity_start_date.rake +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -namespace :db do - desc "sets affinity_start_dates for all appeals that need them" - task affinity_start_date: :environment do - priority_dockets = %w[hearing direct_review evidence_submission] - nonpriority_dockets = %w[hearing] - docket_receipt_dates = [] - - # {Gets receipt_date for recent priority distributed appeal in each docket} - priority_dockets.each do |docket| - docket_receipt_dates << { - receipt_date: DistributedCase.joins("inner join appeals on appeals.uuid::text = distributed_cases.case_id") - .where(docket: docket, priority: true) - .where("distributed_cases.created_at >= ?", 1.week.ago) - .order("appeals.receipt_date desc") - &.first&.task&.appeal&.receipt_date, - priority: true, - docket_type: docket - } - end - - # {Gets receipt_date for recent nonpriority distributed appeal in each docket} - nonpriority_dockets.each do |docket| - docket_receipt_dates << { - receipt_date: DistributedCase.joins("inner join appeals on appeals.uuid::text = distributed_cases.case_id") - .where(docket: docket, priority: false) - .where("distributed_cases.created_at >= ?", 1.week.ago) - .order("appeals.receipt_date desc") - &.first&.task&.appeal&.receipt_date, - priority: false, - docket_type: docket - } - end - - # {Each receipt_date is then used here to get correlating appeals} - docket_receipt_dates.each do |docket_result| - next if docket_result[:receipt_date].nil? - - appeals_to_update = Appeal.extending(DistributionScopes) - .with_appeal_affinities - .ready_for_distribution - .where(docket_type: docket_result[:docket_type]) - .where("receipt_date <= (?)", docket_result[:receipt_date]) - - appeals_to_update_adjusted_for_priority = if docket_result[:priority] == true - appeals_to_update.priority - else - appeals_to_update.nonpriority - end - - # {Updates or creates appeals affinity record} - appeals_to_update_adjusted_for_priority.map do |appeal| - existing_affinity = appeal.appeal_affinity - - if existing_affinity - existing_affinity.update!(affinity_start_date: Time.zone.now) - existing_affinity - else - appeal.create_appeal_affinity!( - docket: appeal.docket_type, - priority: docket_result[:priority], - affinity_start_date: Time.zone.now - ) - end - end - end - Rails.logger.tagged("rake db:affinity_start_date") do - Rails.logger.info("The affinity_start_date rake task has been completed successfully") - end - end -end diff --git a/lib/tasks/appeal_state_synchronizer.rake b/lib/tasks/appeal_state_synchronizer.rake deleted file mode 100644 index cd8e1f29149..00000000000 --- a/lib/tasks/appeal_state_synchronizer.rake +++ /dev/null @@ -1,158 +0,0 @@ -# frozen_string_literal: true - -namespace :appeal_state_synchronizer do - desc "Used to synchronize appeal_states table using data from other sources." - task sync_appeal_states: :environment do - Rails.application.eager_load! - - adjust_legacy_hearing_statuses - adjust_ama_hearing_statuses - locate_unrecorded_docketed_states - backfill_appeal_information - end - - def map_appeal_hearing_scheduled_state(appeal_state) - if !appeal_state.appeal&.hearings&.empty? && appeal_state.appeal.hearings.max_by(&:scheduled_for).disposition.nil? - return { hearing_scheduled: true } - end - - { hearing_scheduled: false } - end - - def map_appeal_hearing_postponed_state(appeal_state) - if appeal_state.appeal.hearings&.max_by(&:scheduled_for)&.disposition == - Constants.HEARING_DISPOSITION_TYPES.postponed - { hearing_postponed: true } - else - { hearing_postponed: false } - end - end - - def map_appeal_hearing_scheduled_in_error_state(appeal_state) - if appeal_state.appeal.hearings&.max_by(&:scheduled_for)&.disposition == - Constants.HEARING_DISPOSITION_TYPES.scheduled_in_error - { scheduled_in_error: true } - else - { scheduled_in_error: false } - end - end - - def map_appeal_hearing_withdrawn_state(appeal_state) - if appeal_state.appeal.hearings&.max_by(&:scheduled_for)&.disposition == - Constants.HEARING_DISPOSITION_TYPES.cancelled - { hearing_withdrawn: true } - else - { hearing_withdrawn: false } - end - end - - # Looks at the latest legacy hearings (in the VACOLS HEARSCHED table via the HearingRepository class) - # to see if a disposition was placed onto a hearing without Caseflow having registered that event. - def adjust_legacy_hearing_statuses - relations = [ - AppealState.eligible_for_quarterly.where(hearing_scheduled: true, appeal_type: "LegacyAppeal"), - AppealState.eligible_for_quarterly.hearing_to_be_rescheduled.where(appeal_type: "LegacyAppeal") - ] - - Parallel.each(relations, in_processes: 2) do |relation| - Parallel.each(relation, in_threads: 10) do |appeal_state| - RequestStore[:current_user] = User.system_user - - hs_state = map_appeal_hearing_scheduled_state(appeal_state) - hp_state = map_appeal_hearing_postponed_state(appeal_state) - sie_state = map_appeal_hearing_scheduled_in_error_state(appeal_state) - w_state = map_appeal_hearing_withdrawn_state(appeal_state) - - appeal_state.update!([hs_state, hp_state, sie_state, w_state].inject(&:merge)) - end - end - end - - def locate_unrecorded_docketed_states - appeals_missing_states = LegacyAppeal.find_by_sql( - <<-SQL - SELECT DISTINCT la.* - FROM legacy_appeals la - JOIN notifications n ON la.vacols_id = n.appeals_id AND event_type = 'Appeal docketed' - LEFT JOIN appeal_states states ON la.id = states.appeal_id AND states.appeal_type = 'LegacyAppeal' - WHERE states.id IS NULL - SQL - ) - - Parallel.each(appeals_missing_states, in_threads: 10) do |appeal| - # It's necessary to have a current user set whenever creating appeal_states records - # as created_by_id is a required field, AND it's derived from RequestStore[:current_user] - # in some higher environments. This must be done in each thread since a RequestStore instance's - # contents are scoped to each thread. - RequestStore[:current_user] = User.system_user - - appeal.appeal_state.appeal_docketed_appeal_state_update_action! - end - end - - def incorrect_hearing_scheduled_appeal_states_query - <<-SQL - SELECT DISTINCT * - FROM appeal_states - WHERE hearing_scheduled IS TRUE - AND appeal_type = 'Appeal' - AND id NOT IN ( - SELECT s.id - FROM appeals - INNER JOIN tasks ON appeals.id = tasks.appeal_id - INNER JOIN hearings h ON appeals.id = h.appeal_id - INNER JOIN appeal_states s ON s.appeal_id = appeals.id AND s.appeal_type = 'Appeal' - WHERE tasks.appeal_type = 'Appeal' - AND tasks.type = 'AssignHearingDispositionTask' - AND tasks.status = 'assigned' - AND appeals.docket_type = 'hearing' - AND h.disposition IS NULL - ) - SQL - end - - def adjust_ama_hearing_statuses - incorrect_appeal_states = AppealState.find_by_sql(incorrect_hearing_scheduled_appeal_states_query) - - Parallel.each(incorrect_appeal_states, in_threads: 10) do |state_to_correct| - RequestStore[:current_user] = User.system_user - - state_to_correct.update!(hearing_scheduled: false) - end - end - - def ama_backfill_sql - <<-SQL - UPDATE notifications n - SET notifiable_id = a.id, - notifiable_type = 'Appeal' - FROM appeals a - WHERE n.appeals_id = a.uuid::text - SQL - end - - def legacy_backfill_sql - <<-SQL - UPDATE notifications n - SET notifiable_id = la.id, - notifiable_type = 'LegacyAppeal' - FROM legacy_appeals la - WHERE n.appeals_id = la.vacols_id - SQL - end - - def backfill_appeal_information - begin - # Temporarily Bump Up Timeout - ActiveRecord::Base.connection.execute("SET statement_timeout = '600s'") - - ActiveRecord::Base.connection.execute(ama_backfill_sql) - ActiveRecord::Base.connection.execute(legacy_backfill_sql) - rescue StandardError => error - Rails.logger.error("#{error.class}: #{error.message}\n#{error.backtrace}") - ensure - # Set Timeout Back - ActiveRecord::Base.connection.execute("SET statement_timeout = '30s'") - end - end -end diff --git a/spec/controllers/swagger/v3/ama_issues_spec.rb b/spec/controllers/api/docs/v3/ama_issues_spec.rb similarity index 86% rename from spec/controllers/swagger/v3/ama_issues_spec.rb rename to spec/controllers/api/docs/v3/ama_issues_spec.rb index 3df4603aaac..a7363e28a0b 100644 --- a/spec/controllers/swagger/v3/ama_issues_spec.rb +++ b/spec/controllers/api/docs/v3/ama_issues_spec.rb @@ -2,7 +2,7 @@ context "api/docs/v3/ama_issues.yaml" do let(:spec) do - YAML.safe_load(File.read(File.join(Rails.root, "app/controllers/swagger/v3/ama_issues.yaml"))) + YAML.safe_load(File.read(File.join(Rails.root, "app/controllers/api/docs/v3/ama_issues.yaml"))) end it "exists and is valid yaml" do @@ -12,7 +12,7 @@ it "has veteran participant id mentioned in parameters" do parameters = spec.dig( "paths", - "/find_by_veteran/{veteran_participant_id}", + "/api/v3/issues/ama/find_by_veteran/{veteran_participant_id}", "get", "parameters" ) @@ -22,7 +22,7 @@ it "has page mentioned in parameters" do parameters = spec.dig( "paths", - "/find_by_veteran/{veteran_participant_id}", + "/api/v3/issues/ama/find_by_veteran/{veteran_participant_id}", "get", "parameters" ) @@ -33,7 +33,7 @@ it "has the status codes accounted for" do responzez = spec.dig( "paths", - "/find_by_veteran/{veteran_participant_id}", + "/api/v3/issues/ama/find_by_veteran/{veteran_participant_id}", "get", "responses" ) diff --git a/spec/controllers/swagger/v3/decision_reviews_spec.rb b/spec/controllers/api/docs/v3/decision_reviews_spec.rb similarity index 68% rename from spec/controllers/swagger/v3/decision_reviews_spec.rb rename to spec/controllers/api/docs/v3/decision_reviews_spec.rb index be910800b60..922ec7c8fbd 100644 --- a/spec/controllers/swagger/v3/decision_reviews_spec.rb +++ b/spec/controllers/api/docs/v3/decision_reviews_spec.rb @@ -2,7 +2,7 @@ context "api/docs/v3/decision_reviews.yaml" do let(:spec) do - YAML.safe_load(File.read(File.join(Rails.root, "app/controllers/swagger/v3/decision_reviews.yaml"))) + YAML.safe_load(File.read(File.join(Rails.root, "app/controllers/api/docs/v3/decision_reviews.yaml"))) end it "exists and is valid yaml" do @@ -54,31 +54,4 @@ expect(hlr_errors_in_spec).to match_array(hlr_errors) end - - describe "#decision_reviews" do - describe "/higher_level_reviews documentation" do - let(:hlr_doc) do - spec.dig("paths", "/higher_level_reviews", "post") - end - it "should have POST" do - expect(hlr_doc).to be_present - end - end - describe "/intake_statuses/{uuid} documentation" do - let(:hlr_intake_status_doc) do - spec.dig("paths", "/intake_statuses/{uuid}", "get") - end - it "should have GET" do - expect(hlr_intake_status_doc).to be_present - end - end - describe "/higher_level_reviews/{uuid} documentation" do - let(:hlr_intake_status_doc) do - spec.dig("paths", "/higher_level_reviews/{uuid}", "get") - end - it "should have GET" do - expect(hlr_intake_status_doc).to be_present - end - end - end end diff --git a/spec/controllers/api/v1/va_notify_controller_spec.rb b/spec/controllers/api/v1/va_notify_controller_spec.rb index 895b7bd04f9..d20084033ba 100644 --- a/spec/controllers/api/v1/va_notify_controller_spec.rb +++ b/spec/controllers/api/v1/va_notify_controller_spec.rb @@ -13,7 +13,7 @@ appeals_id: appeal.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", - event_type: Constants.EVENT_TYPE_FILTERS.quarterly_notification, + event_type: "Quarterly Notification", notification_type: "Email", notified_at: "2023-02-28 14:11:51.91467", email_notification_external_id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -26,7 +26,7 @@ appeals_id: appeal.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", - event_type: Constants.EVENT_TYPE_FILTERS.quarterly_notification, + event_type: "Quarterly Notification", notification_type: "Email", notified_at: "2023-02-28 14:11:51.91467", sms_notification_external_id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", diff --git a/spec/controllers/appeals_controller_spec.rb b/spec/controllers/appeals_controller_spec.rb index 83e6de31ff1..e81086e86ad 100644 --- a/spec/controllers/appeals_controller_spec.rb +++ b/spec/controllers/appeals_controller_spec.rb @@ -759,29 +759,23 @@ def allow_vbms_to_return_empty_array let!(:notifications) do [ create(:notification, appeals_id: legacy_appeal.vacols_id, appeals_type: legacy_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, - notification_type: "SMS", + event_date: 6.days.ago, event_type: "Appeal docketed", notification_type: "SMS", email_notification_status: nil, sms_notification_status: "Success"), create(:notification, appeals_id: ama_appeal.uuid, appeals_type: ama_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "Email", + event_date: 6.days.ago, event_type: "Hearing scheduled", notification_type: "Email", email_notification_status: "Success", sms_notification_status: nil), create(:notification, appeals_id: legacy_appeal_without_claimant.vacols_id, appeals_type: legacy_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "SMS", + event_date: 6.days.ago, event_type: "Hearing scheduled", notification_type: "SMS", email_notification_status: nil, sms_notification_status: "No Claimant Found"), create(:notification, appeals_id: legacy_appeal_without_participant_id.vacols_id, appeals_type: legacy_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "SMS", + event_date: 6.days.ago, event_type: "Hearing scheduled", notification_type: "SMS", email_notification_status: nil, sms_notification_status: "No Participant Id Found"), create(:notification, appeals_id: ama_appeal_without_claimant.uuid, appeals_type: ama_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "Email", + event_date: 6.days.ago, event_type: "Hearing scheduled", notification_type: "Email", email_notification_status: "No Claimant Found", sms_notification_status: nil), create(:notification, appeals_id: ama_appeal_without_participant_id.uuid, appeals_type: ama_appeals_type, - event_date: 6.days.ago, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "SMS", + event_date: 6.days.ago, event_type: "Hearing scheduled", notification_type: "SMS", email_notification_status: nil, sms_notification_status: "No Participant Id Found") ] end @@ -801,7 +795,7 @@ def allow_vbms_to_return_empty_array it "should have the event type of 'Appeal docketed'" do subject response_body = JSON.parse(subject.body) - expect(response_body.first["attributes"]["event_type"]).to eq Constants.EVENT_TYPE_FILTERS.appeal_docketed + expect(response_body.first["attributes"]["event_type"]).to eq "Appeal docketed" end it "should return a successful response" do subject @@ -863,7 +857,7 @@ def allow_vbms_to_return_empty_array it "should have the event type of 'Hearing scheduled'" do subject response_body = JSON.parse(subject.body) - expect(response_body.first["attributes"]["event_type"]).to eq Constants.EVENT_TYPE_FILTERS.hearing_scheduled + expect(response_body.first["attributes"]["event_type"]).to eq "Hearing scheduled" end it "should return a succesful response" do subject diff --git a/spec/controllers/hearings_controller_spec.rb b/spec/controllers/hearings_controller_spec.rb index c844441cdd8..aa3546a0646 100644 --- a/spec/controllers/hearings_controller_spec.rb +++ b/spec/controllers/hearings_controller_spec.rb @@ -13,8 +13,6 @@ let!(:vso_participant_id) { "12345" } describe "PATCH update" do - let(:legacy_appeal_state) { legacy_hearing.appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } } - it "should be successful", :aggregate_failures do params = { notes: "Test", @@ -27,9 +25,6 @@ }, prepped: true } - - expect(legacy_appeal_state.hearing_scheduled).to eq true - patch :update, as: :json, params: { id: legacy_hearing.external_id, hearing: params } expect(response.status).to eq 200 response_body = JSON.parse(response.body)["data"] @@ -40,12 +35,10 @@ expect(response_body["disposition"]).to eq "held" expect(response_body["location"]["facility_id"]).to eq "vba_301" expect(response_body["prepped"]).to eq true - expect(legacy_appeal_state.reload.hearing_scheduled).to eq false end context "when updating an ama hearing" do let!(:hearing) { create(:hearing, :with_tasks) } - let(:appeal_state) { hearing.appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } } it "should update an ama hearing", :aggregate_failures do params = { @@ -58,9 +51,6 @@ prepped: true, evidence_window_waived: true } - - expect(appeal_state.hearing_scheduled).to eq true - patch :update, as: :json, params: { id: hearing.external_id, hearing: params } expect(response.status).to eq 200 response_body = JSON.parse(response.body)["data"] @@ -70,7 +60,6 @@ expect(response_body["prepped"]).to eq true expect(response_body["location"]["facility_id"]).to eq "vba_301" expect(response_body["evidence_window_waived"]).to eq true - expect(appeal_state.reload.hearing_scheduled).to eq false end end diff --git a/spec/factories/appeal.rb b/spec/factories/appeal.rb index c73c2424981..a90f13b070f 100644 --- a/spec/factories/appeal.rb +++ b/spec/factories/appeal.rb @@ -21,9 +21,6 @@ Fakes::VBMSService.document_records ||= {} Fakes::VBMSService.document_records[appeal.veteran_file_number] = evaluator.documents - - # There is a callback to create an AppealState record for appeal_docketed that will raise an error without this - RequestStore[:current_user] ||= User.system_user unless RequestStore[:current_user] end # Appeal's after_save interferes with explicit updated_at values @@ -452,37 +449,12 @@ trait :ready_for_distribution do with_post_intake_tasks completed_distribution_task - - after(:create) do |appeal, _evaluator| - appeal.reload - end - end - - trait :ready_for_distribution_with_appeal_affinity do - ready_for_distribution - with_appeal_affinity end trait :cavc_ready_for_distribution do completed_distribution_task end - trait :with_appeal_affinity do - transient do - affinity_start_date { Time.zone.now } - end - - after(:create) do |appeal, evaluator| - create(:appeal_affinity, appeal: appeal, affinity_start_date: evaluator.affinity_start_date) - end - end - - trait :with_appeal_affinity_no_start_date do - after(:create) do |appeal, _evaluator| - create(:appeal_affinity, appeal: appeal, affinity_start_date: nil) - end - end - trait :completed_distribution_task do after(:create) do |appeal, _evaluator| distribution_tasks = appeal.tasks.select { |task| task.is_a?(DistributionTask) } diff --git a/spec/factories/appeal_affinity.rb b/spec/factories/appeal_affinity.rb deleted file mode 100644 index b1874295538..00000000000 --- a/spec/factories/appeal_affinity.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -# Creates an AppealAffinity record for an appeal, used to calculate affinity windows during a distribution. -# The default behavior creates a standard Appeal using the appeal factory. An Appeal or VACOLS::Case object -# can be linked by passing it in as the "appeal" parameter. -FactoryBot.define do - factory :appeal_affinity do - case_type { appeal.class.name } - case_id do - if appeal.is_a?(Appeal) - appeal.uuid - elsif appeal.is_a?(VACOLS::Case) - appeal.bfkey - end - end - - docket do - if appeal.is_a?(Appeal) - appeal.docket_type - elsif appeal.is_a?(VACOLS::Case) - "legacy" - end - end - - priority do - if appeal.is_a?(Appeal) - (appeal.aod? || appeal.cavc?) - elsif appeal.is_a?(VACOLS::Case) - (appeal.bfac == "7" || appeal.notes.map(&:tskactcd).any? { |n| %w[B B1 B2].include?(n) }) - end - end - - affinity_start_date { Time.zone.now } - - transient do - # This transient trait can't be called "case" because that is a keyword in Ruby, so we're calling it "Appeal" - appeal { create(:appeal) } - end - - after(:create) do |appeal_affinity, evaluator| - if evaluator.distribution - appeal_affinity.distribution_id = evaluator.distribution.id - appeal_affinity.save! - end - - # This scenario will cover creating affinities from the rails console for local testing - distributed_case = DistributedCase.find_by(case_id: appeal_affinity.case_id) - - if appeal_affinity.distribution_id.nil? && distributed_case - appeal_affinity.distribution_id = distributed_case.distribution_id - appeal_affinity.save! - end - end - end -end diff --git a/spec/factories/appeal_state.rb b/spec/factories/appeal_state.rb index 2590b52f762..bb2f194546c 100644 --- a/spec/factories/appeal_state.rb +++ b/spec/factories/appeal_state.rb @@ -25,7 +25,7 @@ end trait :legacy do - appeal { create(:legacy_appeal, :with_veteran, vacols_case: create(:case)) } + appeal { create(:legacy_appeal, vacols_case: create(:case)) } end end end diff --git a/spec/factories/distributed_case.rb b/spec/factories/distributed_case.rb deleted file mode 100644 index 333dd8dda53..00000000000 --- a/spec/factories/distributed_case.rb +++ /dev/null @@ -1,22 +0,0 @@ -# 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 } - distribution { create(:distribution, judge: create(:user, :judge, :with_vacols_judge_record)) } - docket { appeal.docket_type } - docket_index { nil } - priority { (appeal.aod? || appeal.cavc?) } - ready_at { appeal.tasks.find_by(type: DistributionTask.name).assigned_at } - sct_appeal { appeal.sct_appeal? } - task { appeal.tasks.find_by(type: JudgeAssignTask.name) || create(:ama_judge_assign_task, appeal: appeal) } - genpop { true if appeal.docket_type == "hearing" } - genpop_query { "only_genpop" if appeal.docket_type == "hearing" } - - transient do - appeal { create(:appeal, :assigned_to_judge) } - end - end -end diff --git a/spec/factories/distribution.rb b/spec/factories/distribution.rb index 5783213b392..04d38273fb0 100644 --- a/spec/factories/distribution.rb +++ b/spec/factories/distribution.rb @@ -5,9 +5,8 @@ association :judge, factory: :user trait :completed do - completed_at { Time.zone.now } after(:create) do |distribution| - distribution.update(status: :completed, statistics: { batch_size: distribution.distributed_cases.count }) + distribution.update(status: :completed) end end diff --git a/spec/factories/hearing.rb b/spec/factories/hearing.rb index bd2178406c2..ab0bce4cece 100644 --- a/spec/factories/hearing.rb +++ b/spec/factories/hearing.rb @@ -4,16 +4,10 @@ factory :hearing do transient do regional_office { nil } - adding_user do - User.find_by(css_id: "HR_FCT_USER") || - create(:user, css_id: "HR_FCT_USER", full_name: "Hearing Factory AddingUser") - end + adding_user { create(:user) } end appeal { association(:appeal, :hearing_docket) } - judge do - User.find_by(css_id: "HR_FCT_JUDGE") || - create(:user, css_id: "HR_FCT_JUDGE", full_name: "Hearing Factory JudgeUser", roles: ["Hearing Prep"]) - end + judge { create(:user, roles: ["Hearing Prep"]) } uuid { SecureRandom.uuid } hearing_day do association( diff --git a/spec/factories/notification.rb b/spec/factories/notification.rb index d19d87a5a4e..7eb8d375b0a 100644 --- a/spec/factories/notification.rb +++ b/spec/factories/notification.rb @@ -18,7 +18,6 @@ updated_at { Time.zone.now } email_notification_external_id { nil } sms_notification_external_id { nil } - notifiable { nil } end factory :notification_email_only do @@ -38,7 +37,6 @@ updated_at { Time.zone.now } email_notification_external_id { md5(uniqid(time)) } sms_notification_external_id { nil } - notifiable { appeal } end factory :notification_sms_only do @@ -58,7 +56,6 @@ updated_at { Time.zone.now } email_notification_external_id { nil } sms_notification_external_id { md5(uniqid(time)) } - notifiable { appeal } end factory :notification_email_and_sms do @@ -78,6 +75,5 @@ updated_at { Time.zone.now } email_notification_external_id { md5(uniqid(time)) } sms_notification_external_id { md5(uniqid(time)) } - notifiable { appeal } end end diff --git a/spec/factories/vacols/case.rb b/spec/factories/vacols/case.rb index 52cfd37c019..ab443f8b533 100644 --- a/spec/factories/vacols/case.rb +++ b/spec/factories/vacols/case.rb @@ -265,16 +265,6 @@ bfd19 { 1.year.ago.to_date } end - trait :with_appeal_affinity do - transient do - affinity_start_date { Time.zone.now } - end - - after(:create) do |appeal, evaluator| - create(:appeal_affinity, appeal: appeal, affinity_start_date: evaluator.affinity_start_date) - end - end - trait :status_remand do bfmpro { "REM" } bfdc { "3" } diff --git a/spec/feature/explain_spec.rb b/spec/feature/explain_spec.rb index ab4e7f5c652..025abddd8f2 100644 --- a/spec/feature/explain_spec.rb +++ b/spec/feature/explain_spec.rb @@ -203,49 +203,4 @@ end end end - - context "for appeals with affinity dates" do - let!(:legacy_appeal_with_affinity) do - vacols_case = create(:case_with_form_9, :with_appeal_affinity, :ready_for_distribution) - create(:legacy_appeal, vacols_case: vacols_case) - vacols_case - end - let!(:legacy_appeal_without_affinity) do - vacols_case = create(:case_with_form_9, :ready_for_distribution) - create(:legacy_appeal, vacols_case: vacols_case) - vacols_case - end - let!(:ama_appeal_with_affinity) do - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, :with_appeal_affinity, - tied_judge: create(:user, :judge, :with_vacols_judge_record)) - end - let!(:ama_appeal_without_affinity) do - create(:appeal, :hearing_docket, :held_hearing_and_ready_to_distribute, - tied_judge: create(:user, :judge, :with_vacols_judge_record)) - end - - it "legacy appeals show the date if one exists" do - visit "explain/appeals/#{legacy_appeal_with_affinity.bfkey}" - page.find("label", text: "Task Tree").click - expect(page) - .to have_text "Affinity Start Date: #{legacy_appeal_with_affinity.appeal_affinity.affinity_start_date}" - - visit "explain/appeals/#{legacy_appeal_without_affinity.bfkey}" - page.find("label", text: "Task Tree").click - expect(page) - .not_to have_text "Affinity Start Date:" - end - - it "AMA appeals show the date if one exists" do - visit "explain/appeals/#{ama_appeal_with_affinity.uuid}" - page.find("label", text: "Task Tree").click - expect(page) - .to have_text "Affinity Start Date: #{ama_appeal_with_affinity.reload.appeal_affinity.affinity_start_date}" - - visit "explain/appeals/#{ama_appeal_without_affinity.uuid}" - page.find("label", text: "Task Tree").click - expect(page) - .not_to have_text "Affinity Start Date:" - end - end end diff --git a/spec/feature/hearings/daily_docket/ro_viewhearsched_spec.rb b/spec/feature/hearings/daily_docket/ro_viewhearsched_spec.rb index d5034b12cc2..0ab30eeb453 100644 --- a/spec/feature/hearings/daily_docket/ro_viewhearsched_spec.rb +++ b/spec/feature/hearings/daily_docket/ro_viewhearsched_spec.rb @@ -5,7 +5,7 @@ let!(:current_user) { User.authenticate!(css_id: "BVATWARNER", roles: ["RO ViewHearSched"]) } let!(:hearing) { create(:hearing, :with_tasks) } - scenario "User cannot view docket notes", skip: "Flaky test" do + scenario "User cannot view docket notes" do visit "hearings/schedule/docket/" + hearing.hearing_day.id.to_s expect(page).to_not have_button("Print all Hearing Worksheets") expect(page).to_not have_content("Edit Hearing Day") diff --git a/spec/feature/queue/appeal_notifications_page_spec.rb b/spec/feature/queue/appeal_notifications_page_spec.rb index 44dd8eca6ff..ecfef5030f9 100644 --- a/spec/feature/queue/appeal_notifications_page_spec.rb +++ b/spec/feature/queue/appeal_notifications_page_spec.rb @@ -16,8 +16,7 @@ shared_examples "with notifications" do let(:seed_notifications) do create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-01", - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, - notification_type: "Email and SMS", + event_type: "Appeal docketed", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: "555-555-5555", email_notification_status: "delivered", sms_notification_status: "delivered", notification_content: "Your appeal at the Board of Veteran's Appeals has been docketed. "\ @@ -26,22 +25,19 @@ "any questions please reach out to your Veterans Service Organization or representative "\ "or log onto VA.gov for additional information.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-02", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, - notification_type: "Email and SMS", + event_type: "Hearing scheduled", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: "Your hearing has been scheduled with a Veterans Law Judge at the "\ "Board of Veterans' Appeals. You will be notified of the details in writing shortly.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-03", - event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending, - notification_type: "Email and SMS", + event_type: "Privacy Act request pending", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: "You or your representative filed a Privacy Act request. The Board "\ "placed your appeal on hold until this request is satisfied.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-04", - event_type: Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete, - notification_type: "Email and SMS", + event_type: "Privacy Act request complete", notification_type: "Email and SMS", recipient_email: "example@example.com", recipient_phone_number: nil, email_notification_status: "delivered", sms_notification_status: "temporary-failure", notification_content: "The Privacy Act request has been satisfied and the Board will "\ @@ -50,8 +46,7 @@ "Organization or representative, if you have one, or log onto VA.gov for additional "\ "information") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-05", - event_type: Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing, - notification_type: "Email and SMS", + event_type: "Withdrawal of hearing", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "temporary-failure", notification_content: "You or your representative have requested to withdraw your hearing "\ @@ -61,8 +56,7 @@ "hearing coordinator for your region. For a list of hearing coordinators by region "\ "with contact information, please visit https://www.bva.va.gov.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-06", - event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_pending, - notification_type: "Email and SMS", recipient_email: nil, + event_type: "VSO IHP pending", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: "You filed an appeal with the Board of Veterans' Appeals. Your case "\ @@ -70,8 +64,7 @@ "Once the argument has been received, the Board of Veterans' Appeals will resume "\ "processing of your appeal.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-07", - event_type: Constants.EVENT_TYPE_FILTERS.vso_ihp_complete, - notification_type: "Email and SMS", + event_type: "VSO IHP complete", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "Success", notification_content: "The Board of Veterans' Appeals received the written argument from "\ @@ -80,7 +73,7 @@ "please reach out to your Veterans Service Organization or log onto VA.gov for additional "\ "information.") create(:notification, appeals_id: appeals_id, appeals_type: appeal.class.name, event_date: "2022-11-08", - event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email and SMS", recipient_email: nil, recipient_phone_number: nil, email_notification_status: "Success", sms_notification_status: "permanent-failure", notification_content: "The Board of Veterans' Appeals issued a decision on your appeal "\ @@ -107,7 +100,7 @@ # correct event type event_type_cell = page.find("td", match: :first) - expect(event_type_cell).to have_content(Constants.EVENT_TYPE_FILTERS.appeal_docketed) + expect(event_type_cell).to have_content("Appeal docketed") # correct notification date date_cell = page.all("td", minimum: 1)[1] @@ -145,14 +138,13 @@ # by event type filter = page.find("path", class: "unselected-filter-icon-inner-1", match: :first) filter.click - filter_option = page.find("li", class: "cf-filter-option-row", - text: Constants.EVENT_TYPE_FILTERS.appeal_docketed) + filter_option = page.find("li", class: "cf-filter-option-row", text: "Appeal docketed") filter_option.click table = page.find("tbody") cells = table.all("td", minimum: 1) expect(table).to have_selector("tr", count: 2) - expect(cells[0]).to have_content(Constants.EVENT_TYPE_FILTERS.appeal_docketed) - expect(cells[5]).to have_content(Constants.EVENT_TYPE_FILTERS.appeal_docketed) + expect(cells[0]).to have_content("Appeal docketed") + expect(cells[5]).to have_content("Appeal docketed") # clear filter filter.click @@ -206,13 +198,13 @@ # by multiple columns at once filters = page.all("path", class: "unselected-filter-icon-inner-1", minimum: 1) filters[0].click - page.find("li", class: "cf-filter-option-row", text: Constants.EVENT_TYPE_FILTERS.hearing_scheduled).click + page.find("li", class: "cf-filter-option-row", text: "Hearing scheduled").click filters[1].click page.find("li", class: "cf-filter-option-row", text: "Text").click table = page.find("tbody") cells = table.all("td", minimum: 1) expect(table).to have_selector("tr", count: 1) - expect(cells[0]).to have_content(Constants.EVENT_TYPE_FILTERS.hearing_scheduled) + expect(cells[0]).to have_content("Hearing scheduled") expect(cells[2]).to have_content("Text") end end @@ -237,7 +229,7 @@ # prev button moves to previous page click_on("Prev", match: :first) event_type_cell = page.find("td", match: :first) - expect(event_type_cell).to have_content(Constants.EVENT_TYPE_FILTERS.appeal_docketed) + expect(event_type_cell).to have_content("Appeal docketed") # prev button disabled on the first page expect(page).to have_button("Prev", disabled: true) diff --git a/spec/feature/queue/mail_task_spec.rb b/spec/feature/queue/mail_task_spec.rb index 358bfc8d1fd..d575c40a4bf 100644 --- a/spec/feature/queue/mail_task_spec.rb +++ b/spec/feature/queue/mail_task_spec.rb @@ -281,11 +281,9 @@ end it "sends proper notifications", skip: "test is failing in local env and github actions" do - scheduled_payload = AppellantNotification.create_payload(appeal, - Constants.EVENT_TYPE_FILTERS.hearing_scheduled).to_json + scheduled_payload = AppellantNotification.create_payload(appeal, "Hearing scheduled").to_json if appeal.hearings.any? - postpone_payload = AppellantNotification.create_payload(appeal, - Constants.EVENT_TYPE_FILTERS.postponement_of_hearing) + postpone_payload = AppellantNotification.create_payload(appeal, "Postponement of hearing") .to_json expect(SendNotificationJob).to receive(:perform_later).with(postpone_payload) end @@ -747,9 +745,7 @@ shared_context "async actions" do context "async actions" do it "sends withdrawal of hearing notification" do - withdrawal_payload = - AppellantNotification.create_payload(appeal, - Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing).to_json + withdrawal_payload = AppellantNotification.create_payload(appeal, "Withdrawal of hearing").to_json expect(SendNotificationJob).to receive(:perform_later).with(withdrawal_payload) perform_enqueued_jobs do diff --git a/spec/jobs/ama_notification_efolder_sync_job_spec.rb b/spec/jobs/ama_notification_efolder_sync_job_spec.rb index 66823d9b460..c6016c9e877 100644 --- a/spec/jobs/ama_notification_efolder_sync_job_spec.rb +++ b/spec/jobs/ama_notification_efolder_sync_job_spec.rb @@ -21,7 +21,7 @@ appeals_id: appeal.uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now - (10 - index).minutes, email_notification_status: "delivered") @@ -39,8 +39,6 @@ before(:all) { Seeds::NotificationEvents.new.seed! } before(:each) { stub_const("AmaNotificationEfolderSyncJob::BATCH_LIMIT", BATCH_LIMIT_SIZE) } - after(:all) { DatabaseCleaner.clean_with(:truncation, except: %w[vftypes issref]) } - context "first run" do after(:all) { clean_up_after_threads } @@ -61,7 +59,7 @@ appeals_id: appeals[6].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -87,7 +85,7 @@ appeals_id: appeals[6].uuid, appeals_type: appeals[6].class.name, event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -123,7 +121,7 @@ appeals_id: appeals[6].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "Failure Due to Deceased") @@ -153,7 +151,7 @@ appeals_id: appeals[4].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -215,7 +213,7 @@ appeals_id: appeals[4].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: 2.minutes.ago, email_notification_status: "delivered") @@ -231,7 +229,7 @@ appeals_id: appeals[4].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: 1.minute.ago, email_notification_status: "Failure Due to Deceased") @@ -246,7 +244,7 @@ appeals_id: appeals[4].uuid, appeals_type: "Appeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") diff --git a/spec/jobs/application_job_spec.rb b/spec/jobs/application_job_spec.rb index c2e8861c1a5..e145256a2d8 100644 --- a/spec/jobs/application_job_spec.rb +++ b/spec/jobs/application_job_spec.rb @@ -10,50 +10,26 @@ def perform(target = nil) end describe "ApplicationJob" do - let(:freeze_time_first_run) { Time.zone.local(2024, 8, 30, 19, 0, 20) } - let(:freeze_time_second_run) { Time.zone.local(2024, 8, 30, 20, 0, 20) } - context ".application_attr" do it "sets application request store" do JobThatIsGood.perform_now expect(RequestStore[:application]).to eq("fake_job") end - end - - context "JobExecutionTime" do - def job_execution_record_checks - expect(JobExecutionTime.count).to eq(1) - execution_time_record = JobExecutionTime.first - expect(execution_time_record.job_name).to eq("JobThatIsGood") - expect(execution_time_record.last_executed_at).to eq(Time.now.utc) - end - - it "adds record to JobExecutionTime if the IGNORE_JOB_EXECUTION_TIME constant is false" do - Timecop.freeze(freeze_time_first_run) do - expect(JobExecutionTime.count).to eq(0) - JobThatIsGood.perform_now - - job_execution_record_checks - end - end - it "update existing record in JobExecutionTime table when job is run multiple times" do - JobExecutionTime.create(job_name: JobThatIsGood.name, last_executed_at: 2.days.ago) + it "sets extra context in middleware" do + allow(Raven).to receive(:extra_context) - Timecop.freeze(freeze_time_first_run) do - expect(JobExecutionTime.count).to eq(1) - JobThatIsGood.perform_now + sqs_msg = double("sqs_msg") + allow(sqs_msg).to receive(:message_id).and_return("msgid") - job_execution_record_checks - end + JobSentryScopeMiddleware.new.call( + double("worker"), + "high_priority", + sqs_msg, + ActiveSupport::HashWithIndifferentAccess.new(job_class: "JobThatIsGood", job_id: "jobid") + ) {} - Timecop.freeze(freeze_time_second_run) do - JobThatIsGood.perform_now - expect(JobExecutionTime.count).to eq(1) - execution_time_record = JobExecutionTime.first - expect(execution_time_record.job_name).to eq("JobThatIsGood") - expect(execution_time_record.last_executed_at).to eq(Time.now.utc) - end + expect(Raven).to have_received(:extra_context).with(hash_including(application: :fake)) end end diff --git a/spec/jobs/caseflow_job_spec.rb b/spec/jobs/caseflow_job_spec.rb index d0d29c8c4a0..632808dda93 100644 --- a/spec/jobs/caseflow_job_spec.rb +++ b/spec/jobs/caseflow_job_spec.rb @@ -25,47 +25,4 @@ def perform subject end end - - context "#serialize_job_for_enqueueing" do - subject do - CaseflowJob.serialize_job_for_enqueueing(SomeCaseflowJob.new) - end - - it "serializes the job into a hash" do - result = subject - - expect(result.dig(:message_body, "job_class")).to eq "SomeCaseflowJob" - expect(result.dig(:message_body, "queue_name")).to eq "caseflow_test_low_priority" - expect( - result.dig(:message_attributes, "shoryuken_class", :string_value) - ).to eq "ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper" - end - end - - context "#enqueue_batch_of_jobs" do - let(:queue_name) { "fake_queue" } - - subject do - CaseflowJob.enqueue_batch_of_jobs( - jobs_to_enqueue: jobs, - name_of_queue: queue_name - ) - end - - context "when the number of jobs exceeds 10" do - let(:jobs) { Array.new(11).map { SomeCaseflowJob.new } } - - it "raises a MaximumBatchSizeViolationError" do - expect { subject }.to raise_error(Caseflow::Error::MaximumBatchSizeViolationError) - end - end - - context "when the number of jobs doesn't exceed 10" do - let(:jobs) { Array.new(2).map { SomeCaseflowJob.new } } - - it "does not raise a MaximumBatchSizeViolationError" do - expect { subject }.to_not raise_error(Caseflow::Error::MaximumBatchSizeViolationError) - end - end - end end diff --git a/spec/jobs/fetch_all_active_ama_appeals_job_spec.rb b/spec/jobs/fetch_all_active_ama_appeals_job_spec.rb index 31ab918362d..cdff7c1ce3b 100644 --- a/spec/jobs/fetch_all_active_ama_appeals_job_spec.rb +++ b/spec/jobs/fetch_all_active_ama_appeals_job_spec.rb @@ -57,7 +57,7 @@ end it "only OPEN Legacy Appeal records will be added to the Appeal States table" do subject.perform - expect(AppealState.all.map(&:appeal_id)).to match_array(open_ama_appeals.map(&:id)) + expect(AppealState.all.map(&:appeal_id)).to eq(open_ama_appeals.map(&:id)) expect(AppealState.all.count).to eq(5) end end diff --git a/spec/jobs/fetch_all_active_legacy_appeals_job_spec.rb b/spec/jobs/fetch_all_active_legacy_appeals_job_spec.rb index e13a3a9021e..ee563ce8ef6 100644 --- a/spec/jobs/fetch_all_active_legacy_appeals_job_spec.rb +++ b/spec/jobs/fetch_all_active_legacy_appeals_job_spec.rb @@ -85,9 +85,9 @@ create(:legacy_appeal, :with_completed_root_task, vacols_id: "5000") ] end - it "only OPEN Legacy Appeal records will be added to the Appeal States table", skip: "Flaky test" do + it "only OPEN Legacy Appeal records will be added to the Appeal States table" do subject.perform - expect(AppealState.all.map(&:appeal_id)).to match_array(open_legacy_appeals.map(&:id)) + expect(AppealState.all.map(&:appeal_id)).to eq(open_legacy_appeals.map(&:id)) expect(AppealState.all.count).to eq(5) end end diff --git a/spec/jobs/hearings/receive_notification_job_spec.rb b/spec/jobs/hearings/receive_notification_job_spec.rb index 0ed8049697a..bbad6b47a9d 100644 --- a/spec/jobs/hearings/receive_notification_job_spec.rb +++ b/spec/jobs/hearings/receive_notification_job_spec.rb @@ -124,14 +124,13 @@ context ".perform" do # create notification event record let(:hearing_scheduled_event) do - create(:notification_event, event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + create(:notification_event, event_type: "Hearing scheduled", email_template_id: "27bf814b-f065-4fc8-89af-ae1292db894e", sms_template_id: "c2798da3-4c7a-43ed-bc16-599329eaf7cc") end # create notification record let(:notification) do - create(:notification, id: 9, appeals_id: 4, appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + create(:notification, id: 9, appeals_id: 4, appeals_type: "Appeal", event_type: "Hearing scheduled", participant_id: "123456789", notification_type: "Email", recipient_email: "", event_date: Time.zone.now, email_notification_status: "Success") end diff --git a/spec/jobs/legacy_notification_efolder_sync_job_spec.rb b/spec/jobs/legacy_notification_efolder_sync_job_spec.rb index d43ce3e5ec6..7cb01075fb8 100644 --- a/spec/jobs/legacy_notification_efolder_sync_job_spec.rb +++ b/spec/jobs/legacy_notification_efolder_sync_job_spec.rb @@ -33,7 +33,7 @@ appeals_id: appeal.vacols_id, appeals_type: "LegacyAppeal", event_date: Time.zone.today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now - (10 - index).minutes, email_notification_status: "delivered") @@ -55,8 +55,6 @@ before(:all) { ensure_notification_events_exist } before(:each) { stub_const("LegacyNotificationEfolderSyncJob::BATCH_LIMIT", BATCH_LIMIT_SIZE) } - after(:all) { DatabaseCleaner.clean_with(:truncation, except: %w[vftypes issref]) } - context "first run" do after(:all) { clean_up_after_threads } @@ -91,7 +89,7 @@ appeals_id: appeals[6].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "Failure Due to Deceased") @@ -121,7 +119,7 @@ appeals_id: appeals[4].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -133,7 +131,7 @@ appeals_id: appeals[6].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -157,7 +155,7 @@ appeals_id: appeals[6].vacols_id, appeals_type: appeals[6].class.name, event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims, + event_type: "Appeal decision mailed (Non-contested claims)", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") @@ -219,7 +217,7 @@ appeals_id: appeals[4].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: 2.minutes.ago, email_notification_status: "delivered") @@ -235,7 +233,7 @@ appeals_id: appeals[4].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: 1.minute.ago, email_notification_status: "Failure Due to Deceased") @@ -251,7 +249,7 @@ appeals_id: appeals[4].vacols_id, appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: Time.zone.now, email_notification_status: "delivered") diff --git a/spec/jobs/middleware/job_message_deletion_middleware_spec.rb b/spec/jobs/middleware/job_message_deletion_middleware_spec.rb deleted file mode 100644 index f91e99e4ec8..00000000000 --- a/spec/jobs/middleware/job_message_deletion_middleware_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -describe JobMessageDeletionMiddleware do - let(:sqs) { Aws::SQS::Client.new(stub_responses: true) } - let(:msg) do - OpenStruct.new( - queue_url: "http://localhost:4576/000000000000/caseflow_development_low_priority", - data: OpenStruct.new(receipt_handle: "123456"), - client: sqs - ) - end - let(:quarterly_notification_job_body) { { "job_class" => "QuarterlyNotificationsJob" } } - let(:ama_notification_job_body) { { "job_class" => "AmaNotificationEfolderSyncJob" } } - let(:legacy_notification_job_body) { { "job_class" => "LegacyNotificationEfolderSyncJob" } } - let(:warm_bgs_cache_job_body) { { "job_class" => "WarmBgsCachesJob" } } - let(:caseflow_job_body) { { "job_class" => "CaseflowJob" } } - let(:subject) { JobMessageDeletionMiddleware.new } - - it "deletes SQS message for QuarterlyNotificationsJob" do - expect(sqs).to receive(:delete_message).with(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - test_yield_statement = subject.call(nil, nil, msg, quarterly_notification_job_body) { "Executes middleware block" } - expect(test_yield_statement).to eql("Executes middleware block") - end - - it "deletes SQS message for AmaNotificationEfolderSyncJob" do - expect(sqs).to receive(:delete_message).with(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - test_yield_statement = subject.call(nil, nil, msg, ama_notification_job_body) { "Executes middleware block" } - expect(test_yield_statement).to eql("Executes middleware block") - end - - it "deletes SQS message for LegacyNotificationEfolderSyncJob" do - expect(sqs).to receive(:delete_message).with(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - test_yield_statement = subject.call(nil, nil, msg, legacy_notification_job_body) { "Executes middleware block" } - expect(test_yield_statement).to eql("Executes middleware block") - end - - it "deletes SQS message for WarmBgsCacheJob" do - expect(sqs).to receive(:delete_message).with(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - test_yield_statement = subject.call(nil, nil, msg, warm_bgs_cache_job_body) { "Executes middleware block" } - expect(test_yield_statement).to eql("Executes middleware block") - end - - it "does not delete SQS message for all jobs" do - expect(sqs).not_to receive(:delete_message).with(queue_url: msg.queue_url, receipt_handle: msg.data.receipt_handle) - test_yield_statement = subject.call(nil, nil, msg, caseflow_job_body) { "Executes middleware block" } - expect(test_yield_statement).to eql("Executes middleware block") - end -end diff --git a/spec/jobs/nightly_syncs_job_spec.rb b/spec/jobs/nightly_syncs_job_spec.rb index 700c5672e5b..0422aad1ac9 100644 --- a/spec/jobs/nightly_syncs_job_spec.rb +++ b/spec/jobs/nightly_syncs_job_spec.rb @@ -156,61 +156,6 @@ class FakeTask < Dispatch::Task expect(BgsAttorney.count).to eq 5 end end - - context "#sync_hearing_states" do - let(:pending_hearing_appeal_state) do - create_appeal_state_with_case_record_and_hearing(nil) - end - - let(:postponed_hearing_appeal_state) do - create_appeal_state_with_case_record_and_hearing("P") - end - - let(:withdrawn_hearing_appeal_state) do - create_appeal_state_with_case_record_and_hearing("C") - end - - let(:scheduled_in_error_hearing_appeal_state) do - create_appeal_state_with_case_record_and_hearing("E") - end - - let(:held_hearing_appeal_state) do - create_appeal_state_with_case_record_and_hearing("H") - end - - it "Job synchronizes hearing statuses" do - expect([pending_hearing_appeal_state, - postponed_hearing_appeal_state, - withdrawn_hearing_appeal_state, - scheduled_in_error_hearing_appeal_state, - held_hearing_appeal_state].all?(&:hearing_scheduled)).to eq true - - subject - - expect(pending_hearing_appeal_state.hearing_scheduled).to eq true - - expect(postponed_hearing_appeal_state.reload.hearing_scheduled).to eq false - expect(postponed_hearing_appeal_state.hearing_postponed).to eq true - - expect(withdrawn_hearing_appeal_state.reload.hearing_scheduled).to eq false - expect(withdrawn_hearing_appeal_state.hearing_withdrawn).to eq true - - expect(scheduled_in_error_hearing_appeal_state.reload.hearing_scheduled).to eq false - expect(scheduled_in_error_hearing_appeal_state.scheduled_in_error).to eq true - - expect(held_hearing_appeal_state.reload.hearing_scheduled).to eq false - end - - # Hearing scheduled will be set to true to simulate Caseflow missing a - # disposition update. - def create_appeal_state_with_case_record_and_hearing(desired_disposition) - case_hearing = create(:case_hearing, hearing_disp: desired_disposition) - vacols_case = create(:case, case_hearings: [case_hearing]) - appeal = create(:legacy_appeal, vacols_case: vacols_case) - - appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } - end - end end context "when errors occur" do diff --git a/spec/jobs/notification_initialization_job_spec.rb b/spec/jobs/notification_initialization_job_spec.rb deleted file mode 100644 index 3b86fb7e74d..00000000000 --- a/spec/jobs/notification_initialization_job_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -describe NotificationInitializationJob, type: :job do - include ActiveJob::TestHelper - - before { Seeds::NotificationEvents.new.seed! } - - let(:user) { create(:user) } - - subject do - NotificationInitializationJob.perform_now( - appeal_id: appeal_state.appeal_id, - appeal_type: appeal_state.appeal_type, - template_name: Constants.EVENT_TYPE_FILTERS.appeal_docketed, - appeal_status: nil - ) - end - - context "When an appeal does not exist for an appeal state" do - let(:appeal_state) do - create( - :appeal_state, - appeal_id: 99_999, - appeal_type: "Appeal", - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - it "An AppealNotError exception is raised" do - expect_any_instance_of(NotificationInitializationJob).to receive(:log_error).with( - instance_of(Caseflow::Error::AppealNotFound) - ) - - subject - end - end - - context "When an appeal exists for an appeal state" do - context "The appeal is an AMA appeal" do - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - it "enqueues an SendNotificationJob" do - expect { subject }.to have_enqueued_job(SendNotificationJob) - end - end - - context "The appeal is a legacy appeal" do - before { FeatureToggle.enable!(:appeal_docketed_event) } - after { FeatureToggle.disable!(:appeal_docketed_event) } - - let(:appeal_state) do - create( - :appeal_state, - :legacy, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - it "enqueues an SendNotificationJob" do - expect { subject }.to have_enqueued_job(SendNotificationJob) - end - end - end -end diff --git a/spec/jobs/poll_docketed_legacy_appeals_job_spec.rb b/spec/jobs/poll_docketed_legacy_appeals_job_spec.rb index ba8bd65667a..bb6ffc006a4 100644 --- a/spec/jobs/poll_docketed_legacy_appeals_job_spec.rb +++ b/spec/jobs/poll_docketed_legacy_appeals_job_spec.rb @@ -39,7 +39,7 @@ appeals_id: "12342", appeals_type: "LegacyAppeal", event_date: today, - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", notification_type: "Email", notified_at: today) } @@ -71,13 +71,6 @@ expect(PollDocketedLegacyAppealsJob.new.most_recent_docketed_appeals(query)).to eq(recent_docketed_appeal_ids) end - it "should create AppealState records if they do not exist" do - expect(AppealState.where(appeal_id: recent_docketed_appeal_ids)[0]).to be(nil) - appeal_state_count_before = AppealState.count - PollDocketedLegacyAppealsJob.new.create_corresponding_appeal_states(recent_docketed_appeal_ids) - expect(AppealState.count).not_to eq(appeal_state_count_before) - end - it "should filter for all legacy appeals that havent already gotten a notification yet" do expect(PollDocketedLegacyAppealsJob.perform_now).to eq(filtered_docketed_appeal_ids) end diff --git a/spec/jobs/process_notification_status_updates_job_spec.rb b/spec/jobs/process_notification_status_updates_job_spec.rb index a5f94379961..58592c4eaa3 100644 --- a/spec/jobs/process_notification_status_updates_job_spec.rb +++ b/spec/jobs/process_notification_status_updates_job_spec.rb @@ -19,7 +19,7 @@ create(:notification, appeals_id: appeal.uuid, appeals_type: "Appeal", event_date: 6.days.ago, - event_type: Constants.EVENT_TYPE_FILTERS.quarterly_notification, + event_type: "Quarterly Notification", notification_type: "Email", email_notification_external_id: SecureRandom.uuid) end @@ -27,7 +27,7 @@ create(:notification, appeals_id: appeal.uuid, appeals_type: "Appeal", event_date: 6.days.ago, - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", sms_notification_external_id: SecureRandom.uuid, notification_type: "SMS") end 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 ef91a80674a..ba5fb2b658e 100644 --- a/spec/jobs/push_priority_appeals_to_judges_job_spec.rb +++ b/spec/jobs/push_priority_appeals_to_judges_job_spec.rb @@ -42,12 +42,6 @@ def to_judge_hash(arr) subject end - - it "queues the UpdateAppealAffinityDatesJob" do - expect_any_instance_of(UpdateAppealAffinityDatesJob).to receive(:perform).with(no_args) - - subject - end end context ".distribute_non_genpop_priority_appeals" do @@ -81,7 +75,6 @@ def to_judge_hash(arr) :appeal, :ready_for_distribution, :advanced_on_docket_due_to_age, - :with_appeal_affinity, uuid: ready_priority_uuid, docket_type: Constants.AMA_DOCKETS.hearing ) @@ -114,7 +107,6 @@ def to_judge_hash(arr) appeal = create( :appeal, :ready_for_distribution, - :with_appeal_affinity, docket_type: Constants.AMA_DOCKETS.hearing ) most_recent = create(:hearing_day, scheduled_for: 1.day.ago) @@ -181,8 +173,7 @@ def to_judge_hash(arr) :appeal, :ready_for_distribution, :advanced_on_docket_due_to_age, - :with_appeal_affinity, - uuid: ready_priority_uuid2, + uuid: "bece6907-3b6f-4c49-a580-6d5f2e1ca65d", docket_type: Constants.AMA_DOCKETS.hearing ) most_recent = create(:hearing_day, scheduled_for: 1.day.ago) @@ -312,9 +303,8 @@ def to_judge_hash(arr) appeal = create(:appeal, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity, - affinity_start_date: i.months.ago, docket_type: Constants.AMA_DOCKETS.hearing) + appeal.tasks.find_by(type: DistributionTask.name).update(assigned_at: i.months.ago) appeal.reload end end @@ -323,9 +313,8 @@ def to_judge_hash(arr) appeal = create(:appeal, :type_cavc_remand, :cavc_ready_for_distribution, - :with_appeal_affinity, - affinity_start_date: i.months.ago, docket_type: Constants.AMA_DOCKETS.evidence_submission) + appeal.tasks.find_by(type: DistributionTask.name).update(assigned_at: i.month.ago) appeal end end diff --git a/spec/jobs/quarterly_notifications_job_spec.rb b/spec/jobs/quarterly_notifications_job_spec.rb index f7ba2c0a12b..4675e128f82 100644 --- a/spec/jobs/quarterly_notifications_job_spec.rb +++ b/spec/jobs/quarterly_notifications_job_spec.rb @@ -8,6 +8,24 @@ let(:user) { create(:user) } subject { QuarterlyNotificationsJob.perform_now } describe "#perform" do + context "appeal is nil" do + let!(:appeal_state) do + create( + :appeal_state, + appeal_id: 2, + appeal_type: "Appeal", + created_by_id: user.id, + updated_by_id: user.id + ) + end + it "does not push a new message" do + expect { subject }.not_to have_enqueued_job(SendNotificationJob) + end + it "rescues and logs error" do + expect(Rails.logger).to receive(:error) + subject + end + end context "Appeal Decision Mailed" do let!(:appeal_state) do create( @@ -19,21 +37,16 @@ decision_mailed: true ) end - it "does not push a new message" do - expect_message_to_not_be_enqueued - - subject + expect { subject }.not_to have_enqueued_job(SendNotificationJob) end end - context "job setup" do it "sets the current user for BGS calls" do subject expect(RequestStore[:current_user]).to eq(User.system_user) end end - context "Appeal Docketed" do let!(:appeal_state) do create( @@ -45,14 +58,11 @@ appeal_docketed: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Appeal Docketed with withdrawn hearing" do let!(:appeal_state) do create( @@ -65,14 +75,11 @@ hearing_withdrawn: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing to be Rescheduled / Privacy Act Pending for hearing postponed" do let!(:appeal_state) do create( @@ -86,14 +93,11 @@ privacy_act_pending: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing to be Rescheduled for hearing postponed" do let!(:appeal_state) do create( @@ -106,14 +110,11 @@ hearing_postponed: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing to be Rescheduled / Privacy Act Pending for scheduled in error" do let!(:appeal_state) do create( @@ -127,14 +128,11 @@ scheduled_in_error: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing to be Rescheduled for scheduled in error" do let!(:appeal_state) do create( @@ -147,34 +145,30 @@ scheduled_in_error: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing Scheduled / Privacy Act Pending with ihp task" do - let(:hearing) { create(:hearing, :with_tasks) } let!(:appeal_state) do - hearing.appeal.appeal_state.tap do - _1.update!( - appeal_docketed: true, - hearing_scheduled: true, - privacy_act_pending: true, - vso_ihp_pending: true - ) - end + create( + :appeal_state, + appeal_id: appeal.id, + appeal_type: "Appeal", + created_by_id: user.id, + updated_by_id: user.id, + appeal_docketed: true, + hearing_scheduled: true, + privacy_act_pending: true, + vso_ihp_pending: true + ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "VSO IHP Pending / Privacy Act Pending" do let!(:appeal_state) do create( @@ -188,52 +182,47 @@ vso_ihp_pending: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing Scheduled with ihp task pending" do - let(:hearing) { create(:hearing, :with_tasks) } let!(:appeal_state) do - hearing.appeal.appeal_state.tap do - _1.update!( - appeal_docketed: true, - hearing_scheduled: true, - vso_ihp_pending: true - ) - end + create( + :appeal_state, + appeal_id: appeal.id, + appeal_type: "Appeal", + created_by_id: user.id, + updated_by_id: user.id, + appeal_docketed: true, + hearing_scheduled: true, + vso_ihp_pending: true + ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing Scheduled / Privacy Act Pending" do - let(:hearing) { create(:hearing, :with_tasks) } let!(:appeal_state) do - hearing.appeal.appeal_state.tap do - _1.update!( - appeal_docketed: true, - hearing_scheduled: true, - privacy_act_pending: true - ) - end + create( + :appeal_state, + appeal_id: appeal.id, + appeal_type: "Appeal", + created_by_id: user.id, + updated_by_id: user.id, + appeal_docketed: true, + hearing_scheduled: true, + privacy_act_pending: true + ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Privacy Act Pending" do let!(:appeal_state) do create( @@ -246,14 +235,11 @@ privacy_act_pending: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "VSO IHP Pending" do let!(:appeal_state) do create( @@ -266,32 +252,28 @@ vso_ihp_pending: true ) end - it "pushes a new message" do - expect_message_to_be_queued - subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "Hearing Scheduled" do - let(:legacy_hearing) { create(:legacy_hearing) } let!(:appeal_state) do - legacy_hearing.appeal.appeal_state.tap do - _1.update!( - appeal_docketed: true, - hearing_scheduled: true - ) - end - - it "pushes a new message" do - expect_message_to_be_queued - - subject - end + create( + :appeal_state, + appeal_id: legacy_appeal.id, + appeal_type: "LegacyAppeal", + created_by_id: user.id, + updated_by_id: user.id, + appeal_docketed: true, + hearing_scheduled: true + ) + end + it "pushes a new message" do + subject + expect(SendNotificationJob).to have_been_enqueued.exactly(:once) end end - context "cancelled appeal" do let!(:appeal_state) do create( @@ -303,13 +285,11 @@ appeal_cancelled: true ) end - it "does not push a new message" do subject expect { subject }.not_to have_enqueued_job(SendNotificationJob) end end - context "decision mailed" do let!(:appeal_state) do create( @@ -322,25 +302,9 @@ ) end it "does not push a new message" do - expect_message_to_not_be_enqueued - subject + expect { subject }.not_to have_enqueued_job(SendNotificationJob) end end end - - def expect_message_to_be_queued - expect_any_instance_of(QuarterlyNotificationsJob) - .to receive(:enqueue_init_jobs) - .with( - array_including( - instance_of(NotificationInitializationJob) - ) - ) - end - - def expect_message_to_not_be_enqueued - expect_any_instance_of(QuarterlyNotificationsJob) - .to_not receive(:enqueue_init_jobs) - end end diff --git a/spec/jobs/send_notification_job_spec.rb b/spec/jobs/send_notification_job_spec.rb index 32ebb4b8296..9ad5ffb21de 100644 --- a/spec/jobs/send_notification_job_spec.rb +++ b/spec/jobs/send_notification_job_spec.rb @@ -7,19 +7,17 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, - notification_type: "Email", - notifiable: appeal) + notification_type: "Email") end let(:legacy_appeal_notification) do create(:notification, appeals_id: "123456", appeals_type: "LegacyAppeal", - event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed, + event_type: "Appeal docketed", event_date: Time.zone.today, - notification_type: "Email and SMS", - notifiable: appeal) + notification_type: "SMS") end let(:appeal) do create(:appeal, @@ -28,7 +26,6 @@ homelessness: false, veteran_file_number: "123456789") end - let(:legacy_appeal) { create(:legacy_appeal) } let!(:no_name_appeal) do create(:appeal, docket_type: "Appeal", @@ -43,33 +40,24 @@ last_name: nil) end # rubocop:disable Style/BlockDelimiters - let(:good_template_name) { Constants.EVENT_TYPE_FILTERS.appeal_docketed } + let(:good_template_name) { "Appeal docketed" } let(:error_template_name) { "No Participant Id Found" } - let(:deceased_status) { "Failure Due to Deceased" } let(:success_status) { "Success" } let(:error_status) { "No participant_id" } let(:success_message_attributes) { { participant_id: "123456789", status: success_status, - appeal_id: appeal.external_id, - appeal_type: appeal.class.name + appeal_id: "5d70058f-8641-4155-bae8-5af4b61b1576", + appeal_type: "Appeal" } } let(:success_legacy_message_attributes) { { participant_id: "123456789", status: success_status, - appeal_id: legacy_appeal.external_id, - appeal_type: legacy_appeal.class.name - } - } - let(:deceased_legacy_message_attributes) { - { - participant_id: "123456789", - status: deceased_status, - appeal_id: target_appeal.external_id, - appeal_type: target_appeal.class.name + appeal_id: "123456", + appeal_type: "LegacyAppeal" } } let(:no_name_message_attributes) { @@ -77,23 +65,15 @@ participant_id: "246813579", status: success_status, appeal_id: no_name_appeal.uuid, - appeal_type: appeal.class.name + appeal_type: "Appeal" } } let(:error_message_attributes) { { participant_id: nil, status: error_status, - appeal_id: appeal.external_id, - appeal_type: appeal.class.name - } - } - let(:deceased_message_attributes) { - { - participant_id: "123456789", - status: deceased_status, - appeal_id: target_appeal.external_id, - appeal_type: target_appeal.class.name + appeal_id: "5d70058f-8641-4155-bae8-5af4b61b1578", + appeal_type: "Appeal" } } let(:fail_create_message_attributes) { @@ -106,17 +86,10 @@ } let(:good_message) { VANotifySendMessageTemplate.new(success_message_attributes, good_template_name) } let(:legacy_message) { VANotifySendMessageTemplate.new(success_legacy_message_attributes, good_template_name) } - let(:legacy_deceased_message) do - AppellantNotification.create_payload(target_appeal, good_template_name).to_json - end let(:no_name_message) { VANotifySendMessageTemplate.new(no_name_message_attributes, good_template_name) } let(:bad_message) { VANotifySendMessageTemplate.new(error_message_attributes, error_template_name) } - let(:deceased_message) { VANotifySendMessageTemplate.new(deceased_message_attributes, good_template_name).to_json } let(:fail_create_message) { VANotifySendMessageTemplate.new(fail_create_message_attributes, error_template_name) } - let(:quarterly_message) { - VANotifySendMessageTemplate.new(success_message_attributes, - Constants.EVENT_TYPE_FILTERS.quarterly_notification) - } + let(:quarterly_message) { VANotifySendMessageTemplate.new(success_message_attributes, "Quarterly Notification") } let(:participant_id) { success_message_attributes[:participant_id] } let(:no_name_participant_id) { no_name_message_attributes[:participant_id] } let(:bad_participant_id) { "123" } @@ -153,17 +126,9 @@ ) ) } - let(:notification_events_id) { Constants.EVENT_TYPE_FILTERS.vso_ihp_complete } - let(:notification_type) { Constants.EVENT_TYPE_FILTERS.vso_ihp_complete } + let(:notification_events_id) { "VSO IHP complete" } + let(:notification_type) { "VSO IHP complete" } let(:queue_name) { "caseflow_test_send_notifications" } - let(:appeal_to_notify_about) { create(:appeal, :with_deceased_veteran) } - let(:cob_user) do - create(:user).tap do |new_user| - OrganizationsUser.make_user_admin(new_user, ClerkOfTheBoard.singleton) - end - end - - let(:substitution) { AppellantSubstitution.new(created_by_id: cob_user.id, source_appeal_id: appeal.id) } # rubocop:enable Style/BlockDelimiters before do @@ -175,20 +140,6 @@ clear_performed_jobs end - context "#queue_name_suffix" do - subject { described_class.queue_name_suffix } - - it "returns non-FIFO name in development environment" do - is_expected.to eq :send_notifications - end - - it "returns FIFO name in non-development environment" do - allow(ApplicationController).to receive(:dependencies_faked?).and_return(false) - - is_expected.to eq :"send_notifications.fifo" - end - end - it "it is the correct queue" do expect(SendNotificationJob.new.queue_name).to eq(queue_name) end @@ -210,7 +161,6 @@ end it "logs error when message is nil" do - expect(Rails.logger).to receive(:send).with(:error, /Message argument of value nil supplied to job/) perform_enqueued_jobs do expect_any_instance_of(SendNotificationJob).to receive(:log_error) do |_recipient, error_received| expect(error_received.message).to eq "There was no message passed into the " \ @@ -222,7 +172,6 @@ end it "logs error when appeals_id, appeals_type, or event_type is nil" do - expect(Rails.logger).to receive(:send).with(:error, /Nil message attribute\(s\): appeal_type/) perform_enqueued_jobs do expect_any_instance_of(SendNotificationJob).to receive(:log_error) do |_recipient, error_received| expect(error_received.message).to eq "appeals_id or appeal_type or event_type was nil " \ @@ -234,10 +183,8 @@ end it "logs error when audit record is nil" do - allow_any_instance_of(Notification).to receive(:nil?).and_return(true) + allow_any_instance_of(SendNotificationJob).to receive(:create_notification_audit_record).and_return(nil) - expect(Rails.logger).to receive(:send) - .with(:error, /Notification audit record was unable to be found or created/) perform_enqueued_jobs do expect_any_instance_of(SendNotificationJob).to receive(:log_error) do |_recipient, error_received| expect(error_received.message).to eq "Audit record was unable to be found or created " \ @@ -248,17 +195,6 @@ end end - it "notification audit record is recreated when error is in DISCARD ERRORS" do - expect(Rails.logger).to receive(:send).with(:error, /Message argument of value nil supplied to job/) - perform_enqueued_jobs do - expect_any_instance_of(SendNotificationJob).to receive(:log_error) do |_recipient| - expect(SendNotificationJob).to receive(:find_or_create_notification_audit) - end - - SendNotificationJob.perform_later(nil) - end - end - it "sends to VA Notify when no errors are present" do expect(Rails.logger).not_to receive(:error) expect { SendNotificationJob.perform_now(good_message.to_json).to receive(:send_to_va_notify) } @@ -333,9 +269,10 @@ end end - describe "#create_notification" do + describe "#create_notification_audit_record" do it "makes a new notification object" do - expect { SendNotificationJob.perform_now(good_message.to_json) }.to change(Notification, :count).by(1) + expect(Notification).to receive(:new) + SendNotificationJob.perform_now(good_message.to_json) end end @@ -346,35 +283,45 @@ context "va_notify FeatureToggles" do describe "email" do it "is expected to send when the feature toggle is on" do + FeatureToggle.enable!(:va_notify_email) expect(VANotifyService).to receive(:send_email_notifications) SendNotificationJob.perform_now(good_message.to_json) end it "updates the notification_content field with content" do + FeatureToggle.enable!(:va_notify_email) SendNotificationJob.perform_now(good_message.to_json) expect(Notification.last.notification_content).not_to eq(nil) end it "updates the email_notification_content field with content" do + FeatureToggle.enable!(:va_notify_email) SendNotificationJob.perform_now(good_message.to_json) expect(Notification.last.email_notification_content).not_to eq(nil) end it "updates the notification_audit_record with email_notification_external_id" do + FeatureToggle.enable!(:va_notify_email) SendNotificationJob.perform_now(good_message.to_json) expect(Notification.last.email_notification_external_id).not_to eq(nil) end + it "is expected to not send when the feature toggle is off" do + FeatureToggle.disable!(:va_notify_email) + expect(VANotifyService).not_to receive(:send_email_notifications) + SendNotificationJob.perform_now(good_message.to_json) + end end describe "sms" do - before { FeatureToggle.enable!(:va_notify_sms) } - after { FeatureToggle.disable!(:va_notify_sms) } it "is expected to send when the feature toggle is on" do + FeatureToggle.enable!(:va_notify_sms) expect(VANotifyService).to receive(:send_sms_notifications) SendNotificationJob.perform_now(good_message.to_json) end it "updates the sms_notification_content field with content" do + FeatureToggle.enable!(:va_notify_sms) SendNotificationJob.perform_now(good_message.to_json) expect(Notification.last.sms_notification_content).not_to eq(nil) end it "updates the notification_audit_record with sms_notification_external_id" do + FeatureToggle.enable!(:va_notify_sms) SendNotificationJob.perform_now(good_message.to_json) expect(Notification.last.sms_notification_external_id).not_to eq(nil) end @@ -387,14 +334,22 @@ end context "appeal first name not found" do - let(:notification_event) { NotificationEvent.find_by(event_type: Constants.EVENT_TYPE_FILTERS.appeal_docketed) } + let(:notification_event) { NotificationEvent.find_by(event_type: "Appeal docketed") } describe "email" do before { FeatureToggle.enable!(:va_notify_email) } after { FeatureToggle.disable!(:va_notify_email) } it "is expected to send a generic saluation instead of a name" do - expect(VANotifyService).to receive(:send_email_notifications).with(hash_including(first_name: "Appellant")) + expect(VANotifyService).to receive(:send_email_notifications).with( + no_name_participant_id, + "", + notification_event.email_template_id, + "Appellant", + no_name_appeal.docket_number, + "" + ) + SendNotificationJob.perform_now(no_name_message.to_json) end end @@ -404,78 +359,106 @@ after { FeatureToggle.disable!(:va_notify_sms) } it "is expected to send a generic saluation instead of a name" do - expect(VANotifyService).to receive(:send_sms_notifications).with(hash_including(first_name: "Appellant")) + expect(VANotifyService).to receive(:send_sms_notifications).with( + no_name_participant_id, + "", + notification_event.sms_template_id, + "Appellant", + no_name_appeal.docket_number, + "" + ) + SendNotificationJob.perform_now(no_name_message.to_json) end end end context "on retry" do - before { FeatureToggle.enable!(:va_notify_email) } - after { FeatureToggle.disable!(:va_notify_email) } describe "notification object" do it "does not create multiple notification objects" do + FeatureToggle.enable!(:va_notify_email) job = SendNotificationJob.new(good_message.to_json) - allow(job).to receive(:find_or_create_notification_audit).and_return(notification) - expect { job.perform_now }.not_to change(Notification, :count) + job.instance_variable_set(:@notification_audit_record, notification) + expect(Notification).not_to receive(:create) + job.perform_now end end end context "feature flags for setting notification type" do it "notification type should be email if only email flag is on" do - FeatureToggle.enable!(:va_notify_email) job = SendNotificationJob.new(good_message.to_json) - job.instance_variable_set(:@message, JSON.parse(job.arguments[0], object_class: OpenStruct)) - record = job.send(:find_or_create_notification_audit) + job.instance_variable_set(:@va_notify_email, true) + record = job.send(:create_notification_audit_record, + notification.appeals_id, + notification.appeals_type, + notification.event_type, + "123456789") expect(record.notification_type).to eq("Email") - FeatureToggle.disable!(:va_notify_email) end it "notification type should be sms if only sms flag is on" do - FeatureToggle.enable!(:va_notify_sms) job = SendNotificationJob.new(good_message.to_json) - job.instance_variable_set(:@message, JSON.parse(job.arguments[0], object_class: OpenStruct)) - record = job.send(:find_or_create_notification_audit) - expect(record.notification_type).to eq("Email and SMS") - FeatureToggle.disable!(:va_notify_sms) + job.instance_variable_set(:@va_notify_sms, true) + record = job.send(:create_notification_audit_record, + notification.appeals_id, + notification.appeals_type, + notification.event_type, + "123456789") + expect(record.notification_type).to eq("SMS") end it "notification type should be email and sms if both of those flags are on" do - FeatureToggle.enable!(:va_notify_email) - FeatureToggle.enable!(:va_notify_sms) job = SendNotificationJob.new(good_message.to_json) - job.instance_variable_set(:@message, JSON.parse(job.arguments[0], object_class: OpenStruct)) - record = job.send(:find_or_create_notification_audit) + job.instance_variable_set(:@va_notify_email, true) + job.instance_variable_set(:@va_notify_sms, true) + record = job.send(:create_notification_audit_record, + notification.appeals_id, + notification.appeals_type, + notification.event_type, + "123456789") expect(record.notification_type).to eq("Email and SMS") - FeatureToggle.disable!(:va_notify_email) - FeatureToggle.disable!(:va_notify_sms) end end - context "feature flag testing for creating legacy appeal notification records" do - let(:legacy_appeal) { create(:legacy_appeal) } - let!(:case) { create(:case, bfkey: legacy_appeal.vacols_id) } + context "feature flags for sending legacy notifications" do + it "should only send notifications when feature flag is turned on" do + FeatureToggle.enable!(:appeal_docketed_notification) + job = SendNotificationJob.new(legacy_message.to_json) + job.instance_variable_set(:@notification_audit_record, notification) + expect(job).to receive(:send_to_va_notify) + job.perform_now + end - it "creates an instance of a notification" do - FeatureToggle.enable!(:appeal_docketed_event) + it "should not send notifications when feature flag is turned off" do + FeatureToggle.disable!(:appeal_docketed_notification) job = SendNotificationJob.new(legacy_message.to_json) - allow(job).to receive(:find_appeal_by_external_id).and_return(legacy_appeal) - expect(Notification).to receive(:create) + job.instance_variable_set(:@notification_audit_record, notification) + expect(job).not_to receive(:send_to_va_notify) job.perform_now - FeatureToggle.disable!(:appeal_docketed_event) end end - context "feature flag for quarterly notifications" do - before do - FeatureToggle.enable!(:va_notify_quarterly_sms) + context "feature flag testing for creating legacy appeal notification records" do + it "should only create an instance of a notification before saving if a notification was found" do + FeatureToggle.enable!(:appeal_docketed_event) + job = SendNotificationJob.new(legacy_message.to_json) + expect(Notification).to receive(:new) + job.perform_now end - after do - FeatureToggle.disable!(:va_notify_quarterly_sms) + it "should return the notification record if one is found and not try to create one" do + legacy_appeal_notification + FeatureToggle.enable!(:appeal_docketed_event) + FeatureToggle.enable!(:va_notify_sms) + job = SendNotificationJob.new(legacy_message.to_json) + job.instance_variable_set(:@va_notify_sms, true) + expect(Notification).not_to receive(:new) + job.perform_now end + end + context "feature flag for quarterly notifications" do it "should send an sms for quarterly notifications when the flag is on" do FeatureToggle.enable!(:va_notify_quarterly_sms) expect(VANotifyService).to receive(:send_sms_notifications) @@ -490,102 +473,16 @@ end context "no participant or claimant found" do - before do - FeatureToggle.enable!(:va_notify_email) - FeatureToggle.enable!(:va_notify_sms) - end - - after do - FeatureToggle.disable!(:va_notify_email) - FeatureToggle.disable!(:va_notify_sms) - end it "the email status should be updated to say no participant id if that is the message" do + FeatureToggle.enable!(:va_notify_email) SendNotificationJob.new(bad_message.to_json).perform_now expect(Notification.first.email_notification_status).to eq("No Participant Id Found") end it "the sms status should be updated to say no participant id if that is the message" do + FeatureToggle.enable!(:va_notify_sms) SendNotificationJob.new(bad_message.to_json).perform_now expect(Notification.first.sms_notification_status).to eq("No Participant Id Found") end end - - context "Deceased veteran checks" do - before do - FeatureToggle.enable!(:va_notify_email) - FeatureToggle.enable!(:va_notify_sms) - FeatureToggle.enable!(:appeal_docketed_notification) - end - after do - FeatureToggle.disable!(:va_notify_email) - FeatureToggle.disable!(:va_notify_sms) - FeatureToggle.disable!(:appeal_docketed_notification) - end - - context "Appeal is the subject of the notification" do - let!(:target_appeal) { create(:appeal, :with_deceased_veteran) } - - it "The veteran being the claimant and is alive" do - expect(VANotifyService).to receive(:send_email_notifications) - expect(VANotifyService).to receive(:send_sms_notifications) - - SendNotificationJob.new(good_message.to_json).perform_now - - expect(Notification.first.email_notification_status).to eq("Success") - end - - it "The veteran being the claimant and is deceased" do - expect(VANotifyService).to_not receive(:send_email_notifications) - expect(VANotifyService).to_not receive(:send_sms_notifications) - - SendNotificationJob.perform_now(deceased_message) - - expect(Notification.first.email_notification_status).to eq("Failure Due to Deceased") - end - - it "The veteran being deceased and there being an AppellantSubstitution on the appeal to swap the claimant" do - substitution - expect(VANotifyService).to_not receive(:send_email_notifications) - expect(VANotifyService).to_not receive(:send_sms_notifications) - - SendNotificationJob.new(deceased_message).perform_now - - expect(Notification.first.email_notification_status).to eq("Failure Due to Deceased") - end - end - - context "Legacy Appeal is the subject of the notification" do - let(:target_appeal) do - create( - :legacy_appeal, - :with_veteran, - vacols_case: create(:case_with_form_9) - ) - end - - it "The veteran being the claimant and is alive" do - job = SendNotificationJob.new(legacy_message.to_json) - job.instance_variable_set(:@notification_audit, notification) - allow(job).to receive(:find_appeal_by_external_id).and_return(target_appeal) - expect(job).to receive(:send_to_va_notify) - - job.perform_now - - expect(Notification.last.email_notification_status).to eq("Success") - end - - it "The veteran being the claimant and is deceased" do - target_appeal.veteran.update!(date_of_death: 2.weeks.ago) - - job = SendNotificationJob.new(legacy_deceased_message) - job.instance_variable_set(:@notification_audit, notification) - allow(job).to receive(:find_appeal_by_external_id).and_return(target_appeal) - expect(job).to_not receive(:send_to_va_notify) - - job.perform_now - - expect(Notification.last.email_notification_status).to eq("Failure Due to Deceased") - end - end - end end diff --git a/spec/jobs/start_distribution_job_spec.rb b/spec/jobs/start_distribution_job_spec.rb index 6c5dad1d967..c9291e4061c 100644 --- a/spec/jobs/start_distribution_job_spec.rb +++ b/spec/jobs/start_distribution_job_spec.rb @@ -7,9 +7,8 @@ context ".perform" do subject { StartDistributionJob.perform_now(distribution) } - it "calls distribute! and queues the UpdateAppealAffinityDatesJob" do + it "calls distribute!" do expect(distribution).to receive(:distribute!) - expect_any_instance_of(UpdateAppealAffinityDatesJob).to receive(:perform).with(distribution.id) subject end diff --git a/spec/jobs/update_appeal_affinity_dates_job_spec.rb b/spec/jobs/update_appeal_affinity_dates_job_spec.rb deleted file mode 100644 index 83201b15e92..00000000000 --- a/spec/jobs/update_appeal_affinity_dates_job_spec.rb +++ /dev/null @@ -1,366 +0,0 @@ -# frozen_string_literal: true - -describe UpdateAppealAffinityDatesJob do - context "#format_distributed_case_hash" do - let(:distributed_cases_hash_from_database) do - { ["evidence_submission", false] => Time.zone.now, - ["evidence_submission", true] => Time.zone.now, - ["direct_review", false] => Time.zone.now, - ["direct_review", true] => Time.zone.now, - ["hearing", false] => Time.zone.now, - ["hearing", true] => Time.zone.now } - end - - it "deletes the docket/priority pairs which will never need affinities" do - result = described_class.new.send(:format_distributed_case_hash, distributed_cases_hash_from_database) - dockets_in_result = result.map { |hash| hash[:docket] } - - expect(result.length).to eq 4 - expect(dockets_in_result).to match_array(%w[evidence_submission direct_review hearing hearing]) - end - end - - context "#latest_receipt_dates" do - before { create(:case_distribution_lever, :request_more_cases_minimum) } - - let(:judge) { create(:user, :judge, :with_vacols_judge_record) } - let(:distribution_requested) { create(:distribution, :completed, judge: judge) } - let(:distribution_requested_older) { create(:distribution, :completed, :this_month, judge: judge) } - let(:distribution_current_push) { create(:distribution, :completed, :priority, judge: judge) } - let(:distribution_old_push) { create(:distribution, :completed, :priority, :this_month, judge: judge) } - let(:appeal_requested) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 1.week.ago) - end - let(:appeal_requested_older) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 1.year.ago) - end - let(:appeal_current_push) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 2.weeks.ago) - end - let(:appeal_old_push) { create(:appeal, :hearing_docket, :assigned_to_judge, receipt_date: 1.month.ago) } - let!(:distributed_case_requested) do - create(:distributed_case, distribution: distribution_requested, appeal: appeal_requested) - end - let!(:distributed_case_requested_older) do - create(:distributed_case, distribution: distribution_requested_older, appeal: appeal_requested_older) - end - let!(:distributed_case_current_push) do - create(:distributed_case, distribution: distribution_current_push, appeal: appeal_current_push) - end - let!(:distributed_case_old_push) do - create(:distributed_case, distribution: distribution_old_push, appeal: appeal_old_push) - end - - context "from_distribution" do - it "does not use DistributeCases from any push job and gets most recent receipt date" do - job = described_class.new - job.instance_variable_set(:@distribution_id, distribution_requested.id) - result = job.send(:latest_receipt_dates_from_distribution) - - expect(result.length).to eq 1 - expect(result.first[:docket]).to eq appeal_requested.docket_type - expect(result.first[:receipt_date]).to eq appeal_requested.receipt_date - end - end - - context "from_push_job" do - it "only uses DistributedCases from the most recent push job" do - result = described_class.new.send(:latest_receipt_dates_from_push_job) - dockets = result.map { |hash| hash[:docket] } - - expect(result.length).to eq 1 - expect(dockets).to match_array([appeal_current_push.docket_type]) - end - end - end - - context "when there are no query results" do - it "#latest_receipt_dates_from_push_job does not error" do - result = described_class.new.send(:latest_receipt_dates_from_push_job) - expect(result).to eq [] - end - - it "#process_ama_appeals_which_need_affinity_updates doesn't error or call #create_or_update_appeal_affinities" do - expect_any_instance_of(described_class).to_not receive(:create_or_update_appeal_affinities) - result = described_class.new.send(:process_ama_appeals_which_need_affinity_updates, []) - expect(result).to eq [] - end - - it "#perform does not call #process_ama_appeals_which_need_affinity_updates" do - expect_any_instance_of(described_class).to_not receive(:process_ama_appeals_which_need_affinity_updates) - described_class.perform_now - end - end - - context "#process_ama_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_ama_appeals_which_need_affinity_updates, hashes_array) } - - it "doesn't process any legacy appeals" do - expect_any_instance_of(described_class).to receive(:create_or_update_appeal_affinities).exactly(2).times - subject - end - - context "for single docket/priority combinations" do - let!(:direct_review_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 1.day.ago) - end - let!(:direct_review_nonpriority) do - create(:appeal, :direct_review_docket, :ready_for_distribution, receipt_date: 1.day.ago) - end - let!(:evidence_submission_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_motion, :ready_for_distribution, - receipt_date: 1.day.ago) - end - let!(:evidence_submission_nonpriority) do - create(:appeal, :evidence_submission_docket, :ready_for_distribution, receipt_date: 1.day.ago) - end - let!(:hearing_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 1.day.ago) - end - let!(:hearing_nonpriority) do - create(:appeal, :hearing_docket, :ready_for_distribution, receipt_date: 1.day.ago) - end - - context "for direct review priority" do - let(:hashes_array) { [{ docket: "direct_review", priority: true, receipt_date: Time.zone.now }] } - - it "only queries for and passes along direct review priority appeals" do - expect_any_instance_of(described_class) - .to receive(:create_or_update_appeal_affinities) - .with([direct_review_priority], hashes_array.first[:priority]) - - subject - end - end - - context "for evidence submission priority" do - let(:hashes_array) { [{ docket: "evidence_submission", priority: true, receipt_date: Time.zone.now }] } - - it "only queries for and passes along evidence submission priority appeals" do - expect_any_instance_of(described_class) - .to receive(:create_or_update_appeal_affinities) - .with([evidence_submission_priority], hashes_array.first[:priority]) - - subject - end - end - - context "for hearing priority" do - let(:hashes_array) { [{ docket: "hearing", priority: true, receipt_date: Time.zone.now }] } - - it "only queries for and passes along hearing priority appeals" do - expect_any_instance_of(described_class) - .to receive(:create_or_update_appeal_affinities) - .with([hearing_priority], hashes_array.first[:priority]) - - subject - end - end - - context "for hearing nonpriority" do - let(:hashes_array) { [{ docket: "hearing", priority: false, receipt_date: Time.zone.now }] } - - it "only queries for and passes along hearing nonpriority appeals" do - expect_any_instance_of(described_class) - .to receive(:create_or_update_appeal_affinities) - .with([hearing_nonpriority], hashes_array.first[:priority]) - - subject - end - end - end - end - - context "#create_or_update_appeal_affinties" 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(:appeal) } - let(:appeal_with_appeal_affinity_no_start_date) { create(:appeal, :with_appeal_affinity_no_start_date) } - let(:job) { described_class.new } - - before { job.instance_variable_set(:@distribution_id, distribution.id) } - - it "updates existing affinity records if they exist" do - appeals = [appeal_with_appeal_affinity_no_start_date] - result = job.send(:create_or_update_appeal_affinities, appeals, false) - - expect(result.first.affinity_start_date).to_not be nil - expect(result.first.distribution_id).to eq distribution.id - end - - it "creates new affinity records if they don't exist" do - appeals = [appeal_no_appeal_affinity] - result = job.send(:create_or_update_appeal_affinities, appeals, false) - - expect(result.first.affinity_start_date).to_not be nil - expect(result.first.docket).to eq appeal_no_appeal_affinity.docket_type - expect(result.first.priority).to eq false - expect(result.first.distribution_id).to eq distribution.id - 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) - described_class.perform_now(1) - end - - it "updates from the most recent push job if provided no args" do - expect_any_instance_of(described_class).to receive(:update_from_push_priority_appeals_job).and_return(true) - described_class.perform_now - end - - it "sends a slack notification if the job errors" do - allow_any_instance_of(described_class) - .to receive(:update_from_push_priority_appeals_job).and_raise(StandardError) - - expect_any_instance_of(SlackService).to receive(:send_notification) - - described_class.perform_now - end - - context "full run" do - before { create(:case_distribution_lever, :request_more_cases_minimum) } - - let!(:judge) { create(:user, :judge, :with_vacols_judge_record) } - let!(:previous_distribution) { create(:distribution, :completed, :this_month, judge: judge) } - - # previously distributed appeals with distributed cases from each docket and priority combination - let!(:distributed_appeal_drd_priority) do - appeal = create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 2.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - let!(:distributed_appeal_drd_nonpriority) do - appeal = create(:appeal, :direct_review_docket, :assigned_to_judge, - receipt_date: 1.week.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - let!(:distributed_appeal_esd_priority) do - appeal = create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 3.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - let!(:distributed_appeal_esd_nonpriority) do - appeal = create(:appeal, :evidence_submission_docket, :assigned_to_judge, - receipt_date: 2.weeks.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - let!(:distributed_appeal_hrd_priority) do - appeal = create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 4.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - let!(:distributed_appeal_hrd_nonpriority) do - appeal = create(:appeal, :hearing_docket, :assigned_to_judge, - receipt_date: 3.weeks.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: previous_distribution) - appeal - end - - # ready appeals from each docket and priority combination without existing affinity records - let!(:ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 3.days.ago) - end - let!(:ready_appeal_drd_nonpriority) do - create(:appeal, :direct_review_docket, :ready_for_distribution, receipt_date: 2.weeks.ago) - end - let!(:ready_appeal_esd_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 4.days.ago) - end - let!(:ready_appeal_esd_nonpriority) do - create(:appeal, :evidence_submission_docket, :ready_for_distribution, receipt_date: 3.weeks.ago) - end - let!(:ready_appeal_hrd_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 5.days.ago) - end - let!(:ready_appeal_hrd_nonpriority) do - create(:appeal, :hearing_docket, :ready_for_distribution, receipt_date: 4.weeks.ago) - end - - # ready appeals from each docket and priority combination with existing affinity records but no start date - let!(:ready_appeal_drd_priority_no_start_date) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 3.days.ago) - end - let!(:ready_appeal_esd_priority_no_start_date) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 4.days.ago) - end - let!(:ready_appeal_hrd_priority_no_start_date) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 5.days.ago) - end - let!(:ready_appeal_hrd_nonpriority_no_start_date) do - create(:appeal, :hearing_docket, :ready_for_distribution, :with_appeal_affinity_no_start_date, - receipt_date: 4.weeks.ago) - end - - # ready appeals from each docket and priority combination which should not be selected - let!(:ready_appeal_drd_priority_not_selectable) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution) - end - let!(:ready_appeal_esd_priority_not_selectable) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution) - end - let!(:ready_appeal_hrd_priority_not_selectable) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution) - end - let!(:ready_appeal_hrd_nonpriority_not_selectable) do - create(:appeal, :hearing_docket, :ready_for_distribution) - end - - # non-ready appeals from each docket and priority combination - let!(:non_ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :with_post_intake_tasks) - end - let!(:non_ready_appeal_esd_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :with_post_intake_tasks) - end - let!(:non_ready_appeal_hrd_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :with_post_intake_tasks) - end - let!(:non_ready_appeal_hrd_nonpriority) do - create(:appeal, :hearing_docket, :with_post_intake_tasks) - 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 - - # Validate that only the expected appeals are the ones that were updated - expect(ready_appeal_drd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_esd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_hrd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_hrd_nonpriority.appeal_affinity).to_not be nil - expect(ready_appeal_drd_priority_no_start_date.appeal_affinity).to_not be nil - 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 - end - end - end -end diff --git a/spec/jobs/update_appellant_representation_job_spec.rb b/spec/jobs/update_appellant_representation_job_spec.rb index 77c899236d0..35219a6cb01 100644 --- a/spec/jobs/update_appellant_representation_job_spec.rb +++ b/spec/jobs/update_appellant_representation_job_spec.rb @@ -41,6 +41,14 @@ metric_name: "runtime", metric_value: anything ) + expect(MetricsService).to receive(:emit_gauge).with( + app_name: "queue_job", + attrs: { endpoint: "AppellantNotification.appeal_mapper", service: "queue_job" }, + metric_group: "service", + metric_name: "request_latency", + metric_value: anything + ).exactly(new_task_count).times + UpdateAppellantRepresentationJob.perform_now end @@ -72,6 +80,13 @@ end end end + + it "sends the correct number of messages to DataDog and not send a message to Slack" do + expect(MetricsService).to receive(:increment_counter).exactly(7).times + expect_any_instance_of(SlackService).to_not receive(:send_notification) + + UpdateAppellantRepresentationJob.perform_now + end end context "when individual appeals throw errors" do diff --git a/spec/jobs/va_notify_status_update_job_spec.rb b/spec/jobs/va_notify_status_update_job_spec.rb index 4c6f2c65842..c58d7546a2e 100644 --- a/spec/jobs/va_notify_status_update_job_spec.rb +++ b/spec/jobs/va_notify_status_update_job_spec.rb @@ -16,7 +16,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email", email_notification_status: "Success") @@ -25,7 +25,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "SMS", sms_notification_status: "Success") @@ -34,7 +34,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email and SMS", email_notification_status: "Success", @@ -44,7 +44,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email", email_notification_external_id: "0", @@ -54,7 +54,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "SMS", email_notification_external_id: nil, @@ -64,7 +64,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "SMS", email_notification_external_id: nil, @@ -74,7 +74,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email", email_notification_external_id: "1", @@ -84,7 +84,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email and SMS", email_notification_external_id: "2", @@ -95,7 +95,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1576", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email and SMS", email_notification_external_id: "3", @@ -106,7 +106,7 @@ create(:notification, appeals_id: "5d70058f-8641-4155-bae8-5af4b61b1577", appeals_type: "Appeal", - event_type: Constants.EVENT_TYPE_FILTERS.hearing_scheduled, + event_type: "Hearing scheduled", event_date: Time.zone.today, notification_type: "Email and SMS", email_notification_external_id: "4", diff --git a/spec/jobs/virtual_hearings/create_conference_job_spec.rb b/spec/jobs/virtual_hearings/create_conference_job_spec.rb index 343e4e07fa9..9828792b5b2 100644 --- a/spec/jobs/virtual_hearings/create_conference_job_spec.rb +++ b/spec/jobs/virtual_hearings/create_conference_job_spec.rb @@ -58,7 +58,7 @@ end end.to( have_performed_job(VirtualHearings::CreateConferenceJob) - .exactly(5) + .exactly(10) .times ) end @@ -170,7 +170,7 @@ end it "job goes back on queue and logs if error", :aggregate_failures do - expect(Rails.logger).to receive(:error).exactly(6).times + expect(Rails.logger).to receive(:error).exactly(11).times expect do perform_enqueued_jobs do @@ -178,7 +178,7 @@ end end.to( have_performed_job(VirtualHearings::CreateConferenceJob) - .exactly(5) + .exactly(10) .times ) diff --git a/spec/lib/tasks/affinity_start_date_spec.rb b/spec/lib/tasks/affinity_start_date_spec.rb deleted file mode 100644 index 2332a9a6a65..00000000000 --- a/spec/lib/tasks/affinity_start_date_spec.rb +++ /dev/null @@ -1,319 +0,0 @@ -# frozen_string_literal: true - -describe "affinity_start_date" do - include_context "rake" - - before { create(:case_distribution_lever, :request_more_cases_minimum) } - - let!(:judge) { create(:user, :judge, :with_vacols_judge_record) } - let!(:distribution) { create(:distribution, :completed, :this_month, judge: judge) } - let!(:old_distribution) { create(:distribution, :completed, :last_month, judge: judge) } - let(:output_match) { "" } - - subject do - Rake::Task["db:affinity_start_date"].reenable - Rake::Task["db:affinity_start_date"].invoke - end - - context "direct_review" do - # {most recent distributed appeals with distributed cases from direct review docket} - let!(:distributed_appeal_drd_priority) do - appeal = create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 2.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - # older distributed appeals with distributed cases from direct review docket - # which should not be selected - let!(:old_distributed_appeal_drd_priority) do - appeal = create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 5.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: old_distribution, created_at: 2.days.ago) - appeal - end - - # direct review appeals that should be selected - let!(:ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 3.days.ago) - end - let!(:ready_appeal_drd_priority_with_appeal_affinity) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity, affinity_start_date: 6.days.ago, receipt_date: 7.days.ago) - end - let!(:other_ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, - :ready_for_distribution, receipt_date: 2.weeks.ago) - end - let!(:ready_appeal_drd_priority_no_receipt) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, - :ready_for_distribution, receipt_date: 1.week.ago) - end - - # direct review appeals that should not be selected - let!(:non_ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :mail_blocking_distribution) - end - let!(:receipt_ready_appeal_drd_priority_not_selectable) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity, affinity_start_date: 1.day.ago, receipt_date: 1.day.ago) - end - - it "is successful and adds expected appeal affinity records or values" do - # Only 2 of the staged appeals should have an affinity - expect(AppealAffinity.count).to eq 2 - - expect { subject }.to output(output_match).to_stdout - - # Only 5 of the staged appeals should have an affinity - expect(AppealAffinity.count).to eq 5 - - # Validate that only the expected appeals are the ones that were updated - expect(ready_appeal_drd_priority.appeal_affinity).to_not be nil - expect(other_ready_appeal_drd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_drd_priority_with_appeal_affinity.appeal_affinity).to_not be nil - expect(ready_appeal_drd_priority.appeal_affinity.affinity_start_date).to_not be nil - expect(other_ready_appeal_drd_priority.appeal_affinity.affinity_start_date).to_not be nil - expect(ready_appeal_drd_priority_with_appeal_affinity.appeal_affinity.affinity_start_date).to_not be nil - expect(ready_appeal_drd_priority_no_receipt.appeal_affinity).to_not be nil - - expect(non_ready_appeal_drd_priority.appeal_affinity).to be nil - expect(receipt_ready_appeal_drd_priority_not_selectable.appeal_affinity.affinity_start_date.to_date) - .to eq(1.day.ago.to_date) - end - end - - context "evidence_submission" do - # {most recent distributed appeals with distributed cases from evidence submission docket} - let!(:distributed_appeal_esd_priority) do - appeal = create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 3.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - # older distributed appeals with distributed cases from evidence submission docket - # which appeals with same receipt date should not be selected - let!(:old_distributed_appeal_esd_priority) do - appeal = create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 8.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: old_distribution, created_at: 2.days.ago) - appeal - end - - # {select} - let!(:ready_appeal_esd_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 4.days.ago) - end - let!(:other_ready_appeal_esd_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, - :ready_for_distribution, receipt_date: 3.weeks.ago) - end - let!(:receipt_ready_appeal_esd_priority_not_selectable) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 8.days.ago) - end - let!(:ready_appeal_esd_priority_no_start_date) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 4.days.ago) - end - - # {not_select} - let!(:ready_appeal_esd_priority_not_selectable) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution) - end - let!(:non_ready_appeal_esd_priority) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :with_post_intake_tasks) - end - - it "is successful and adds expected appeal affinity records or values" do - expect(AppealAffinity.count).to eq 1 - - expect { subject }.to output(output_match).to_stdout - - # Only 8 of the staged appeals should have an affinity - expect(AppealAffinity.count).to eq 4 - - # Validate that only the expected appeals are the ones that were updated - expect(ready_appeal_esd_priority.appeal_affinity).to_not be nil - expect(other_ready_appeal_esd_priority.appeal_affinity).to_not be nil - expect(receipt_ready_appeal_esd_priority_not_selectable.appeal_affinity).to_not be nil - expect(ready_appeal_esd_priority_no_start_date.appeal_affinity).to_not be nil - - expect(ready_appeal_esd_priority_not_selectable.appeal_affinity).to be nil - expect(non_ready_appeal_esd_priority.appeal_affinity).to be nil - end - end - - context "hearing_request" do - # {most recent distributed appeals which should be used for appeal selection} - let!(:distributed_appeal_hrd_priority) do - appeal = create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 4.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - let!(:distributed_appeal_hrd_nonpriority) do - appeal = create(:appeal, :hearing_docket, :assigned_to_judge, - receipt_date: 3.weeks.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - # {old distributed appeals which should not be used} - let!(:old_distributed_appeal_hrd_priority) do - appeal = create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 10.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: old_distribution, created_at: 9.days.ago) - appeal - end - let!(:old_distributed_appeal_hrd_nonpriority) do - appeal = create(:appeal, :hearing_docket, :assigned_to_judge, - receipt_date: 11.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: old_distribution, created_at: 9.days.ago) - appeal - end - - # {select} - let!(:ready_appeal_hrd_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 5.days.ago) - end - let!(:ready_appeal_hrd_nonpriority) do - create(:appeal, :hearing_docket, :ready_for_distribution, receipt_date: 4.weeks.ago) - end - let!(:ready_appeal_hrd_priority_no_start_date) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 5.days.ago) - end - let!(:ready_appeal_hrd_nonpriority_no_start_date) do - create(:appeal, :hearing_docket, :ready_for_distribution, :with_appeal_affinity_no_start_date, - receipt_date: 4.weeks.ago) - end - let!(:ready_appeal_hrd_nonpriority_with_appeal_affinity) do - create(:appeal, :hearing_docket, :ready_for_distribution, :with_appeal_affinity, - affinity_start_date: 18.days.ago, receipt_date: 4.weeks.ago) - end - # {not select} - let!(:ready_appeal_hrd_priority_not_selectable) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution) - end - let!(:ready_appeal_hrd_nonpriority_not_selectable) do - create(:appeal, :hearing_docket, :ready_for_distribution) - end - let!(:receipt_ready_appeal_hrd_priority_not_selectable) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 2.days.ago) - end - let!(:receipt_ready_appeal_hrd_nonpriority_not_selectable) do - create(:appeal, :hearing_docket, :ready_for_distribution, receipt_date: 11.days.ago) - end - let!(:non_ready_appeal_hrd_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :with_post_intake_tasks) - end - let!(:non_ready_appeal_hrd_nonpriority) do - create(:appeal, :hearing_docket, :with_post_intake_tasks) - end - - it "is successful and adds expected appeal affinity records or values" do - # Only 8 of the staged appeals should have an affinity - expect(AppealAffinity.count).to eq 3 - - expect { subject }.to output(output_match).to_stdout - - expect(AppealAffinity.count).to eq 5 - - # Validate that only the expected appeals are the ones that were updated - expect(ready_appeal_hrd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_hrd_nonpriority.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(ready_appeal_hrd_nonpriority_with_appeal_affinity.appeal_affinity).to_not be nil - - expect(ready_appeal_hrd_priority_not_selectable.appeal_affinity).to be nil - expect(ready_appeal_hrd_nonpriority_not_selectable.appeal_affinity).to be nil - expect(receipt_ready_appeal_hrd_priority_not_selectable.appeal_affinity).to be nil - expect(receipt_ready_appeal_hrd_nonpriority_not_selectable.appeal_affinity).to be nil - expect(non_ready_appeal_hrd_priority.appeal_affinity).to be nil - expect(non_ready_appeal_hrd_nonpriority.appeal_affinity).to be nil - end - end - - context "when appeal affinity is nil" do - let!(:distributed_appeal_hrd_priority) do - appeal = create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 4.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - let!(:ready_appeal_hrd_priority) do - create(:appeal, :hearing_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 5.days.ago) - end - - it "successfully creates an appeal affinity with the correct type/priority" do - expect { subject }.to output(output_match).to_stdout - - expect(ready_appeal_hrd_priority.appeal_affinity).to_not be nil - expect(ready_appeal_hrd_priority.appeal_affinity.docket).to eq("hearing") - expect(ready_appeal_hrd_priority.appeal_affinity.priority).to be true - expect(ready_appeal_hrd_priority.appeal_affinity.affinity_start_date).to_not be nil - expect(ready_appeal_hrd_priority.appeal_affinity.affinity_start_date) - .to be_within(1.second).of Time.zone.now - end - end - - context "when appeal affinity has no affinity start date" do - let!(:distributed_appeal_esd_priority) do - appeal = create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 3.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - let!(:ready_appeal_esd_priority_no_start_date) do - create(:appeal, :evidence_submission_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity_no_start_date, receipt_date: 4.days.ago) - end - - it "successfully updates the appeal affinity with the correct type/priority" do - expect { subject }.to output(output_match).to_stdout - - expect(ready_appeal_esd_priority_no_start_date.appeal_affinity).to_not be nil - expect(ready_appeal_esd_priority_no_start_date.appeal_affinity.affinity_start_date).to_not be nil - expect(ready_appeal_esd_priority_no_start_date.appeal_affinity.affinity_start_date) - .to be_within(1.second).of Time.zone.now - end - end - - context "when appeal has no matching receipt date" do - let!(:distributed_appeal_drd_priority) do - appeal = create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :assigned_to_judge, - receipt_date: 5.days.ago, associated_judge: judge) - create(:distributed_case, appeal: appeal, distribution: distribution, created_at: 1.day.ago) - appeal - end - - let!(:ready_appeal_drd_priority) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - receipt_date: 3.days.ago) - end - - let!(:ready_appeal_drd_priority_with_appeal_affinity) do - create(:appeal, :direct_review_docket, :advanced_on_docket_due_to_age, :ready_for_distribution, - :with_appeal_affinity, affinity_start_date: 2.days.ago, receipt_date: 4.days.ago) - end - - it "does not update or create an appeal_affinity" do - expect { subject }.to output(output_match).to_stdout - - expect(ready_appeal_drd_priority.appeal_affinity).to be nil - expect(ready_appeal_drd_priority_with_appeal_affinity.appeal_affinity).to_not be nil - expect(ready_appeal_drd_priority_with_appeal_affinity.appeal_affinity.affinity_start_date.to_date) - .to eq(2.days.ago.to_date) - end - end -end diff --git a/spec/models/appeal_affinity_spec.rb b/spec/models/appeal_affinity_spec.rb deleted file mode 100644 index 80407887244..00000000000 --- a/spec/models/appeal_affinity_spec.rb +++ /dev/null @@ -1,151 +0,0 @@ -# frozen_string_literal: true - -describe AppealAffinity do - let!(:appeal_affinity) { create(:appeal_affinity, appeal: appeal) } - - context "#case" do - subject { appeal_affinity.case } - context "for an AMA appeal" do - let(:appeal) { create(:appeal) } - - it "returns the Appeal object" do - expect(subject.is_a?(Appeal)).to be true - end - end - - context "for a legacy appeal" do - let(:appeal) { create(:case) } - - it "returns the VACOLS::Case object" do - expect(subject.is_a?(VACOLS::Case)).to be true - end - end - end - - # It would make more sense to place these tests into their respective model spec files, but the appeal spec file is - # already thousands of lines long, so the functionality can be tested here since it is reliant on this model anyway - context "ActiveRecord associations return the AffinityAppeal object" do - subject { appeal.appeal_affinity.is_a?(AppealAffinity) } - context "for an AMA appeal" do - let(:appeal) { create(:appeal) } - it { should be true } - end - - context "for an legacy appeal" do - let(:appeal) { create(:case) } - it { should be true } - end - end - - context "after_save" do - let!(:appeal_affinity) { nil } - - it "updates distribution task instructions when created" do - appeal = create(:appeal, :direct_review_docket, :ready_for_distribution) - dist_task = appeal.tasks.find_by(type: DistributionTask.name) - expect(dist_task.instructions).to eq [] - - affinity = create(:appeal_affinity, appeal: appeal) - - dist_task.reload - expect(dist_task.instructions) - .to eq ["Affinity start date: #{affinity.affinity_start_date.to_date.strftime('%m/%d/%Y')}"] - end - - it "updates distribution task instructions when updated w/ new value" do - appeal = create(:appeal, :direct_review_docket, :ready_for_distribution_with_appeal_affinity, - affinity_start_date: 1.week.ago) - dist_task = appeal.tasks.find_by(type: DistributionTask.name) - original_affinity_date = appeal.appeal_affinity.affinity_start_date - - expect(dist_task.instructions) - .to eq ["Affinity start date: #{original_affinity_date.to_date.strftime('%m/%d/%Y')}"] - - appeal.appeal_affinity.update!(affinity_start_date: nil) - - dist_task.reload - expect(dist_task.instructions) - .to eq ["Affinity start date: #{original_affinity_date.to_date.strftime('%m/%d/%Y')}"] - - appeal.appeal_affinity.update!(affinity_start_date: Time.zone.now) - - appeal.reload - dist_task.reload - expect(dist_task.instructions).to match_array( - ["Affinity start date: #{original_affinity_date.to_date.strftime('%m/%d/%Y')}", - "Affinity start date: #{appeal.appeal_affinity.affinity_start_date.to_date.strftime('%m/%d/%Y')}"] - ) - end - end - - context "factory" do - before { Timecop.freeze } - after { Timecop.return } - - context "when passed a priority AMA appeal" do - let(:appeal) { create(:appeal, :advanced_on_docket_due_to_age) } - - it "correctly sets parameters" do - expect(appeal_affinity.case_id).to eq(appeal.uuid) - expect(appeal_affinity.case_type).to eq(appeal.class.name) - expect(appeal_affinity.docket).to eq(appeal.docket_type) - expect(appeal_affinity.priority).to eq(true) - expect(appeal_affinity.affinity_start_date.to_date).to eq(Time.zone.today) - end - end - - context "when passed a priority VACOLS::Case" do - let(:appeal) { create(:case, :type_cavc_remand) } - - it "correctly sets parameters" do - expect(appeal_affinity.case_id).to eq(appeal.bfkey) - expect(appeal_affinity.case_type).to eq(appeal.class.name) - expect(appeal_affinity.docket).to eq("legacy") - expect(appeal_affinity.priority).to eq(true) - expect(appeal_affinity.affinity_start_date.to_date).to eq(Time.zone.today) - end - end - - context "when passed a distribution" do - let(:appeal_affinity) do - # Creating the lever wasn't working in a before block, so create it here before referencing the distribution - create(:case_distribution_lever, :request_more_cases_minimum) - create(:appeal_affinity, distribution: distribution) - end - let(:distribution) { create(:distribution, judge: create(:user, :with_vacols_judge_record)) } - - it "correctly sets the distribution" do - expect(appeal_affinity.distribution_id).to eq(distribution.id) - end - end - - context "when passed an appeal with a distributed case record" do - # Override this from the top-level so that the DistributedCase is created first to test the factory correctly - let(:appeal_affinity) { nil } - let(:appeal) { create(:appeal) } - let(:distribution) { create(:distribution, judge: create(:user, :with_vacols_judge_record)) } - - before do - create(:case_distribution_lever, :request_more_cases_minimum) - DistributedCase.create!(distribution: distribution, task: create(:distribution_task, appeal: appeal), - priority: false, sct_appeal: false, case_id: appeal.uuid, docket: appeal.docket_type, - ready_at: Time.zone.now) - end - - it "correctly sets the appeal affinity distribution" do - appeal_affinity = create(:appeal_affinity, appeal: appeal) - expect(appeal_affinity.distribution_id).to eq(distribution.id) - end - end - - context "when created as a trait using the Appeal factory" do - let(:appeal_affinity) { nil } - let(:appeal_with_affinity) { create(:appeal, :ready_for_distribution_with_appeal_affinity) } - - it "is ready to distribute with a set affinity start date" do - expect(appeal_with_affinity.appeal_affinity).not_to be nil - expect(appeal_with_affinity.ready_for_distribution?).to be true - end - end - end -end diff --git a/spec/models/appeal_spec.rb b/spec/models/appeal_spec.rb index 26bbd09cceb..148c4ab68bc 100644 --- a/spec/models/appeal_spec.rb +++ b/spec/models/appeal_spec.rb @@ -2126,10 +2126,6 @@ end context "when an appeal has with cavc remand" do - # The Appeal factory will set this to system_user if not already set and the checks after duplicating require the - # original appeal creator to be "regular_user" because it is being passed into the finalize_split_appeal method - before { RequestStore[:current_user] = regular_user } - it "should duplicate the appeals and with cavc remand for the same veteran" do original_appeal = create( :appeal, :type_cavc_remand, diff --git a/spec/models/appeal_state_spec.rb b/spec/models/appeal_state_spec.rb index 3684e193fcb..e9d85d775dc 100644 --- a/spec/models/appeal_state_spec.rb +++ b/spec/models/appeal_state_spec.rb @@ -2,681 +2,6 @@ describe AppealState do it_behaves_like "AppealState belongs_to polymorphic appeal" do - let!(:user) { create(:user) } # A User needs to exist for `appeal_state` factories - end - - let!(:user) { create(:user) } - - context "State scopes" do - let!(:appeal_docketed_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - let!(:hearing_withdrawn_docketed_appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_withdrawn: true, - appeal_docketed: true - ) - end - - let!(:privacy_pending_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_withdrawn: false, - vso_ihp_pending: false, - privacy_act_pending: true - ) - end - - let!(:ihp_pending_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_withdrawn: false, - vso_ihp_pending: true, - privacy_act_pending: false - ) - end - - let!(:ihp_pending_privacy_pending_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_withdrawn: false, - vso_ihp_pending: true, - privacy_act_pending: true - ) - end - - let!(:hearing_to_be_rescheduled_postponed_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_postponed: true - ) - end - - let!(:hearing_to_be_rescheduled_scheduled_in_error_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - scheduled_in_error: true - ) - end - - let!(:hearing_to_be_rescheduled_privacy_pending_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_postponed: true, - privacy_act_pending: true - ) - end - - let!(:appeal_decided_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - decision_mailed: true - ) - end - - let!(:appeal_cancelled_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_cancelled: true - ) - end - - shared_context "staged hearing task tree" do - let(:appeal) { create(:appeal, :active) } - let(:distribution_task) { DistributionTask.create!(appeal: appeal, parent: appeal.root_task) } - let(:hearing_task) { HearingTask.create!(appeal: appeal, parent: distribution_task) } - let!(:assign_disp_task) do - AssignHearingDispositionTask.create!(appeal: appeal, parent: hearing_task, assigned_to: Bva.singleton) - end - end - - shared_context "vacols case with case hearing" do - let(:case_hearing) { create(:case_hearing) } - let(:vacols_case) { create(:case, case_hearings: [case_hearing]) } - let!(:legacy_appeal) { create(:legacy_appeal, vacols_case: vacols_case) } - end - - context "#eligible_for_quarterly" do - subject { described_class.eligible_for_quarterly.pluck(:id) } - - it "Decided and cancelled appeals are excluded" do - is_expected.to_not contain_exactly( - appeal_decided_state.id, appeal_cancelled_state.id - ) - end - end - - context "#appeal_docketed" do - subject { described_class.appeal_docketed.pluck(:id) } - - it "Only appeals in docketed state are included" do - is_expected.to match_array( - [appeal_docketed_state.id, hearing_withdrawn_docketed_appeal_state.id] - ) - end - end - - context "#hearing_scheduled" do - subject { described_class.hearing_scheduled.pluck(:id) } - - context "ama" do - subject do - AppealState.find_by_appeal_id(appeal.id).update!(hearing_scheduled: true) - - described_class.hearing_scheduled.pluck(:id) - end - - let!(:appeal_state) { appeal.appeal_state } - - context "Whenever the expected task is absent" do - let(:appeal) { create(:appeal, :active) } - - it "The appeal state isn't retrieved by the query" do - is_expected.to be_empty - end - end - - context "Whenever the hearing has been held and the evidence submission window is open" do - include_context "staged hearing task tree" - - let!(:evidence_task) do - EvidenceSubmissionWindowTask.create!( - appeal: appeal, - parent: assign_disp_task, - assigned_to: MailTeam.singleton - ) - end - - it "The appeal state isn't retrieved by the query" do - is_expected.to be_empty - end - end - - context "Whenever the hearing has not been held" do - include_context "staged hearing task tree" - - it "The appeal state is returned" do - is_expected.to match_array([appeal_state.id]) - end - end - end - - context "legacy" do - include_context "vacols case with case hearing" - - let!(:appeal_state) { legacy_appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } } - - context "hearing has not been held" do - it "the appeal state is returned" do - is_expected.to match_array([appeal_state.id]) - end - end - - context "hearing has been held" do - it "the appeal state is not returned" do - case_hearing.update!(hearing_disp: "H") - - is_expected.to be_empty - end - end - end - - context "ama and legacy" do - include_context "vacols case with case hearing" - include_context "staged hearing task tree" - - let!(:ama_state) { appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } } - let!(:legacy_state) { legacy_appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } } - - context "An AMA and legacy hearings are both pending" do - it "both appeal states are returned by the query" do - is_expected.to match_array([ama_state.id, legacy_state.id]) - end - end - - context "An AMA and legacy hearings have been held" do - let!(:evidence_task) do - EvidenceSubmissionWindowTask.create!( - parent: assign_disp_task, - appeal: appeal, - assigned_to: MailTeam.singleton - ) - end - - it "neither appeal states are returned by the query" do - case_hearing.update!(hearing_disp: "H") - - is_expected.to be_empty - end - end - - context "An AMA hearing is pending and the legacy hearing has been held" do - it "only the AMA appeal state is returned by the query" do - case_hearing.update!(hearing_disp: "H") - - is_expected.to match_array([ama_state.id]) - end - end - - context "A legacy hearing is pending and an AMA hearing has been held" do - let!(:evidence_task) do - EvidenceSubmissionWindowTask.create!( - assigned_to: MailTeam.singleton, - parent: assign_disp_task, - appeal: appeal - ) - end - - it "only the legacy appeal state is returned by the query" do - is_expected.to match_array([legacy_state.id]) - end - end - end - end - - context "#hearing_scheduled_privacy_pending" do - include_context "staged hearing task tree" - - subject { described_class.hearing_scheduled_privacy_pending.pluck(:id) } - - let!(:hearing_scheduled_privacy_pending_state) do - appeal.appeal_state.tap do - _1.update!(hearing_scheduled: true, - privacy_act_pending: true) - end - end - - it "Only appeals in hearing scheduled and privacy act state are included" do - is_expected.to match_array([hearing_scheduled_privacy_pending_state.id]) - end - end - - context "#hearing_to_be_rescheduled" do - subject { described_class.hearing_to_be_rescheduled.pluck(:id) } - - it "Only appeals in hearing to be rescheduled state are included" do - is_expected.to match_array( - [ - hearing_to_be_rescheduled_postponed_state.id, - hearing_to_be_rescheduled_scheduled_in_error_state.id - ] - ) - end - end - - context "#hearing_to_be_rescheduled_privacy_pending" do - subject { described_class.hearing_to_be_rescheduled_privacy_pending.pluck(:id) } - - it "Only appeals in hearing to be rescheduled and privacy act state are included" do - is_expected.to match_array([hearing_to_be_rescheduled_privacy_pending_state.id]) - end - end - - context "#ihp_pending" do - subject { described_class.ihp_pending.pluck(:id) } - - it "Only appeals in VSO IHP pending state are included" do - is_expected.to match_array([ihp_pending_state.id]) - end - end - - context "#ihp_pending_privacy_pending" do - subject { described_class.ihp_pending_privacy_pending.pluck(:id) } - - it "Only appeals in VSO IHP Pending and privacy act state are included" do - is_expected.to match_array([ihp_pending_privacy_pending_state.id]) - end - end - - context "#privacy_pending" do - subject { described_class.privacy_pending.pluck(:id) } - - it "Only appeals in hearing to be rescheduled and privacy act state are included" do - is_expected.to match_array([privacy_pending_state.id]) - end - end - end - - shared_examples "privacy_act_pending status remains active upon update" do - before { appeal_state.update!(privacy_act_pending: true) } - - it "privacy_act_pending remains true" do - subject - - expect(appeal_state.privacy_act_pending).to eq true - end - end - - context "#appeal_docketed_appeal_state_update!" do - subject { appeal_state.appeal_docketed_appeal_state_update_action! } - - context "updates the appeal_docketed attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: false - ) - end - - it "sets appeal_docketed to true and all others false" do - subject - - expect(appeal_state.appeal_docketed).to eq true - end - end - end - - context "#vso_ihp_pending_appeal_state_update!" do - subject { appeal_state.vso_ihp_pending_appeal_state_update_action! } - - context "updates the vso_ihp_pending attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - it "sets vso_ihp_pending to true" do - subject - - expect(appeal_state.vso_ihp_pending).to eq true - end - end - end - - context "#vso_ihp_cancelled_appeal_state_update!" do - subject { appeal_state.vso_ihp_cancelled_appeal_state_update_action! } - - context "updates the vso_ihp_pending attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - vso_ihp_pending: true - ) - end - - it "sets vso_ihp_pending to false and all others false" do - subject - - expect(appeal_state.vso_ihp_pending).to eq false - end - end - end - - context "#vso_ihp_complete_appeal_state_update_action!" do - subject { appeal_state.vso_ihp_complete_appeal_state_update_action! } - - context "updates the vso_ihp_complete attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - vso_ihp_complete: true - ) - end - - it "sets vso_ihp_complete to true and all others false" do - subject - - expect(appeal_state.vso_ihp_complete).to eq true - end - end - end - - context "#privacy_act_pending_appeal_state_update!" do - subject { appeal_state.privacy_act_pending_appeal_state_update_action! } - - context "updates the privacy_act_pending attribute" do - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - privacy_act_pending: false - ) - end - - it "sets privacy_act_pending to true and all others false" do - subject - - expect(appeal_state.privacy_act_pending).to eq true - end - end - end - - context "#privacy_act_cancelled_appeal_state_update_action!" do - subject { appeal_state.privacy_act_cancelled_appeal_state_update_action! } - - context "updates the privacy_act_pending attribute" do - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - privacy_act_pending: true - ) - end - - it "sets privacy_act_cancelled to true and all others false" do - subject - - expect(appeal_state.privacy_act_pending).to eq false - end - end - end - - context "#privacy_act_complete_appeal_state_update_action!" do - subject { appeal_state.privacy_act_complete_appeal_state_update_action! } - - context "updates the privacy_act_complete attribute" do - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - privacy_act_pending: true, - hearing_scheduled: true - ) - end - - it "sets privacy_act_complete to true and leaves others intact" do - subject - - expect(appeal_state.privacy_act_pending).to eq false - expect(appeal_state.privacy_act_complete).to eq true - expect(appeal_state.hearing_scheduled).to eq true - end - end - end - - context "#decision_mailed_appeal_state_update_action!" do - subject { appeal_state.decision_mailed_appeal_state_update_action! } - - context "updates the decision_mailed attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - decision_mailed: false - ) - end - - it "sets decision_mailed to true and all others false" do - subject - - expect(appeal_state.decision_mailed).to eq true - end - end - end - - context "#appeal_cancelled_appeal_state_update_action!" do - subject { appeal_state.appeal_cancelled_appeal_state_update_action! } - - context "updates the appeal_cancelled attribute" do - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_scheduled: true, - privacy_act_complete: true - ) - end - - it "sets appeal_cancelled to true and all others false" do - subject - - expect(appeal_state.hearing_scheduled).to eq false - expect(appeal_state.privacy_act_complete).to eq false - expect(appeal_state.appeal_cancelled).to eq true - end - end - end - - context "#hearing_postponed_appeal_state_update!" do - subject { appeal_state.hearing_postponed_appeal_state_update_action! } - - context "updates the hearing_postponed attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_scheduled: true - ) - end - - it "sets hearing_postponed to true and all others false" do - subject - - expect(appeal_state.hearing_scheduled).to eq false - expect(appeal_state.hearing_postponed).to eq true - end - end - end - - context "#hearing_withdrawn_appeal_state_update!" do - subject { appeal_state.hearing_withdrawn_appeal_state_update_action! } - - context "updates the hearing_withdrawn attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_scheduled: true - ) - end - - it "sets hearing_withdrawn to true and all others false" do - subject - - expect(appeal_state.appeal_docketed).to eq false - expect(appeal_state.hearing_withdrawn).to eq true - end - end - end - context "#hearing_scheduled_appeal_state_update!" do - subject { appeal_state.hearing_scheduled_appeal_state_update_action! } - - context "updates the hearing_scheduled attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - appeal_docketed: true - ) - end - - it "sets hearing_scheduled to true" do - subject - - expect(appeal_state.hearing_scheduled).to eq true - end - end - end - - context "hearing_held_appeal_state_update_action!" do - subject { appeal_state.hearing_held_appeal_state_update_action! } - - context "updates the hearing_scheduled attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_scheduled: true - ) - end - - it "sets hearing_scheduled to true and all others false" do - expect(appeal_state.hearing_scheduled).to eq true - - subject - - expect(appeal_state.hearing_scheduled).to eq false - end - end - end - - context "#scheduled_in_error_appeal_state_update!" do - subject { appeal_state.scheduled_in_error_appeal_state_update_action! } - - context "updates the scheduled_in_error attribute" do - include_examples "privacy_act_pending status remains active upon update" - - let(:appeal_state) do - create( - :appeal_state, - :ama, - created_by_id: user.id, - updated_by_id: user.id, - hearing_scheduled: true - ) - end - - it "sets scheduled_in_error to true and all others false" do - subject - - expect(appeal_state.hearing_scheduled).to eq false - expect(appeal_state.scheduled_in_error).to eq true - end - end + let!(:_user) { create(:user) } # A User needs to exist for `appeal_state` factories end end diff --git a/spec/models/appellant_notification_spec.rb b/spec/models/appellant_notification_spec.rb index a0438ec0ced..d4d0289a4e5 100644 --- a/spec/models/appellant_notification_spec.rb +++ b/spec/models/appellant_notification_spec.rb @@ -94,7 +94,7 @@ describe "docket_appeal" do let(:appeal) { create(:appeal, :with_pre_docket_task) } let(:appeal_state) { create(:appeal_state, appeal_id: appeal.id, appeal_type: appeal.class.to_s) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.appeal_docketed } + let(:template_name) { "Appeal docketed" } let!(:pre_docket_task) { PreDocketTask.find_by(appeal: appeal) } it "will update the appeal state after docketing the Predocketed Appeal" do pre_docket_task.docket_appeal @@ -107,12 +107,16 @@ appeal_state_record = AppealState.find_by(appeal_id: appeal.id, appeal_type: appeal.class.to_s) expect(appeal_state_record.appeal_docketed).to eq(true) end + it "will update the appeal state after docketing the Predocketed Appeal" do + expect(AppellantNotification).to receive(:appeal_mapper).with(appeal.id, appeal.class.to_s, "appeal_docketed") + pre_docket_task.docket_appeal + end end describe "create_tasks_on_intake_success!" do let(:appeal) { create(:appeal) } let(:appeal_state) { create(:appeal_state, appeal_id: appeal.id, appeal_type: appeal.class.to_s) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.appeal_docketed } + let(:template_name) { "Appeal docketed" } it "will notify appellant that appeal is docketed on successful intake" do appeal.create_tasks_on_intake_success! appeal_state_record = AppealState.find_by(appeal_id: appeal.id, appeal_type: appeal.class.to_s) @@ -123,6 +127,10 @@ appeal_state_record = AppealState.find_by(appeal_id: appeal.id, appeal_type: appeal.class.to_s) expect(appeal_state_record.appeal_docketed).to eq(true) end + it "will update appeal state after appeal is docketed on successful intake" do + expect(AppellantNotification).to receive(:appeal_mapper).with(appeal.id, appeal.class.to_s, "appeal_docketed") + appeal.create_tasks_on_intake_success! + end end end @@ -141,8 +149,8 @@ file: "some file" } end - let(:contested) { Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_contested_claims } - let(:non_contested) { Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims } + let(:contested) { "Appeal decision mailed (Contested claims)" } + let(:non_contested) { "Appeal decision mailed (Non-contested claims)" } let(:dispatch) { LegacyAppealDispatch.new(appeal: legacy_appeal, params: params) } let(:dispatch_func) { "create_decision_document_and_submit_for_processing!" } it "Will notify appellant that the legacy appeal decision has been mailed (Non Contested)" do @@ -150,6 +158,12 @@ decision_document = dispatch.send dispatch_func, params decision_document.process! end + it "Will update appeal state after legacy appeal decision has been mailed (Non Contested)" do + expect(AppellantNotification).to receive(:appeal_mapper) + .with(legacy_appeal.id, legacy_appeal.class.to_s, "decision_mailed") + decision_document = dispatch.send dispatch_func, params + decision_document.process! + end it "Will notify appellant that the legacy appeal decision has been mailed (Contested)" do expect(AppellantNotification).to receive(:notify_appellant).with(legacy_appeal, contested) allow(legacy_appeal).to receive(:contested_claim).and_return(true) @@ -157,6 +171,14 @@ decision_document = dispatch.send dispatch_func, params decision_document.process! end + it "Will update appeal state after legacy appeal decision has been mailed (Contested)" do + expect(AppellantNotification).to receive(:appeal_mapper) + .with(legacy_appeal.id, legacy_appeal.class.to_s, "decision_mailed") + allow(legacy_appeal).to receive(:contested_claim).and_return(true) + legacy_appeal.contested_claim + decision_document = dispatch.send dispatch_func, params + decision_document.process! + end end describe "AMA Appeal Decision Mailed" do @@ -185,8 +207,8 @@ file: "some file" } end - let(:contested) { Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_contested_claims } - let(:non_contested) { Constants.EVENT_TYPE_FILTERS.appeal_decision_mailed_non_contested_claims } + let(:contested) { "Appeal decision mailed (Contested claims)" } + let(:non_contested) { "Appeal decision mailed (Non-contested claims)" } let(:dispatch) do AmaAppealDispatch.new( appeal: appeal, @@ -207,6 +229,11 @@ decision_document = dispatch.send dispatch_func, params decision_document.process! end + it "Will update appeal state after AMA appeal decision has been mailed (Non Contested)" do + expect(AppellantNotification).to receive(:appeal_mapper).with(appeal.id, appeal.class.to_s, "decision_mailed") + decision_document = dispatch.send dispatch_func, params + decision_document.process! + end it "Will notify appellant that the AMA appeal decision has been mailed (Contested)" do expect(AppellantNotification).to receive(:notify_appellant).with(contested_appeal, contested) allow(contested_appeal).to receive(:contested_claim?).and_return(true) @@ -215,6 +242,14 @@ .send dispatch_func, contested_params contested_decision_document.process! end + it "Will update appeal state after AMA appeal decision has been mailed (Contested)" do + expect(AppellantNotification).to receive(:appeal_mapper) + .with(contested_appeal.id, contested_appeal.class.to_s, "decision_mailed") + allow(contested_appeal).to receive(:contested_claim?).and_return(true) + contested_appeal.contested_claim? + contested_decision_document = contested_dispatch.send dispatch_func, contested_params + contested_decision_document.process! + end end end @@ -228,7 +263,7 @@ appeal_type: appeal_hearing.class.to_s, created_by_id: user.id, updated_by_id: user.id) end - let(:template_name) { Constants.EVENT_TYPE_FILTERS.hearing_scheduled } + let(:template_name) { "Hearing scheduled" } let(:hearing) { create(:hearing, appeal: appeal) } let(:schedule_hearing_task) { ScheduleHearingTask.find_by(appeal: appeal_hearing) } let(:task_values) do @@ -284,7 +319,7 @@ describe HearingPostponed do describe "#postpone!" do - let(:template_name) { Constants.EVENT_TYPE_FILTERS.postponement_of_hearing } + let(:template_name) { "Postponement of hearing" } let(:postponed_hearing) { create(:hearing, :postponed, :with_tasks) } let(:appeal_state) do create(:appeal_state, @@ -319,7 +354,7 @@ let!(:hearing) { create(:hearing, hearing_day: hearing_day) } let(:appeal_state) { create(:appeal_state, appeal_id: hearing.appeal.id, appeal_type: hearing.appeal.class.to_s) } context "when a hearing coordinator selects 'postponed' on the daily docket page for an AMA Appeal" do - let(:template_name) { Constants.EVENT_TYPE_FILTERS.postponement_of_hearing } + let(:template_name) { "Postponement of hearing" } let(:params) do { hearing: hearing.reload, @@ -352,7 +387,7 @@ let!(:hearing) { create(:hearing, hearing_day: hearing_day) } let(:appeal_state) { create(:appeal_state, appeal_id: hearing.appeal.id, appeal_type: hearing.appeal.class.to_s) } context "when a hearing coordinator selects 'cancelled' on the daily docket page for an AMA Appeal" do - let(:template_name) { Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing } + let(:template_name) { "Withdrawal of hearing" } let(:params) do { hearing: hearing.reload, @@ -380,7 +415,7 @@ end describe DocketHearingPostponed do - let!(:template_name) { Constants.EVENT_TYPE_FILTERS.postponement_of_hearing } + let!(:template_name) { "Postponement of hearing" } let(:bva) { Bva.singleton } let!(:hearing_coord) { create(:user, roles: ["Edit HearSched", "Build HearSched"]) } describe ".update_hearing" do @@ -442,7 +477,7 @@ end describe DocketHearingWithdrawn do - let!(:template_name) { Constants.EVENT_TYPE_FILTERS.withdrawal_of_hearing } + let!(:template_name) { "Withdrawal of hearing" } let(:bva) { Bva.singleton } let!(:hearing_coord) { create(:user, roles: ["Edit HearSched", "Build HearSched"]) } describe ".update_hearing" do @@ -508,8 +543,8 @@ end describe "FOIA/Privacy Act tasks" do - let(:template_pending) { Constants.EVENT_TYPE_FILTERS.privacy_act_request_pending } - let(:template_closed) { Constants.EVENT_TYPE_FILTERS.privacy_act_request_complete } + let(:template_pending) { "Privacy Act request pending" } + let(:template_closed) { "Privacy Act request complete" } context "HearingAdminFoiaPrivacyRequestTask" do let(:appeal) { create(:appeal) } @@ -549,7 +584,8 @@ task_params_org) end it "updates appeal state when task is created" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") HearingAdminActionFoiaPrivacyRequestTask.create_child_task(parent_task, hearings_management_user, task_params_org) @@ -559,11 +595,13 @@ hafpr_child.update!(status: "completed") end it "updates appeal state when task is completed" do - expect_any_instance_of(AppealState).to receive(:privacy_act_complete_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_complete") hafpr_child.update!(status: "completed") end it "updates appeal state when task is cancelled" do - expect_any_instance_of(AppealState).to receive(:privacy_act_cancelled_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_cancelled") hafpr_child.update!(status: "cancelled") end end @@ -585,44 +623,30 @@ before do priv_org.add_user(current_user) end - context "PrivacyActRequestMailTask" do - context "being created" do - let(:appeal) { create(:appeal) } - let(:root_task) { RootTask.create!(appeal: appeal) } - let!(:distribution_task) { DistributionTask.create!(appeal: appeal, parent: root_task) } - let(:current_user) do - create(:user).tap do |user| - MailTeam.singleton.add_user(user) - end - end - - let(:task_params) do - { - type: "PrivacyActRequestMailTask", - instructions: "fjdkfjwpie", - parent_id: root_task.id - } - end - - it "sends a notification when PrivacyActRequestMailTask is created" do - expect(AppellantNotification).to receive(:notify_appellant).with(appeal, template_pending) - PrivacyActRequestMailTask.create_from_params(task_params, current_user) - end - - it "updates appeal state when PrivacyActRequestMailTask is created" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) - PrivacyActRequestMailTask.create_from_params(task_params, current_user) - end + let(:task_params) do + { + type: "PrivacyActRequestMailTask", + instructions: "fjdkfjwpie" + } + end + it "sends a notification when PrivacyActRequestMailTask is created" do + expect(AppellantNotification).to receive(:notify_appellant).with(appeal, template_pending) + mail_task.create_twin_of_type(task_params) + end + it "updates appeal state when PrivacyActRequestMailTask is created" do + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") + mail_task.create_twin_of_type(task_params) end - it "sends a notification when PrivacyActRequestMailTask is completed" do expect(AppellantNotification).to receive(:notify_appellant).with(appeal, template_closed) foia_child.update!(status: "completed") foia_task.update_status_if_children_tasks_are_closed(foia_child) end it "updates appeal state when PrivacyActRequestMailTask is completed" do - expect_any_instance_of(AppealState).to receive(:privacy_act_complete_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_complete") foia_child.update!(status: "completed") foia_task.update_status_if_children_tasks_are_closed(foia_child) end @@ -632,7 +656,8 @@ foia_task.update_status_if_children_tasks_are_closed(foia_child) end it "does updates appeal state when PrivacyActRequestMailTask is cancelled" do - expect_any_instance_of(AppealState).to receive(:privacy_act_cancelled_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_cancelled") foia_child.update!(status: "cancelled") foia_task.update_status_if_children_tasks_are_closed(foia_child) end @@ -665,7 +690,8 @@ ColocatedTask.create_from_params(foia_colocated_task, attorney) end it "updates appeal state when creating a FoiaColocatedTask" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") ColocatedTask.create_from_params(foia_colocated_task, attorney) end it "sends notification when completing a FoiaColocatedTask" do @@ -675,7 +701,8 @@ end it "updates appeal state when completing a FoiaColocatedTask" do foia_c_task = ColocatedTask.create_from_params(foia_colocated_task, attorney) - expect_any_instance_of(AppealState).to receive(:privacy_act_complete_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_complete") foia_c_task.children.first.update!(status: "completed") end it "does not send a notification when cancelling a FoiaColocatedTask" do @@ -685,7 +712,8 @@ end it "updates the appeal state when cancelling a FoiaColocatedTask" do foia_c_task = ColocatedTask.create_from_params(foia_colocated_task, attorney) - expect_any_instance_of(AppealState).to receive(:privacy_act_cancelled_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_cancelled") foia_c_task.children.first.update!(status: "cancelled") end end @@ -728,7 +756,8 @@ PrivacyActTask.create_child_task(colocated_task, attorney, privacy_params_org) end it "updates appeal state when creating a PrivacyActTask" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") PrivacyActTask.create_child_task(colocated_task, attorney, privacy_params_org) end it "sends notification when completing a PrivacyActTask assigned to user" do @@ -736,8 +765,10 @@ privacy_child.update!(status: "completed") end it "updates appeal state when completing a PrivacyActTask assigned to user" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) - expect_any_instance_of(AppealState).to receive(:privacy_act_complete_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_complete") privacy_child.update!(status: "completed") end it "sends notification when completing a PrivacyActTask assigned to organization" do @@ -745,8 +776,10 @@ privacy_parent.update_with_instructions(status: "completed") end it "updates appeal state when cancelling a PrivacyActTask assigned to organization" do - expect_any_instance_of(AppealState).to receive(:privacy_act_pending_appeal_state_update_action!) - expect_any_instance_of(AppealState).to receive(:privacy_act_cancelled_appeal_state_update_action!) + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_pending") + expect(AppellantNotification).to receive(:appeal_mapper) + .with(appeal.id, appeal.class.to_s, "privacy_act_cancelled") privacy_parent.update_with_instructions(status: "cancelled") end end @@ -769,7 +802,7 @@ ) end let(:task_factory) { IhpTasksFactory.new(root_task) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_pending } + let(:template_name) { "VSO IHP pending" } before do allow_any_instance_of(BGSService).to receive(:fetch_poas_by_participant_ids) .with([participant_id_with_pva]) do @@ -808,7 +841,7 @@ end let(:root_task) { RootTask.find_by(appeal: appeal) } let(:task_factory) { IhpTasksFactory.new(root_task) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_pending } + let(:template_name) { "VSO IHP pending" } it "The appellant will NOT recieve an 'IhpTaskPending' notification" do expect(AppellantNotification).not_to receive(:notify_appellant).with(appeal, template_name) task_factory.create_ihp_tasks! @@ -827,7 +860,7 @@ let(:colocated_task) do ColocatedTask.create!(appeal: appeal, parent_id: root_task.id, assigned_by: attorney, assigned_to: org) end - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_pending } + let(:template_name) { "VSO IHP pending" } let(:params) do { instructions: "test", @@ -907,7 +940,7 @@ let(:org) { create(:organization) } let(:task) { create(:colocated_task, :ihp, :in_progress, assigned_to: org) } let(:appeal_state) { create(:appeal_state, appeal_id: task.appeal.id, appeal_type: task.appeal.class.to_s) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_complete } + let(:template_name) { "VSO IHP complete" } it "will notify the appellant of the 'IhpTaskComplete' status" do allow(task).to receive(:verify_user_can_update!).with(user).and_return(true) expect(AppellantNotification).to receive(:notify_appellant).with(task.appeal, template_name) @@ -928,7 +961,7 @@ let(:org) { create(:organization) } let(:task) { create(:informal_hearing_presentation_task, :in_progress, assigned_to: org) } let(:appeal_state) { create(:appeal_state, appeal_id: task.appeal.id, appeal_type: task.appeal.class.to_s) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_complete } + let(:template_name) { "VSO IHP complete" } it "will notify the appellant of the 'IhpTaskComplete' status" do allow(task).to receive(:verify_user_can_update!).with(user).and_return(true) expect(AppellantNotification).to receive(:notify_appellant).with(task.appeal, template_name) @@ -961,7 +994,7 @@ let(:user) { create(:user) } let(:org) { create(:organization) } let(:task) { create(:colocated_task, :ihp, :in_progress, assigned_to: org) } - let(:template_name) { Constants.EVENT_TYPE_FILTERS.vso_ihp_complete } + let(:template_name) { "VSO IHP complete" } it "will update the 'vso_ihp_complete' column in the Appeal State table to TRUE" do allow(task).to receive(:verify_user_can_update!).with(user).and_return(true) task.update!(status: "completed") @@ -998,7 +1031,7 @@ describe SendNotificationJob do let(:appeal) { create(:appeal, :active) } - let(:template) { Constants.EVENT_TYPE_FILTERS.hearing_scheduled } + let(:template) { "Hearing scheduled" } let(:payload) { AppellantNotification.create_payload(appeal, template_name) } describe "#perform" do it "pushes a new message" do diff --git a/spec/models/case_distribution_lever_spec.rb b/spec/models/case_distribution_lever_spec.rb index a687a6a7926..105834af346 100644 --- a/spec/models/case_distribution_lever_spec.rb +++ b/spec/models/case_distribution_lever_spec.rb @@ -10,7 +10,6 @@ batch_size_per_attorney ama_direct_review_start_distribution_prior_to_goals ama_hearing_case_affinity_days - ama_hearing_case_aod_affinity_days cavc_affinity_days ama_evidence_submission_docket_time_goals ama_hearings_docket_time_goals] diff --git a/spec/models/concerns/distribution_concern_spec.rb b/spec/models/concerns/distribution_concern_spec.rb index a11f9228e18..819f0976309 100644 --- a/spec/models/concerns/distribution_concern_spec.rb +++ b/spec/models/concerns/distribution_concern_spec.rb @@ -28,24 +28,19 @@ class DistributionConcernTestClass end let(:appeal_no_open_dist_task) { create(:appeal, :assigned_to_judge, associated_judge: judge) } - subject { @concern_test_class.send :assign_judge_tasks_for_appeals, appeals, judge } + subject { @concern_test_class } context "for appeals with no open distribution task" do let!(:appeals) { [appeal_no_open_dist_task] } it "appeals are skipped and return nil " do - result = subject + result = subject.send :assign_judge_tasks_for_appeals, appeals, judge expect(result.first).to be nil end end context "for appeals with an open distribution task" do - let!(:mocked_slack_service) { instance_double(SlackService) } - before do - allow(SlackService).to receive(:new).and_return(mocked_slack_service) - end - context "when an appeal has another open task in allowable list" do let!(:appeals) do appeal = create(:appeal, :direct_review_docket, :ready_for_distribution) @@ -57,9 +52,9 @@ class DistributionConcernTestClass end it "a JudgeAssignTask is created and no slack notification is sent" do - expect(mocked_slack_service).not_to receive(:send_notification) + expect_any_instance_of(SlackService).not_to receive(:send_notification) - result = subject + result = subject.send :assign_judge_tasks_for_appeals, appeals, judge expect(result[0].is_a?(JudgeAssignTask)).to be true end @@ -78,37 +73,13 @@ class DistributionConcernTestClass end it "a JudgeAssignTask is created and slack notification is sent" do - expect(mocked_slack_service).to receive(:send_notification).exactly(1).times + expect_any_instance_of(SlackService).to receive(:send_notification).exactly(1).times - result = subject + result = subject.send :assign_judge_tasks_for_appeals, appeals, judge expect(result[0].is_a?(JudgeAssignTask)).to be true end end - - context "when an appeal has a closed RootTask" do - let(:appeal_cancelled_root_task) do - appeal = create(:appeal, :direct_review_docket, :ready_for_distribution) - appeal.root_task.cancelled! - appeal - end - let(:appeal_completed_root_task) do - appeal = create(:appeal, :direct_review_docket, :ready_for_distribution) - appeal.root_task.completed! - appeal - end - let(:appeal_distributable) { create(:appeal, :direct_review_docket, :ready_for_distribution) } - let!(:appeals) { [appeal_cancelled_root_task, appeal_completed_root_task, appeal_distributable] } - - it "does not distribute and sends a slack notification" do - expect(mocked_slack_service).to receive(:send_notification).exactly(2).times - - result = subject - - expect(result.compact.count).to eq 1 - expect(result.compact[0].is_a?(JudgeAssignTask)).to be true - end - end end end diff --git a/spec/models/docket_spec.rb b/spec/models/docket_spec.rb index beaa71dc4c8..e2b18b43b92 100644 --- a/spec/models/docket_spec.rb +++ b/spec/models/docket_spec.rb @@ -61,11 +61,8 @@ create(:appeal, :type_cavc_remand, :cavc_ready_for_distribution, - :with_appeal_affinity, - docket_type: Constants.AMA_DOCKETS.direct_review, - affinity_start_date: affinity_start_date) + docket_type: Constants.AMA_DOCKETS.direct_review) end - let(:affinity_start_date) { Time.zone.now } context "docket type" do # docket_type is implemented in the subclasses and should error if called here @@ -106,7 +103,7 @@ subject { DirectReviewDocket.new.appeals(ready: true, genpop: "not_genpop", judge: other_judge) } it "returns no appeals" do - expect(subject.to_a.length).to eq 0 + expect(subject.count.size).to eq 0 end end @@ -249,35 +246,35 @@ expect(subject).to include with_blocking_but_closed_tasks end end + + context "nonblocking mail tasks but closed Root Task" do + it "excludes those appeals" do + inactive_appeal = create(:appeal, + :with_post_intake_tasks, + docket_type: Constants.AMA_DOCKETS.direct_review) + AodMotionMailTask.create_from_params({ + appeal: inactive_appeal, + parent_id: inactive_appeal.root_task.id + }, user) + inactive_appeal.root_task.update!(status: "completed") + + expect(subject).to_not include inactive_appeal + end + end end end context "count" do let(:priority) { nil } - let(:ready) { nil } - subject { DirectReviewDocket.new.count(priority: priority, ready: ready) } + subject { DirectReviewDocket.new.count(priority: priority) } - it "counts all active appeals on the docket" do + it "counts appeals" do expect(subject).to eq(6) end - context "when looking for ready appeals" do - let(:ready) { true } - it "counts only ready appeals" do - expect(subject).to eq(6) - end - end - context "when looking for nonpriority appeals" do let(:priority) { false } - it "counts active nonpriority appeals" do - expect(subject).to eq(3) - end - end - - context "when looking for priority appeals" do - let(:priority) { true } - it "counts active priority appeals" do + it "counts nonpriority appeals" do expect(subject).to eq(3) end end @@ -302,37 +299,19 @@ end context "age_of_n_oldest_priority_appeals_available_to_judge" do - # Set cavc_appeal to be outside its affinity window - let(:affinity_start_date) { (CaseDistributionLever.cavc_affinity_days + 7).days.ago } let(:judge) { create(:user, :with_vacols_judge_record) } - let!(:cavc_appeal_no_appeal_affinity) do - create_ready_cavc_appeal_without_appeal_affinity(tied_judge: judge, created_date: 7.days.ago) - end - - before do - FeatureToggle.enable!(:acd_exclude_from_affinity) - FeatureToggle.enable!(:acd_distribute_by_docket_date) - end subject { DirectReviewDocket.new.age_of_n_oldest_priority_appeals_available_to_judge(judge, 5) } it "returns the receipt_date field of the oldest direct review priority appeals ready for distribution" do - expect(subject.length).to eq(4) - expect(subject).to match_array([aod_age_appeal.receipt_date, - aod_motion_appeal.receipt_date, - cavc_appeal.receipt_date, - cavc_appeal_no_appeal_affinity.receipt_date]) + expect(subject.length).to eq(3) + expect(subject).to eq([aod_age_appeal.receipt_date, aod_motion_appeal.receipt_date, cavc_appeal.receipt_date]) end end context "age_of_n_oldest_nonpriority_appeals_available_to_judge" do let(:judge) { create(:user, :with_vacols_judge_record) } - before do - FeatureToggle.enable!(:acd_exclude_from_affinity) - FeatureToggle.enable!(:acd_distribute_by_docket_date) - end - subject { DirectReviewDocket.new.age_of_n_oldest_nonpriority_appeals_available_to_judge(judge, 5) } it "returns the receipt_date field of the oldest direct review priority appeals ready for distribution" do @@ -443,7 +422,11 @@ let(:second_judge) { create(:user, :judge, :with_vacols_judge_record) } let(:second_distribution) { Distribution.create!(judge: second_judge) } - let(:affinity_start_date) { (CaseDistributionLever.cavc_affinity_days + 1).days.ago } + let(:cavc_affinity_days) { CaseDistributionLever.cavc_affinity_days } + + before do + cavc_distribution_task.update!(assigned_at: (cavc_affinity_days + 1).days.ago) + end context "when genpop: not_genpop is set" do it "is not distributed because it is now genpop" do @@ -728,60 +711,4 @@ end end end - - context "distribute appeals when CAVC cases don't have an appeal_affinity record" do - let(:judge) { create(:user, :judge, :with_vacols_judge_record) } - let!(:distribution) { Distribution.create!(judge: judge) } - let!(:cavc_appeal_with_appeal_affinity) do - appeal = create_ready_cavc_appeal_without_appeal_affinity(tied_judge: judge, created_date: 7.days.ago) - create(:appeal_affinity, appeal: appeal) - appeal - end - let!(:cavc_appeal_no_appeal_affinity) do - create_ready_cavc_appeal_without_appeal_affinity(tied_judge: judge, created_date: 7.days.ago) - end - - before do - FeatureToggle.enable!(:acd_exclude_from_affinity) - FeatureToggle.enable!(:acd_distribute_by_docket_date) - end - - subject { DirectReviewDocket.new.distribute_appeals(distribution, priority: true, limit: 3) } - - it "selects all appeals tied to the requesting judge" do - expect(subject.map(&:case_id)).to match_array([cavc_appeal_with_appeal_affinity.uuid, - cavc_appeal_no_appeal_affinity.uuid]) - end - end - - def create_ready_cavc_appeal_without_appeal_affinity(tied_judge: nil, created_date: 1.year.ago) - Timecop.travel(created_date - 6.months) - if tied_judge - judge = tied_judge - attorney = JudgeTeam.for_judge(judge)&.attorneys&.first || create(:user, :with_vacols_attorney_record) - else - judge = create(:user, :judge, :with_vacols_judge_record) - attorney = create(:user, :with_vacols_attorney_record) - end - - source_appeal = create( - :appeal, - :direct_review_docket, - :dispatched, - associated_judge: judge, - associated_attorney: attorney - ) - - Timecop.travel(6.months.from_now) - cavc_remand = create( - :cavc_remand, - source_appeal: source_appeal - ) - remand_appeal = cavc_remand.remand_appeal - distribution_tasks = remand_appeal.tasks.select { |task| task.is_a?(DistributionTask) } - (distribution_tasks.flat_map(&:descendants) - distribution_tasks).each(&:completed!) - Timecop.return - - remand_appeal - end end diff --git a/spec/models/dockets/hearing_request_docket_spec.rb b/spec/models/dockets/hearing_request_docket_spec.rb index 4bfb93c8452..5077d95aa84 100644 --- a/spec/models/dockets/hearing_request_docket_spec.rb +++ b/spec/models/dockets/hearing_request_docket_spec.rb @@ -2,14 +2,17 @@ describe HearingRequestDocket, :postgres do before do - # 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 - 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, :ama_hearing_case_affinity_days) + create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days) create(:case_distribution_lever, :request_more_cases_minimum) create(:case_distribution_lever, :cavc_affinity_days) FeatureToggle.enable!(:acd_distribute_by_docket_date) + + # 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") end context "#ready_priority_appeals" do @@ -117,42 +120,6 @@ end end end - - context "when cases don't have an appeal_affinity record" do - let(:other_judge) { create(:user, :judge, :with_vacols_judge_record) } - let!(:ready_aod_appeal_tied_to_judge_without_appeal_affinity) do - create_ready_aod_appeal_no_appeal_affinity(tied_judge: requesting_judge, created_date: 7.days.ago) - end - let!(:ready_aod_appeal_tied_to_other_judge_without_appeal_affinity) do - create_ready_aod_appeal_no_appeal_affinity(tied_judge: other_judge, created_date: 7.days.ago) - end - let!(:ready_nonpriority_appeal_tied_to_judge_without_appeal_affinity) do - create_ready_nonpriority_appeal_no_appeal_affinity(tied_judge: requesting_judge, created_date: 5.days.ago) - end - let!(:ready_nonpriority_appeal_tied_to_other_judge_without_appeal_affinity) do - create_ready_nonpriority_appeal_no_appeal_affinity(tied_judge: other_judge, created_date: 5.days.ago) - end - - before { FeatureToggle.enable!(:acd_exclude_from_affinity) } - - subject { described_class.new } - - it "priority appeals tied to the requesting judge are still selected" do - expect(subject.age_of_n_oldest_priority_appeals_available_to_judge(requesting_judge, 3)).to match_array( - [ready_aod_appeal_tied_to_judge.receipt_date, - ready_aod_appeal_tied_to_judge_without_appeal_affinity.receipt_date, - ready_aod_appeal_hearing_cancelled.receipt_date] - ) - end - - it "nonpriority appeals tied to the requesting judge are still selected" do - expect(subject.age_of_n_oldest_nonpriority_appeals_available_to_judge(requesting_judge, 3)).to match_array( - [ready_nonpriority_appeal_tied_to_judge.receipt_date, - ready_nonpriority_appeal_tied_to_judge_without_appeal_affinity.receipt_date, - ready_nonpriority_appeal_hearing_cancelled.receipt_date] - ) - end - end end context "when the distribution contains Specialty Case Team appeals" do @@ -650,10 +617,6 @@ let!(:ready_aod_tied_to_other_judge_out_of_window_20_days) do create_ready_aod_appeal(tied_judge: other_judge, created_date: 20.days.ago) end - let!(:ready_aod_tied_to_requesting_judge_no_appeal_affinity) do - create_ready_aod_appeal_no_appeal_affinity(tied_judge: requesting_judge_no_attorneys, - created_date: 10.days.ago) - end # appeal which is always genpop let!(:ready_aod_hearing_cancelled) do @@ -684,7 +647,6 @@ 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, - ready_aod_tied_to_requesting_judge_no_appeal_affinity.uuid, ready_aod_hearing_cancelled.uuid, sct_ready_priority_appeal_not_tied_to_a_judge.uuid] ) @@ -695,21 +657,6 @@ end def create_ready_aod_appeal(tied_judge: nil, created_date: 1.year.ago) - Timecop.travel(created_date) - appeal = create( - :appeal, - :hearing_docket, - :advanced_on_docket_due_to_age, - :with_post_intake_tasks, - :held_hearing_and_ready_to_distribute, - :with_appeal_affinity, - tied_judge: tied_judge || create(:user, :judge, :with_vacols_judge_record) - ) - Timecop.return - appeal - end - - def create_ready_aod_appeal_no_appeal_affinity(tied_judge: nil, created_date: 1.year.ago) Timecop.travel(created_date) appeal = create( :appeal, @@ -753,27 +700,12 @@ def create_ready_cavc_appeal(tied_judge: nil, created_date: 1.year.ago) remand_appeal = cavc_remand.remand_appeal distribution_tasks = remand_appeal.tasks.select { |task| task.is_a?(DistributionTask) } (distribution_tasks.flat_map(&:descendants) - distribution_tasks).each(&:completed!) - create(:appeal_affinity, appeal: remand_appeal) Timecop.return remand_appeal end def create_ready_nonpriority_appeal(tied_judge: nil, created_date: 1.year.ago) - Timecop.travel(created_date) - appeal = create( - :appeal, - :hearing_docket, - :with_post_intake_tasks, - :held_hearing_and_ready_to_distribute, - :with_appeal_affinity, - tied_judge: tied_judge || create(:user, :judge, :with_vacols_judge_record) - ) - Timecop.return - appeal - end - - def create_ready_nonpriority_appeal_no_appeal_affinity(tied_judge: nil, created_date: 1.year.ago) Timecop.travel(created_date) appeal = create( :appeal, diff --git a/spec/models/tasks/assign_hearing_disposition_task_spec.rb b/spec/models/tasks/assign_hearing_disposition_task_spec.rb index 133ef7f8546..188901dbfee 100644 --- a/spec/models/tasks/assign_hearing_disposition_task_spec.rb +++ b/spec/models/tasks/assign_hearing_disposition_task_spec.rb @@ -221,13 +221,9 @@ it "sets the hearing disposition and calls hold!", :aggregate_failures do expect(disposition_task).to receive(:hold!).exactly(1).times.and_call_original - state = appeal.appeal_state.tap { _1.update!(hearing_scheduled: true) } - expect(state.hearing_scheduled).to eq true - subject expect(hearing.disposition).to eq Constants.HEARING_DISPOSITION_TYPES.held - expect(state.reload.hearing_scheduled).to eq false if appeal.is_a? Appeal expect(Hearing.count).to eq 1 diff --git a/spec/models/tasks/distribution_task_spec.rb b/spec/models/tasks/distribution_task_spec.rb index 4972076ad48..9605a1e23d3 100644 --- a/spec/models/tasks/distribution_task_spec.rb +++ b/spec/models/tasks/distribution_task_spec.rb @@ -76,54 +76,4 @@ end end end - - describe "after_update hooks" do - before do - distribution_task.update!(status: "on_hold") - create(:appeal_affinity, appeal: distribution_task.appeal) - end - - context "when affinity appeal is not set to assigned" do - it "returns an affinity appeal start date with no instructions" do - expect(distribution_task.appeal.appeal_affinity.affinity_start_date).to_not eq nil - expect(distribution_task.instructions.size).to eq 0 - end - end - - context "when affinity appeal is set to assigned" do - before { distribution_task.ready_for_distribution! } - - it "returns no affinity appeal start date with instructions" do - expect(distribution_task.appeal.appeal_affinity.affinity_start_date).to eq nil - expect(distribution_task.instructions.size).to eq 1 - end - end - - context "when no affinity appeal is linked" do - let(:root_task_without_affinity) { create(:root_task) } - let(:distribution_task_without_affinity) do - DistributionTask.create!( - appeal: root_task_without_affinity.appeal, - assigned_to: Bva.singleton - ) - end - - before do - distribution_task_without_affinity.update!(status: "on_hold") - distribution_task_without_affinity.ready_for_distribution! - end - - it "should be assigned" do - expect(distribution_task_without_affinity.status).to eq "assigned" - end - - it "returns no affinity appeal record" do - expect(distribution_task_without_affinity.appeal.appeal_affinity).to eq nil - end - - it "does not update instructions" do - expect(distribution_task_without_affinity.instructions.size).to eq 0 - end - end - end end diff --git a/spec/models/vacols/case_docket_spec.rb b/spec/models/vacols/case_docket_spec.rb index 0322794d56f..5b6929e9a6e 100644 --- a/spec/models/vacols/case_docket_spec.rb +++ b/spec/models/vacols/case_docket_spec.rb @@ -424,6 +424,22 @@ end end + context "when the case has been made genpop" do + let(:hearing_judge) { "1111" } + let(:genpop) { "only_genpop" } + + before do + nonpriority_ready_case.update(bfhines: "GP") + end + + it "distributes the case" do + expect(subject.count).to eq(2) + expect(nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) + expect(third_nonpriority_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) + expect(another_nonpriority_ready_case.reload.bfcurloc).to eq("83") + end + end + context "when bust backlog is specified" do let(:limit) { 2 } let(:bust_backlog) { true } @@ -584,6 +600,21 @@ expect(postcavc_ready_case.reload.bfcurloc).to eq("83") end end + + context "when the case has been made genpop" do + let(:hearing_judge) { "1111" } + let(:genpop) { "only_genpop" } + + before do + aod_ready_case.update(bfhines: "GP") + end + + it "distributes the case" do + expect(subject.count).to eq(1) + expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) + expect(postcavc_ready_case.reload.bfcurloc).to eq("83") + end + end end context "when an aod case is tied to the same judge as last decided the case" do @@ -614,6 +645,17 @@ expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) end end + + context "when the case has been made genpop" do + before do + aod_ready_case.update(bfhines: "GP") + end + + it "distributes the case" do + subject + expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) + end + end end end @@ -678,52 +720,4 @@ expect(nonpriority_ready_case.reload.bfcurloc).to eq(LegacyAppeal::LOCATION_CODES[:caseflow]) end end - - context "removal of BFHINES check" do - let(:genpop) { "any" } - let(:limit) { 10 } - let(:original_docket_number) { aod_ready_case_docket_number } - let!(:hearing) do - create(:case_hearing, - :disposition_held, - folder_nr: original.bfkey, - hearing_date: 5.days.ago.to_date, - board_member: judge.vacols_attorney_id) - end - - subject { VACOLS::CaseDocket.distribute_priority_appeals(judge, genpop, limit) } - - context "when BFHINES is nil" do - before do - aod_ready_case.update(bfhines: nil) - end - - it "distributes the case with passed in judge" do - subject - expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) - end - end - - context "when BFHINES is GP" do - before do - aod_ready_case.update(bfhines: "GP") - end - - it "distributes the case with passed in judge" do - subject - expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) - end - end - - context "when BFHINES is a value other than GP" do - before do - aod_ready_case.update(bfhines: "42") - end - - it "distributes the case with passed in judge" do - subject - expect(aod_ready_case.reload.bfcurloc).to eq(judge.vacols_uniq_id) - end - end - end end diff --git a/spec/models/validators/intake_start_validator_spec.rb b/spec/models/validators/intake_start_validator_spec.rb index d8d6c8dd95a..19f7a9280d6 100644 --- a/spec/models/validators/intake_start_validator_spec.rb +++ b/spec/models/validators/intake_start_validator_spec.rb @@ -33,7 +33,7 @@ context "intake user is on the BVA Intake team" do before { BvaIntake.singleton.add_user(user) } - it "sets a veteran_not_modifiable error code", skip: "Flaky test" do + it "sets a veteran_not_modifiable error code" do subject expect(intake.error_code).to eq "veteran_not_modifiable" diff --git a/spec/requests/api/docs/v3/docs_controller_spec.rb b/spec/requests/api/docs/v3/docs_controller_spec.rb new file mode 100644 index 00000000000..f47d778e0a9 --- /dev/null +++ b/spec/requests/api/docs/v3/docs_controller_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +describe Api::Docs::V3::DocsController, type: :request do + describe "#decision_reviews" do + it "should successfully return openapi spec" do + get "/api/docs/v3/decision_reviews" + expect(response).to have_http_status(200) + json = JSON.parse(response.body) + expect(json["openapi"]).to eq("3.0.0") + end + describe "/higher_level_reviews documentation" do + before(:each) do + get "/api/docs/v3/decision_reviews" + end + let(:hlr_doc) do + json = JSON.parse(response.body) + json["paths"]["/higher_level_reviews"] + end + it "should have POST" do + expect(hlr_doc).to include("post") + end + end + describe "/intake_statuses/{uuid} documentation" do + before(:each) do + get "/api/docs/v3/decision_reviews" + end + let(:hlr_intake_status_doc) do + json = JSON.parse(response.body) + json["paths"]["/intake_statuses/{uuid}"] + end + it "should have GET" do + expect(hlr_intake_status_doc).to include("get") + end + end + describe "/higher_level_reviews/{uuid} documentation" do + before(:each) do + get "/api/docs/v3/decision_reviews" + end + let(:hlr_intake_status_doc) do + json = JSON.parse(response.body) + json["paths"]["/higher_level_reviews/{uuid}"] + end + it "should have GET" do + expect(hlr_intake_status_doc).to include("get") + end + end + end + + describe "#ama_issues" do + it "should successfully return openapi spec" do + get "/api/docs/v3/ama_issues" + expect(response).to have_http_status(200) + json = JSON.parse(response.body) + expect(json["openapi"]).to eq("3.0.3") + end + describe "/issues/ama/find_by_veteran/{veteran_participant_id} documentation" do + before(:each) do + get "/api/docs/v3/ama_issues" + end + let(:ama_issues_find_by_veteran_doc) do + json = JSON.parse(response.body) + json["paths"]["/api/v3/issues/ama/find_by_veteran/{veteran_participant_id}"] + end + it "should have GET" do + expect(ama_issues_find_by_veteran_doc).to include("get") + end + end + end +end diff --git a/spec/requests/api/v2/appeals_spec.rb b/spec/requests/api/v2/appeals_spec.rb deleted file mode 100644 index 718db192347..00000000000 --- a/spec/requests/api/v2/appeals_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require "swagger_helper" - -RSpec.describe "api/v2/appeals", type: :request, openapi_spec: "v2/swagger.yaml", skip: true do - path "/api/v2/appeals" do - get("list appeals") do - response(200, "successful") do - after do |example| - example.metadata[:response][:content] = { - "application/json" => { - example: JSON.parse(response.body, symbolize_names: true) - } - } - end - run_test! - end - end - end -end diff --git a/spec/requests/api/v3/issues/ama/veterans_controller_spec.rb b/spec/requests/api/v3/issues/ama/veterans_controller_spec.rb index d4f7af86f59..2d95a1dbe40 100644 --- a/spec/requests/api/v3/issues/ama/veterans_controller_spec.rb +++ b/spec/requests/api/v3/issues/ama/veterans_controller_spec.rb @@ -119,7 +119,7 @@ include_context :number_of_request_issues_exceeds_paginates_per, true end - context "when a veteran has multiple decision issues with multiple request issues", skip: "Flakey test" do + context "when a veteran has multiple decision issues with multiple request issues" do let_it_be(:vet) { create(:veteran, file_number: "123456789") } let_it_be(:vacols_case) { create(:case, bfcorlid: "123456789S") } let_it_be(:decision_issues) { create_list(:decision_issue, 2, participant_id: vet.participant_id) } diff --git a/spec/seeds/users_spec.rb b/spec/seeds/users_spec.rb index a6e84c71c61..88ce8a3a3ee 100644 --- a/spec/seeds/users_spec.rb +++ b/spec/seeds/users_spec.rb @@ -6,7 +6,7 @@ it "creates all kinds of users and organizations", :aggregate_failures do expect { subject }.to_not raise_error - expect(User.count).to eq(138) + expect(User.count).to eq(148) # This is creating 70 locally and 72 in GHA expect(Organization.count >= 70).to be true expect(VhaProgramOffice.count).to eq(5) diff --git a/spec/services/claim_change_history/claim_history_service_spec.rb b/spec/services/claim_change_history/claim_history_service_spec.rb index fe244f251b5..996d63b9a49 100644 --- a/spec/services/claim_change_history/claim_history_service_spec.rb +++ b/spec/services/claim_change_history/claim_history_service_spec.rb @@ -569,7 +569,7 @@ context "equal to number of days" do let(:filters) { { days_waiting: { number_of_days: 5, operator: "=" } } } - it "should only return events for tasks that match the days waiting filter", skip: "Flakey test" do + it "should only return events for tasks that match the days waiting filter" do subject expect(service_instance.events.map(&:event_type)).to contain_exactly(*expected_hlr_event_types) end diff --git a/spec/services/external_api/va_notify_service_spec.rb b/spec/services/external_api/va_notify_service_spec.rb index 53cadcd0d45..21b385dccce 100644 --- a/spec/services/external_api/va_notify_service_spec.rb +++ b/spec/services/external_api/va_notify_service_spec.rb @@ -17,13 +17,6 @@ let(:status) { "in-progress" } let(:first_name) { "Bob" } let(:docket_number) { "1234567" } - let(:payload) do - { participant_id: participant_id, - notification_id: notification_id, - first_name: first_name, - docket_number: docket_number, - status: status } - end let(:success_response) do HTTPI::Response.new(200, {}, notification_response_body) end @@ -55,7 +48,9 @@ context "notifications sent" do describe "email" do subject do - ExternalApi::VANotifyService.send_email_notifications(**payload, email_template_id: email_template_id) + ExternalApi::VANotifyService.send_email_notifications( + participant_id, notification_id, email_template_id, first_name, docket_number, status + ) end it "email sent successfully" do allow(HTTPI).to receive(:post).and_return(success_response) @@ -72,7 +67,9 @@ describe "sms" do subject do - ExternalApi::VANotifyService.send_sms_notifications(**payload, sms_template_id: sms_template_id) + ExternalApi::VANotifyService.send_sms_notifications( + participant_id, notification_id, sms_template_id, first_name, docket_number, status + ) end it "sms sent successfully" do allow(HTTPI).to receive(:post).and_return(sms_success_response) diff --git a/spec/support/shared_examples/workflows/vbms_document_transactions.rb b/spec/support/shared_examples/workflows/vbms_document_transactions.rb index c65441c4dbf..bd0233ad6e3 100644 --- a/spec/support/shared_examples/workflows/vbms_document_transactions.rb +++ b/spec/support/shared_examples/workflows/vbms_document_transactions.rb @@ -5,7 +5,7 @@ it "fetches file from s3 and returns temporary location" do pdf_name = "veteran-#{document.veteran_file_number}-doc-#{document.id}.pdf" expect(Caseflow::Fakes::S3Service).to receive(:fetch_file) - expect(document_transaction.pdf_location) + expect(doc_to_upload.pdf_location) .to eq File.join(Rails.root, "tmp", "pdfs", pdf_name) end end @@ -14,27 +14,16 @@ context "fetches a bucket name based on document type" do it "changes based on specific document types" do document.document_type = "BVA Case Notifications" - expect(document_transaction.send(:s3_location)).to include("notification-reports") + expect(doc_to_upload.send(:s3_location)).to include("notification-reports") end it "defaults to idt-uploaded-documents" do - expect(document_transaction.send(:s3_location)).to include("idt-uploaded-documents") + expect(doc_to_upload.send(:s3_location)).to include("idt-uploaded-documents") end end end context "#call" do - let(:file_name) do - "veteran-#{document.veteran_file_number}-doc-#{document.id}.pdf" - end - - subject do - # Pulls document from S3 - document_transaction.pdf_location - - expect(File).to exist(File.join(Rails.root, "tmp", "pdfs", file_name)) - - document_transaction.call - end + subject { doc_to_upload.call } before do allow(VBMSService).to receive(transaction_method).and_call_original @@ -54,14 +43,11 @@ subject expect(VBMSService).to have_received(transaction_method).with( - upload_arg, document_transaction + upload_arg, doc_to_upload ) expect(document.uploaded_to_vbms_at).to eq(Time.zone.now) expect(document.processed_at).to_not be_nil expect(document.submitted_at).to eq(Time.zone.now) - - # Ensure that the file is cleaned up - expect(File).not_to exist(File.join(Rails.root, "tmp", "pdfs", file_name)) end end @@ -76,9 +62,6 @@ expect(document.attempted_at).to eq(Time.zone.now) expect(document.processed_at).to be_nil expect(document.error).to eq("Some VBMS error") - - # Ensure that the file is cleaned up - expect(File).not_to exist(File.join(Rails.root, "tmp", "pdfs", file_name)) end end @@ -103,7 +86,7 @@ expect(S3Service).to receive(:store_file).with(expected_path, /PDF/) - document_transaction.cache_file + doc_to_upload.cache_file end end end diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb deleted file mode 100644 index b7bddeb2e4a..00000000000 --- a/spec/swagger_helper.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -OPENAPI = "3.0.2" -SECURITY = { - bearerAuth: [] -}.freeze -SECURITY_SCHEMES = { - bearerAuth: { - type: "http", - scheme: "bearer", - description: "API Key provided by Caseflow" - } -}.freeze - -RSpec.configure do |config| - # Specify a root folder where Swagger JSON files are generated - # NOTE: If you're using the rswag-api to serve API descriptions, you'll need - # to ensure that it's configured to serve Swagger from the same folder - config.openapi_root = Rails.root.join("app/controllers/swagger").to_s - - # Define one or more Swagger documents and provide global metadata for each one - # When you run the 'rswag:specs:swaggerize' rake task, the complete Swagger will - # be generated at the provided relative path under openapi_root - # By default, the operations defined in spec files are added to the first - # document below. You can override this behavior by adding a openapi_spec tag to the - # the root example_group in your specs, e.g. describe '...', openapi_spec: 'v2/swagger.json' - config.openapi_specs = { - "v1/swagger.yaml" => { - openapi: OPENAPI, - info: { - title: "API V1", - version: "v1" - }, - security: SECURITY, - servers: [ - url: "/api/v1" - ], - paths: {}, - components: { - securitySchemes: SECURITY_SCHEMES - } - }, - "v2/swagger.yaml" => { - openapi: OPENAPI, - info: { - title: "API V2", - version: "V2" - }, - security: SECURITY, - servers: [ - url: "/api/v2" - ], - paths: {}, - components: { - securitySchemes: SECURITY_SCHEMES - } - }, - "v3/swagger.yaml" => { - openapi: OPENAPI, - info: { - title: "API V3", - version: "V3" - }, - security: SECURITY, - servers: [ - url: "/api/v3" - ], - paths: {}, - components: { - securitySchemes: SECURITY_SCHEMES - } - } - } - - # Specify the format of the output Swagger file when running 'rswag:specs:swaggerize'. - # The openapi_specs configuration option has the filename including format in - # the key, this may want to be changed to avoid putting yaml in json files. - # Defaults to json. Accepts ':json' and ':yaml'. - config.openapi_format = :yaml -end diff --git a/spec/workflows/bulk_task_reassignment_spec.rb b/spec/workflows/bulk_task_reassignment_spec.rb index 9f442c14808..06bcbc0ffac 100644 --- a/spec/workflows/bulk_task_reassignment_spec.rb +++ b/spec/workflows/bulk_task_reassignment_spec.rb @@ -93,8 +93,11 @@ expect { subject }.to raise_error(BulkTaskReassignment::InvalidTaskParent).with_message(expected_output) end end + context "with no children" do it "describes what changes will be made and makes them" do + expect(Rails.logger).to receive(:info).exactly(9).times + subject tasks.each do |task| expect(task.reload.cancelled?).to eq true diff --git a/spec/workflows/update_document_in_vbms_spec.rb b/spec/workflows/update_document_in_vbms_spec.rb index 8d36f0e0249..90ad5a86540 100644 --- a/spec/workflows/update_document_in_vbms_spec.rb +++ b/spec/workflows/update_document_in_vbms_spec.rb @@ -21,7 +21,7 @@ end let(:uploaded_to_vbms_at) { nil } let(:processed_at) { nil } - let!(:document_transaction) { UpdateDocumentInVbms.new(document: document) } + let!(:doc_to_upload) { UpdateDocumentInVbms.new(document: document) } let(:transaction_method) { :update_document_in_vbms } let(:upload_arg) { document.appeal } @@ -29,19 +29,19 @@ describe "#source" do it "is hardcoded to BVA" do - expect(document_transaction.source).to eq "BVA" + expect(doc_to_upload.source).to eq "BVA" end end describe "#document_type_id" do it "fetches the ID corresponding to the document type string" do - expect(document_transaction.document_type_id).to eq 482 + expect(doc_to_upload.document_type_id).to eq 482 end end describe "#document_type" do it "reads it from the document instance" do - expect(document_transaction.document_type).to eq document.document_type + expect(doc_to_upload.document_type).to eq document.document_type end end end diff --git a/spec/workflows/upload_document_to_vbms_spec.rb b/spec/workflows/upload_document_to_vbms_spec.rb index b69067b2978..045d40be31a 100644 --- a/spec/workflows/upload_document_to_vbms_spec.rb +++ b/spec/workflows/upload_document_to_vbms_spec.rb @@ -20,7 +20,7 @@ end let(:uploaded_to_vbms_at) { nil } let(:processed_at) { nil } - let!(:document_transaction) { UploadDocumentToVbms.new(document: document) } + let!(:doc_to_upload) { UploadDocumentToVbms.new(document: document) } let(:transaction_method) { :upload_document_to_vbms_veteran } let(:upload_arg) { document.veteran_file_number } @@ -28,19 +28,19 @@ describe "#source" do it "is hardcoded to BVA" do - expect(document_transaction.source).to eq "BVA" + expect(doc_to_upload.source).to eq "BVA" end end describe "#document_type_id" do it "fetches the ID corresponding to the document type string" do - expect(document_transaction.document_type_id).to eq 482 + expect(doc_to_upload.document_type_id).to eq 482 end end describe "#document_type" do it "reads it from the document instance" do - expect(document_transaction.document_type).to eq document.document_type + expect(doc_to_upload.document_type).to eq document.document_type end end end