From 0d42b992008e88bd4d397965d915d59a0ab2c5e9 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 24 Apr 2023 10:43:15 -0400 Subject: [PATCH 001/308] APPEALS-21142 branch init --- app/controllers/hearings/appeals_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/hearings/appeals_controller.rb b/app/controllers/hearings/appeals_controller.rb index 32fb47ade8c..ea14a60498c 100644 --- a/app/controllers/hearings/appeals_controller.rb +++ b/app/controllers/hearings/appeals_controller.rb @@ -8,6 +8,7 @@ class Hearings::AppealsController < HearingsController def update appeal.update!(appeal_params) render json: { appeal: appeal.attributes_for_hearing } + end private From a70558fc77ae7f890c29c4dcdc6e28ea89baf32b Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Mon, 24 Apr 2023 11:59:00 -0400 Subject: [PATCH 002/308] APPEALS-21119 Added empty files for audit tables creation --- db/scripts/audit/create_vbms_communication_packages_audit.rb | 0 db/scripts/audit/create_vbms_communication_packages_audit.sql | 0 db/scripts/audit/create_vbms_distribution_destinations_audit.rb | 0 db/scripts/audit/create_vbms_distribution_destinations_audit.sql | 0 db/scripts/audit/create_vbms_distributions_audit.rb | 0 db/scripts/audit/create_vbms_distributions_audit.sql | 0 db/scripts/audit/create_vbms_uploaded_documents_audit.rb | 0 db/scripts/audit/create_vbms_uploaded_documents_audit.sql | 0 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 db/scripts/audit/create_vbms_communication_packages_audit.rb create mode 100644 db/scripts/audit/create_vbms_communication_packages_audit.sql create mode 100644 db/scripts/audit/create_vbms_distribution_destinations_audit.rb create mode 100644 db/scripts/audit/create_vbms_distribution_destinations_audit.sql create mode 100644 db/scripts/audit/create_vbms_distributions_audit.rb create mode 100644 db/scripts/audit/create_vbms_distributions_audit.sql create mode 100644 db/scripts/audit/create_vbms_uploaded_documents_audit.rb create mode 100644 db/scripts/audit/create_vbms_uploaded_documents_audit.sql diff --git a/db/scripts/audit/create_vbms_communication_packages_audit.rb b/db/scripts/audit/create_vbms_communication_packages_audit.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_communication_packages_audit.sql b/db/scripts/audit/create_vbms_communication_packages_audit.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/create_vbms_distribution_destinations_audit.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/create_vbms_distribution_destinations_audit.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distributions_audit.rb b/db/scripts/audit/create_vbms_distributions_audit.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distributions_audit.sql b/db/scripts/audit/create_vbms_distributions_audit.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/create_vbms_uploaded_documents_audit.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.sql b/db/scripts/audit/create_vbms_uploaded_documents_audit.sql new file mode 100644 index 00000000000..e69de29bb2d From 25fadf70162bb3807befb0899bf1b7edf65783bd Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 24 Apr 2023 14:50:54 -0400 Subject: [PATCH 003/308] APPEALS-21142 Created three new models --- app/models/vbms_communication_package.rb | 6 ++++++ app/models/vbms_distrobution.rb | 6 ++++++ app/models/vbms_distrobution_destination.rb | 4 ++++ 3 files changed, 16 insertions(+) create mode 100644 app/models/vbms_communication_package.rb create mode 100644 app/models/vbms_distrobution.rb create mode 100644 app/models/vbms_distrobution_destination.rb diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb new file mode 100644 index 00000000000..c391fc70632 --- /dev/null +++ b/app/models/vbms_communication_package.rb @@ -0,0 +1,6 @@ +class VbmsCommunicationPackage < CaseflowRecord + + belongs_to :vbms_uploaded_documents + has_many :vbms_distributions + +end diff --git a/app/models/vbms_distrobution.rb b/app/models/vbms_distrobution.rb new file mode 100644 index 00000000000..cd12d447038 --- /dev/null +++ b/app/models/vbms_distrobution.rb @@ -0,0 +1,6 @@ +class VbmsDistrobution < ApplicationRecord + + belongs_to :vbms_communication_packages + has_many :vbms_distribution_destinations + +end diff --git a/app/models/vbms_distrobution_destination.rb b/app/models/vbms_distrobution_destination.rb new file mode 100644 index 00000000000..1ba1ae2a588 --- /dev/null +++ b/app/models/vbms_distrobution_destination.rb @@ -0,0 +1,4 @@ +class VbmsDistrobutionDestination < ApplicationRecord + + belongs_to :vbms_distributions +end From e58bc91c9f8ca57b82e389cb071a56ce7306e9fa Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 24 Apr 2023 15:40:45 -0400 Subject: [PATCH 004/308] APPEALS-21142 syntax corrections in regards to melongs_to macro. Switched model inheritance from AppplicationRec to CaseflowRec --- app/models/vbms_communication_package.rb | 2 +- app/models/vbms_distrobution.rb | 6 +++--- app/models/vbms_distrobution_destination.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index c391fc70632..6c899b7c244 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,6 +1,6 @@ class VbmsCommunicationPackage < CaseflowRecord - belongs_to :vbms_uploaded_documents + belongs_to :vbms_uploaded_document has_many :vbms_distributions end diff --git a/app/models/vbms_distrobution.rb b/app/models/vbms_distrobution.rb index cd12d447038..a0965d71b89 100644 --- a/app/models/vbms_distrobution.rb +++ b/app/models/vbms_distrobution.rb @@ -1,6 +1,6 @@ -class VbmsDistrobution < ApplicationRecord - - belongs_to :vbms_communication_packages +# frozen_string_literal: true +class VbmsDistrobution < CaseflowRecord + belongs_to :vbms_communication_package has_many :vbms_distribution_destinations end diff --git a/app/models/vbms_distrobution_destination.rb b/app/models/vbms_distrobution_destination.rb index 1ba1ae2a588..61b1178d047 100644 --- a/app/models/vbms_distrobution_destination.rb +++ b/app/models/vbms_distrobution_destination.rb @@ -1,4 +1,4 @@ -class VbmsDistrobutionDestination < ApplicationRecord +class VbmsDistrobutionDestination < CaseflowRecord - belongs_to :vbms_distributions + belongs_to :vbms_distribution end From 9478e0e944eba296448780a5be15bc090581515b Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 24 Apr 2023 15:44:12 -0400 Subject: [PATCH 005/308] APPEALS-21142 minor formatting changes in models. --- app/models/vbms_communication_package.rb | 3 +-- app/models/vbms_distrobution.rb | 2 +- app/models/vbms_distrobution_destination.rb | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 6c899b7c244..1cc7b2a7798 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,6 +1,5 @@ +# frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - belongs_to :vbms_uploaded_document has_many :vbms_distributions - end diff --git a/app/models/vbms_distrobution.rb b/app/models/vbms_distrobution.rb index a0965d71b89..4458cff5621 100644 --- a/app/models/vbms_distrobution.rb +++ b/app/models/vbms_distrobution.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true + class VbmsDistrobution < CaseflowRecord belongs_to :vbms_communication_package has_many :vbms_distribution_destinations - end diff --git a/app/models/vbms_distrobution_destination.rb b/app/models/vbms_distrobution_destination.rb index 61b1178d047..ab8e53f6f87 100644 --- a/app/models/vbms_distrobution_destination.rb +++ b/app/models/vbms_distrobution_destination.rb @@ -1,4 +1,5 @@ -class VbmsDistrobutionDestination < CaseflowRecord +# frozen_string_literal: true +class VbmsDistrobutionDestination < CaseflowRecord belongs_to :vbms_distribution end From b0c3f9cc1a059e56d4b7879943631949d45acf79 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Mon, 24 Apr 2023 16:23:27 -0400 Subject: [PATCH 006/308] APPEALS-21119 Skeleton rb files for table creation. Full file (rb and sql for vbms uploaded doc audit) --- ...reate_vbms_communication_packages_audit.rb | 11 ++++++++ ...te_vbms_distribution_destinations_audit.rb | 11 ++++++++ .../audit/create_vbms_distributions_audit.rb | 11 ++++++++ .../create_vbms_uploaded_documents_audit.rb | 25 +++++++++++++++++++ .../create_vbms_uploaded_documents_audit.sql | 20 +++++++++++++++ 5 files changed, 78 insertions(+) diff --git a/db/scripts/audit/create_vbms_communication_packages_audit.rb b/db/scripts/audit/create_vbms_communication_packages_audit.rb index e69de29bb2d..516fcd1b0c2 100644 --- a/db/scripts/audit/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/create_vbms_communication_packages_audit.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute("create table caseflow_audit.vbms_communication_packages_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_communication_package_id bigint not null, + DATA FROM TABLE... + );") diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/create_vbms_distribution_destinations_audit.rb index e69de29bb2d..2f333f274c7 100644 --- a/db/scripts/audit/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/create_vbms_distribution_destinations_audit.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute("create table caseflow_audit.vbms_distribution_destinations_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_distribution_destinations_id bigint not null, + DATA FROM TABLE... + );") diff --git a/db/scripts/audit/create_vbms_distributions_audit.rb b/db/scripts/audit/create_vbms_distributions_audit.rb index e69de29bb2d..0170416026f 100644 --- a/db/scripts/audit/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/create_vbms_distributions_audit.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute("create table caseflow_audit.vbms_distributions_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_distributions_id bigint not null, + DATA FROM TABLE... + );") diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/create_vbms_uploaded_documents_audit.rb index e69de29bb2d..929ca934df5 100644 --- a/db/scripts/audit/create_vbms_uploaded_documents_audit.rb +++ b/db/scripts/audit/create_vbms_uploaded_documents_audit.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute("create table caseflow_audit.vbms_uploaded_documents_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_uploaded_documents_id bigint not null, + appeal_id int8, + appeal_type varchar, + attempted_at timestamp, + canceled_at timestamp, + created_at timestamp NOT NULL, + document_name varchar, + document_subject varchar, + document_type varchar NOT NULL, + error varchar, + last_submitted_at timestamp, + processed_at timestamp, + submitted_at timestamp, + updated_at timestamp NOT NULL, + uploaded_to_vbms_at timestamp, + veteran_file_number varchar + );") diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.sql b/db/scripts/audit/create_vbms_uploaded_documents_audit.sql index e69de29bb2d..abc025d620d 100644 --- a/db/scripts/audit/create_vbms_uploaded_documents_audit.sql +++ b/db/scripts/audit/create_vbms_uploaded_documents_audit.sql @@ -0,0 +1,20 @@ +create table caseflow_audit.vbms_uploaded_documents_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_uploaded_documents_id bigint not null, + appeal_id int8, + appeal_type varchar, + attempted_at timestamp, + canceled_at timestamp, + created_at timestamp NOT NULL, + document_name varchar, + document_subject varchar, + document_type varchar NOT NULL, + error varchar, + last_submitted_at timestamp, + processed_at timestamp, + submitted_at timestamp, + updated_at timestamp NOT NULL, + uploaded_to_vbms_at timestamp, + veteran_file_number varchar + ); From 0d4ceb4af877cbf1b0e7c6c0089c5770c0763ef4 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 25 Apr 2023 11:19:01 -0400 Subject: [PATCH 007/308] APPEALS-21119 Add empty files --- ...add_row_to_vbms_communication_packages_audit_table_function.rb | 0 ...dd_row_to_vbms_communication_packages_audit_table_function.sql | 0 ..._row_to_vbms_distribution_destinations_audit_table_function.rb | 0 ...row_to_vbms_distribution_destinations_audit_table_function.sql | 0 .../audit/add_row_to_vbms_distributions_audit_table_function.rb | 0 .../audit/add_row_to_vbms_distributions_audit_table_function.sql | 0 .../add_row_to_vbms_uploaded_documents_audit_table_function.rb | 0 .../add_row_to_vbms_uploaded_documents_audit_table_function.sql | 0 .../audit/create_vbms_communication_packages_audit_trigger.rb | 0 .../audit/create_vbms_communication_packages_audit_trigger.sql | 0 .../audit/create_vbms_distribution_destinations_audit_trigger.rb | 0 .../audit/create_vbms_distribution_destinations_audit_trigger.sql | 0 db/scripts/audit/create_vbms_distributions_audit_trigger.rb | 0 db/scripts/audit/create_vbms_distributions_audit_trigger.sql | 0 db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb | 0 db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql | 0 16 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.rb create mode 100644 db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.sql create mode 100644 db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.rb create mode 100644 db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.sql create mode 100644 db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.rb create mode 100644 db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.sql create mode 100644 db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.rb create mode 100644 db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.sql create mode 100644 db/scripts/audit/create_vbms_communication_packages_audit_trigger.rb create mode 100644 db/scripts/audit/create_vbms_communication_packages_audit_trigger.sql create mode 100644 db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.rb create mode 100644 db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.sql create mode 100644 db/scripts/audit/create_vbms_distributions_audit_trigger.rb create mode 100644 db/scripts/audit/create_vbms_distributions_audit_trigger.sql create mode 100644 db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb create mode 100644 db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql diff --git a/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.sql b/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_communication_packages_audit_trigger.rb b/db/scripts/audit/create_vbms_communication_packages_audit_trigger.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_communication_packages_audit_trigger.sql b/db/scripts/audit/create_vbms_communication_packages_audit_trigger.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.rb b/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.sql b/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distributions_audit_trigger.rb b/db/scripts/audit/create_vbms_distributions_audit_trigger.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_distributions_audit_trigger.sql b/db/scripts/audit/create_vbms_distributions_audit_trigger.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb b/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql b/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql new file mode 100644 index 00000000000..e69de29bb2d From 5099cd22702e9720c372bafa10053495351730a2 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 25 Apr 2023 11:51:04 -0400 Subject: [PATCH 008/308] created two new tables and three migrations. Migrations create tables with basic information in realtion to the models. FK's will be added in a seperate migration. --- ...4000_create_vbms_communication_packages.rb | 11 +++++++ ...0230425151524_create_vbms_distrobutions.rb | 15 ++++++++++ ...4013_change_vbms_communication_packages.rb | 5 ++++ db/schema.rb | 30 +++++++++++++++---- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20230425144000_create_vbms_communication_packages.rb create mode 100644 db/migrate/20230425151524_create_vbms_distrobutions.rb create mode 100644 db/migrate/20230425154013_change_vbms_communication_packages.rb diff --git a/db/migrate/20230425144000_create_vbms_communication_packages.rb b/db/migrate/20230425144000_create_vbms_communication_packages.rb new file mode 100644 index 00000000000..3842d073ca6 --- /dev/null +++ b/db/migrate/20230425144000_create_vbms_communication_packages.rb @@ -0,0 +1,11 @@ +class CreateVbmsCommunicationPackages < Caseflow::Migration + def change + create_table :vbms_communication_packages do |t| + t.string :file_number + t.bigint :document_referenced, default: [], array: true + t.string :status + t.string :comm_package_name, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20230425151524_create_vbms_distrobutions.rb b/db/migrate/20230425151524_create_vbms_distrobutions.rb new file mode 100644 index 00000000000..142132771c5 --- /dev/null +++ b/db/migrate/20230425151524_create_vbms_distrobutions.rb @@ -0,0 +1,15 @@ +class CreateVbmsDistrobutions < Caseflow::Migration + def change + create_table :vbms_distrobutions do |t| + t.string :type, null: false + t.string :name, null: false + t.string :middle_name + t.string :last_name, null: false + t.string :participant_id + t.string :poa_code, null: false + t.string :claimant_station_oc_jurisdiction, null: false + t.timestamp :created_at, null: false + t.timestamp :updated_at + end + end +end diff --git a/db/migrate/20230425154013_change_vbms_communication_packages.rb b/db/migrate/20230425154013_change_vbms_communication_packages.rb new file mode 100644 index 00000000000..c0ae1770b27 --- /dev/null +++ b/db/migrate/20230425154013_change_vbms_communication_packages.rb @@ -0,0 +1,5 @@ +class ChangeVbmsCommunicationPackages < Caseflow::Migration + def change + change_column_null(:vbms_communication_packages, :updated_at, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index a3711114e08..09ac860ee6d 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: 2023_03_17_164013) do +ActiveRecord::Schema.define(version: 2023_04_25_154013) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -91,7 +91,7 @@ t.boolean "appeal_docketed", default: false, null: false, comment: "When true, appeal has been docketed" t.bigint "appeal_id", null: false, comment: "AMA or Legacy Appeal ID" t.string "appeal_type", null: false, comment: "Appeal Type (Appeal or LegacyAppeal)" - t.datetime "created_at", null: false + t.datetime "created_at", null: false, comment: "Date and Time the record was inserted into the table" t.bigint "created_by_id", null: false, comment: "User id of the user that inserted the record" t.boolean "decision_mailed", default: false, null: false, comment: "When true, appeal has decision mail request complete" t.boolean "hearing_postponed", default: false, null: false, comment: "When true, appeal has hearing postponed and no hearings scheduled" @@ -100,7 +100,7 @@ t.boolean "privacy_act_complete", default: false, null: false, comment: "When true, appeal has a privacy act request completed" t.boolean "privacy_act_pending", default: false, null: false, comment: "When true, appeal has a privacy act request still open" t.boolean "scheduled_in_error", default: false, null: false, comment: "When true, hearing was scheduled in error and none scheduled" - t.datetime "updated_at" + t.datetime "updated_at", comment: "Date and time the record was last updated" t.bigint "updated_by_id", comment: "User id of the last user that updated the record" t.boolean "vso_ihp_complete", default: false, null: false, comment: "When true, appeal has a VSO IHP request completed" t.boolean "vso_ihp_pending", default: false, null: false, comment: "When true, appeal has a VSO IHP request pending" @@ -1275,7 +1275,7 @@ t.string "recipient_email", comment: "Participant's Email Address" t.string "recipient_phone_number", comment: "Participants Phone Number" t.text "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_external_id" t.string "sms_notification_status", comment: "Status of SMS/Text Notification" 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" @@ -1577,7 +1577,6 @@ t.boolean "national_cemetery_administration", default: false t.boolean "no_special_issues", default: false, comment: "Affirmative no special issues, added belatedly" t.boolean "nonrating_issue", default: false - t.boolean "pact_act", default: false, comment: "The Sergeant First Class (SFC) Heath Robinson Honoring our Promise to Address Comprehensive Toxics (PACT) Act" t.boolean "pension_united_states", default: false t.boolean "private_attorney_or_agent", default: false t.boolean "radiation", default: false @@ -1789,6 +1788,27 @@ t.index ["updated_at"], name: "index_users_on_updated_at" end + create_table "vbms_communication_packages", force: :cascade do |t| + t.string "comm_package_name", null: false + t.datetime "created_at", null: false + t.bigint "document_referenced", default: [], array: true + t.string "file_number" + t.string "status" + t.datetime "updated_at" + end + + create_table "vbms_distrobutions", force: :cascade do |t| + t.string "claimant_station_oc_jurisdiction", null: false + t.datetime "created_at", null: false + t.string "last_name", null: false + t.string "middle_name" + t.string "name", null: false + t.string "participant_id" + t.string "poa_code", null: false + t.string "type", null: false + t.datetime "updated_at" + end + create_table "vbms_uploaded_documents", force: :cascade do |t| t.bigint "appeal_id", comment: "Appeal/LegacyAppeal ID; use as FK to appeals/legacy_appeals" t.string "appeal_type", comment: "'Appeal' or 'LegacyAppeal'" From d3cb31dc0a9e474bc2236fb686bf003a070b9187 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 25 Apr 2023 13:34:55 -0400 Subject: [PATCH 009/308] base tables made for mew models. next step is to add/run migrations for the foreign keys. --- ...5_create_vbms_distrobution_destinations.rb | 24 +++++++++++++++++++ db/schema.rb | 23 +++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20230425171045_create_vbms_distrobution_destinations.rb diff --git a/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb b/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb new file mode 100644 index 00000000000..2bbf4b1c967 --- /dev/null +++ b/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb @@ -0,0 +1,24 @@ +class CreateVbmsDistrobutionDestinations < Caseflow::Migration + def change + create_table :vbms_distrobution_destinations do |t| + t.string :type, null: false + t.string :address_line_1, null: false + t.string :address_line_2, null: false + t.string :address_line_3, null: false + t.string :address_line_4 + t.string :address_line_5 + t.string :address_line_6 + t.boolean :treat_line_2_as_addressee, null: false + t.boolean :treat_line_3_as_addressee + t.string :city, null: false + t.string :state, null: false + t.string :postal_code, null: false + t.string :country_name, null: false + t.string :country_code, null: false + t.string :email_address, null: false + t.string :phone_number, null: false + t.timestamp :created_at, null: false + t.timestamp :updated_at + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 09ac860ee6d..7c1a5d4842c 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: 2023_04_25_154013) do +ActiveRecord::Schema.define(version: 2023_04_25_171045) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1797,6 +1797,27 @@ t.datetime "updated_at" end + create_table "vbms_distrobution_destinations", force: :cascade do |t| + t.string "address_line_1", null: false + t.string "address_line_2", null: false + t.string "address_line_3", null: false + t.string "address_line_4" + t.string "address_line_5" + t.string "address_line_6" + t.string "city", null: false + t.string "country_code", null: false + t.string "country_name", null: false + t.datetime "created_at", null: false + t.string "email_address", null: false + t.string "phone_number", null: false + t.string "postal_code", null: false + t.string "state", null: false + t.boolean "treat_line_2_as_addressee", null: false + t.boolean "treat_line_3_as_addressee" + t.string "type", null: false + t.datetime "updated_at" + end + create_table "vbms_distrobutions", force: :cascade do |t| t.string "claimant_station_oc_jurisdiction", null: false t.datetime "created_at", null: false From ea6d89b8962784810a87e56d6935cc99ca7efe43 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 25 Apr 2023 13:45:12 -0400 Subject: [PATCH 010/308] APPEALS-21119 Reorganize audit folder and update old paths in makefile --- Makefile.example | 6 +++--- .../add_row_to_appeal_states_audit_table_function.rb | 0 .../add_row_to_appeal_states_audit_table_function.sql | 0 ...w_to_vbms_communication_packages_audit_table_function.rb | 0 ..._to_vbms_communication_packages_audit_table_function.sql | 0 ...o_vbms_distribution_destinations_audit_table_function.rb | 0 ..._vbms_distribution_destinations_audit_table_function.sql | 0 .../add_row_to_vbms_distributions_audit_table_function.rb | 0 .../add_row_to_vbms_distributions_audit_table_function.sql | 0 ...d_row_to_vbms_uploaded_documents_audit_table_function.rb | 0 ..._row_to_vbms_uploaded_documents_audit_table_function.sql | 0 db/scripts/audit/{ => tables}/create_appeal_states_audit.rb | 0 .../audit/{ => tables}/create_appeal_states_audit.sql | 0 .../create_vbms_communication_packages_audit.rb | 0 .../create_vbms_communication_packages_audit.sql | 0 .../create_vbms_distribution_destinations_audit.rb | 0 .../create_vbms_distribution_destinations_audit.sql | 0 .../audit/{ => tables}/create_vbms_distributions_audit.rb | 0 .../audit/{ => tables}/create_vbms_distributions_audit.sql | 0 .../{ => tables}/create_vbms_uploaded_documents_audit.rb | 0 .../{ => tables}/create_vbms_uploaded_documents_audit.sql | 0 .../{ => triggers}/create_appeal_states_audit_trigger.rb | 0 .../{ => triggers}/create_appeal_states_audit_trigger.sql | 0 .../create_vbms_communication_packages_audit_trigger.rb | 0 .../create_vbms_communication_packages_audit_trigger.sql | 0 .../create_vbms_distribution_destinations_audit_trigger.rb | 0 .../create_vbms_distribution_destinations_audit_trigger.sql | 0 .../create_vbms_distributions_audit_trigger.rb | 0 .../create_vbms_distributions_audit_trigger.sql | 0 .../create_vbms_uploaded_documents_audit_trigger.rb | 0 .../create_vbms_uploaded_documents_audit_trigger.sql | 0 31 files changed, 3 insertions(+), 3 deletions(-) rename db/scripts/audit/{ => functions}/add_row_to_appeal_states_audit_table_function.rb (100%) rename db/scripts/audit/{ => functions}/add_row_to_appeal_states_audit_table_function.sql (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_communication_packages_audit_table_function.rb (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_communication_packages_audit_table_function.sql (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_distribution_destinations_audit_table_function.rb (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_distribution_destinations_audit_table_function.sql (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_distributions_audit_table_function.rb (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_distributions_audit_table_function.sql (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_uploaded_documents_audit_table_function.rb (100%) rename db/scripts/audit/{ => functions}/add_row_to_vbms_uploaded_documents_audit_table_function.sql (100%) rename db/scripts/audit/{ => tables}/create_appeal_states_audit.rb (100%) rename db/scripts/audit/{ => tables}/create_appeal_states_audit.sql (100%) rename db/scripts/audit/{ => tables}/create_vbms_communication_packages_audit.rb (100%) rename db/scripts/audit/{ => tables}/create_vbms_communication_packages_audit.sql (100%) rename db/scripts/audit/{ => tables}/create_vbms_distribution_destinations_audit.rb (100%) rename db/scripts/audit/{ => tables}/create_vbms_distribution_destinations_audit.sql (100%) rename db/scripts/audit/{ => tables}/create_vbms_distributions_audit.rb (100%) rename db/scripts/audit/{ => tables}/create_vbms_distributions_audit.sql (100%) rename db/scripts/audit/{ => tables}/create_vbms_uploaded_documents_audit.rb (100%) rename db/scripts/audit/{ => tables}/create_vbms_uploaded_documents_audit.sql (100%) rename db/scripts/audit/{ => triggers}/create_appeal_states_audit_trigger.rb (100%) rename db/scripts/audit/{ => triggers}/create_appeal_states_audit_trigger.sql (100%) rename db/scripts/audit/{ => triggers}/create_vbms_communication_packages_audit_trigger.rb (100%) rename db/scripts/audit/{ => triggers}/create_vbms_communication_packages_audit_trigger.sql (100%) rename db/scripts/audit/{ => triggers}/create_vbms_distribution_destinations_audit_trigger.rb (100%) rename db/scripts/audit/{ => triggers}/create_vbms_distribution_destinations_audit_trigger.sql (100%) rename db/scripts/audit/{ => triggers}/create_vbms_distributions_audit_trigger.rb (100%) rename db/scripts/audit/{ => triggers}/create_vbms_distributions_audit_trigger.sql (100%) rename db/scripts/audit/{ => triggers}/create_vbms_uploaded_documents_audit_trigger.rb (100%) rename db/scripts/audit/{ => triggers}/create_vbms_uploaded_documents_audit_trigger.sql (100%) diff --git a/Makefile.example b/Makefile.example index 3b1b93b03ac..d174fd713a8 100644 --- a/Makefile.example +++ b/Makefile.example @@ -140,9 +140,9 @@ db: ## Connect to your dev postgres (caseflow) db audit: ## Create caseflow_audit schema, tables, and triggers in postgres bundle exec rails r db/scripts/audit/create_caseflow_audit_schema.rb - bundle exec rails r db/scripts/audit/create_appeal_states_audit.rb - bundle exec rails r db/scripts/audit/add_row_to_appeal_states_audit_table_function.rb - bundle exec rails r db/scripts/audit/create_appeal_states_audit_trigger.rb + bundle exec rails r db/scripts/audit/tables/create_appeal_states_audit.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb + bundle exec rails r db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb audit-remove: ## Remove caseflow_audit schema, tables and triggers in postgres bundle exec rails r db/scripts/audit/remove_caseflow_audit_schema.rb diff --git a/db/scripts/audit/add_row_to_appeal_states_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb similarity index 100% rename from db/scripts/audit/add_row_to_appeal_states_audit_table_function.rb rename to db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb diff --git a/db/scripts/audit/add_row_to_appeal_states_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql similarity index 100% rename from db/scripts/audit/add_row_to_appeal_states_audit_table_function.sql rename to db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql diff --git a/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb similarity index 100% rename from db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.rb rename to db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb diff --git a/db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql similarity index 100% rename from db/scripts/audit/add_row_to_vbms_communication_packages_audit_table_function.sql rename to db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql diff --git a/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb similarity index 100% rename from db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.rb rename to db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb diff --git a/db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql similarity index 100% rename from db/scripts/audit/add_row_to_vbms_distribution_destinations_audit_table_function.sql rename to db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql diff --git a/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb similarity index 100% rename from db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.rb rename to db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb diff --git a/db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql similarity index 100% rename from db/scripts/audit/add_row_to_vbms_distributions_audit_table_function.sql rename to db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql diff --git a/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb similarity index 100% rename from db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.rb rename to db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb diff --git a/db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql similarity index 100% rename from db/scripts/audit/add_row_to_vbms_uploaded_documents_audit_table_function.sql rename to db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql diff --git a/db/scripts/audit/create_appeal_states_audit.rb b/db/scripts/audit/tables/create_appeal_states_audit.rb similarity index 100% rename from db/scripts/audit/create_appeal_states_audit.rb rename to db/scripts/audit/tables/create_appeal_states_audit.rb diff --git a/db/scripts/audit/create_appeal_states_audit.sql b/db/scripts/audit/tables/create_appeal_states_audit.sql similarity index 100% rename from db/scripts/audit/create_appeal_states_audit.sql rename to db/scripts/audit/tables/create_appeal_states_audit.sql diff --git a/db/scripts/audit/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb similarity index 100% rename from db/scripts/audit/create_vbms_communication_packages_audit.rb rename to db/scripts/audit/tables/create_vbms_communication_packages_audit.rb diff --git a/db/scripts/audit/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql similarity index 100% rename from db/scripts/audit/create_vbms_communication_packages_audit.sql rename to db/scripts/audit/tables/create_vbms_communication_packages_audit.sql diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb similarity index 100% rename from db/scripts/audit/create_vbms_distribution_destinations_audit.rb rename to db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql similarity index 100% rename from db/scripts/audit/create_vbms_distribution_destinations_audit.sql rename to db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql diff --git a/db/scripts/audit/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb similarity index 100% rename from db/scripts/audit/create_vbms_distributions_audit.rb rename to db/scripts/audit/tables/create_vbms_distributions_audit.rb diff --git a/db/scripts/audit/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql similarity index 100% rename from db/scripts/audit/create_vbms_distributions_audit.sql rename to db/scripts/audit/tables/create_vbms_distributions_audit.sql diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb similarity index 100% rename from db/scripts/audit/create_vbms_uploaded_documents_audit.rb rename to db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit.sql b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql similarity index 100% rename from db/scripts/audit/create_vbms_uploaded_documents_audit.sql rename to db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql diff --git a/db/scripts/audit/create_appeal_states_audit_trigger.rb b/db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb similarity index 100% rename from db/scripts/audit/create_appeal_states_audit_trigger.rb rename to db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb diff --git a/db/scripts/audit/create_appeal_states_audit_trigger.sql b/db/scripts/audit/triggers/create_appeal_states_audit_trigger.sql similarity index 100% rename from db/scripts/audit/create_appeal_states_audit_trigger.sql rename to db/scripts/audit/triggers/create_appeal_states_audit_trigger.sql diff --git a/db/scripts/audit/create_vbms_communication_packages_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb similarity index 100% rename from db/scripts/audit/create_vbms_communication_packages_audit_trigger.rb rename to db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb diff --git a/db/scripts/audit/create_vbms_communication_packages_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql similarity index 100% rename from db/scripts/audit/create_vbms_communication_packages_audit_trigger.sql rename to db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb similarity index 100% rename from db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.rb rename to db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb diff --git a/db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql similarity index 100% rename from db/scripts/audit/create_vbms_distribution_destinations_audit_trigger.sql rename to db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql diff --git a/db/scripts/audit/create_vbms_distributions_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb similarity index 100% rename from db/scripts/audit/create_vbms_distributions_audit_trigger.rb rename to db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb diff --git a/db/scripts/audit/create_vbms_distributions_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql similarity index 100% rename from db/scripts/audit/create_vbms_distributions_audit_trigger.sql rename to db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb similarity index 100% rename from db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.rb rename to db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb diff --git a/db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql similarity index 100% rename from db/scripts/audit/create_vbms_uploaded_documents_audit_trigger.sql rename to db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql From c884b9214a7713d94ba5aed06f3ba314d221e592 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 25 Apr 2023 15:21:58 -0400 Subject: [PATCH 011/308] APPEALS-21142 migrations made for table edits, questions about doc_referenced attribute on table. FK migrations next. --- ...90059_change_vbms_distrobutions_to_vbms_distributions.rb | 5 +++++ ...bution_destinations_to_vbms_distribution_destinations.rb | 5 +++++ db/schema.rb | 6 +++--- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb create mode 100644 db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb diff --git a/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb b/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb new file mode 100644 index 00000000000..b3a34299575 --- /dev/null +++ b/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb @@ -0,0 +1,5 @@ +class ChangeVbmsDistrobutionsToVbmsDistributions < Caseflow::Migration + def change + safety_assured { rename_table :vbms_distrobutions, :vbms_distributions } + end +end diff --git a/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb b/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb new file mode 100644 index 00000000000..989cc72f2c1 --- /dev/null +++ b/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb @@ -0,0 +1,5 @@ +class ChangeVbmsDistrobutionDestinationsToVbmsDistributionDestinations < Caseflow::Migration + def change + safety_assured { rename_table :vbms_distrobution_destinations, :vbms_distribution_destinations } + end +end diff --git a/db/schema.rb b/db/schema.rb index 7c1a5d4842c..3878623bc06 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: 2023_04_25_171045) do +ActiveRecord::Schema.define(version: 2023_04_25_190546) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1797,7 +1797,7 @@ t.datetime "updated_at" end - create_table "vbms_distrobution_destinations", force: :cascade do |t| + create_table "vbms_distribution_destinations", force: :cascade do |t| t.string "address_line_1", null: false t.string "address_line_2", null: false t.string "address_line_3", null: false @@ -1818,7 +1818,7 @@ t.datetime "updated_at" end - create_table "vbms_distrobutions", force: :cascade do |t| + create_table "vbms_distributions", force: :cascade do |t| t.string "claimant_station_oc_jurisdiction", null: false t.datetime "created_at", null: false t.string "last_name", null: false From 6e0b0592d5eda0d4b1c381633a03096cf51e0105 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 26 Apr 2023 11:46:37 -0400 Subject: [PATCH 012/308] migrations for adding FKs to tables made. Not Ran. --- ...5628_add_foreign_keys_to_vbms_communication_packages.rb | 7 +++++++ ...0230426144408_add_foreign_keys_to_vbms_distrobutions.rb | 7 +++++++ ...7_add_foreign_keys_to_vbms_distrobution_destinations.rb | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb create mode 100644 db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb create mode 100644 db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb diff --git a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb new file mode 100644 index 00000000000..118cc245f6b --- /dev/null +++ b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb @@ -0,0 +1,7 @@ +class AddForeignKeysToVbmsCommunicationPackages < Caseflow::Migration + def change + add_reference :vbms_communication_packages, :vbms_uploaded_documents, foreign_key: true, null: false + add_reference :vbms_communication_packages, :created_by, foreign_key: { to_table: :users} + add_reference :vbms_communication_packages, :updated_by, foreign_key: { to_table: :users} + end +end diff --git a/db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb b/db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb new file mode 100644 index 00000000000..725c14d6d93 --- /dev/null +++ b/db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb @@ -0,0 +1,7 @@ +class AddForeignKeysToVbmsDistrobutions < Caseflow::Migration + def change + add_reference :vbms_distributions, :vbms_communication_packages, foreign_key: true, null: false + add_reference :vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false + add_reference :vbms_distributions, :updated_by, foreign_key: { to_table: :users} + end +end diff --git a/db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb b/db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb new file mode 100644 index 00000000000..e23f606fdea --- /dev/null +++ b/db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb @@ -0,0 +1,7 @@ +class AddForeignKeysToVbmsDistrobutionDestinations < Caseflow::Migration + def change + add_reference :vbms_distribution_destinations, :vbms_distributions, foreign_key: true, null: false + add_reference :vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false + add_reference :vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users} + end +end From b0c04ab67e39425c4bbbd11095123483de98460a Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 26 Apr 2023 11:57:25 -0400 Subject: [PATCH 013/308] migrations for adding FKs to tables made. Not Ran. correctly named --- ...=> 20230426155344_add_foreign_keys_to_vbms_distributions.rb} | 2 +- ...55534_add_foreign_keys_to_vbms_distribution_destinations.rb} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename db/migrate/{20230426144408_add_foreign_keys_to_vbms_distrobutions.rb => 20230426155344_add_foreign_keys_to_vbms_distributions.rb} (83%) rename db/migrate/{20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb => 20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb} (84%) diff --git a/db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb similarity index 83% rename from db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb rename to db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb index 725c14d6d93..6f45c8bfedb 100644 --- a/db/migrate/20230426144408_add_foreign_keys_to_vbms_distrobutions.rb +++ b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb @@ -1,4 +1,4 @@ -class AddForeignKeysToVbmsDistrobutions < Caseflow::Migration +class AddForeignKeysToVbmsDistributions < Caseflow::Migration def change add_reference :vbms_distributions, :vbms_communication_packages, foreign_key: true, null: false add_reference :vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false diff --git a/db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb similarity index 84% rename from db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb rename to db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb index e23f606fdea..ba1300bef61 100644 --- a/db/migrate/20230426144437_add_foreign_keys_to_vbms_distrobution_destinations.rb +++ b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb @@ -1,4 +1,4 @@ -class AddForeignKeysToVbmsDistrobutionDestinations < Caseflow::Migration +class AddForeignKeysToVbmsDistributionDestinations < Caseflow::Migration def change add_reference :vbms_distribution_destinations, :vbms_distributions, foreign_key: true, null: false add_reference :vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false From 783497bb39edff69f287c85d399a5a540b8b758f Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 26 Apr 2023 15:43:12 -0400 Subject: [PATCH 014/308] APPEALS-21142 safely_assured FK migrations. next step it to run them. --- ...95628_add_foreign_keys_to_vbms_communication_packages.rb | 6 +++--- ...20230426155344_add_foreign_keys_to_vbms_distributions.rb | 6 +++--- ...34_add_foreign_keys_to_vbms_distribution_destinations.rb | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb index 118cc245f6b..2622fe6a478 100644 --- a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb +++ b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb @@ -1,7 +1,7 @@ class AddForeignKeysToVbmsCommunicationPackages < Caseflow::Migration def change - add_reference :vbms_communication_packages, :vbms_uploaded_documents, foreign_key: true, null: false - add_reference :vbms_communication_packages, :created_by, foreign_key: { to_table: :users} - add_reference :vbms_communication_packages, :updated_by, foreign_key: { to_table: :users} + safety_assured { add_reference(:vbms_communication_packages, :vbms_uploaded_document, foreign_key: { to_table: :vbms_uploaded_documents}, null: false) } + saftey_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}), null: false } + saftey_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}) } end end diff --git a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb index 6f45c8bfedb..fe5c12613cd 100644 --- a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb +++ b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb @@ -1,7 +1,7 @@ class AddForeignKeysToVbmsDistributions < Caseflow::Migration def change - add_reference :vbms_distributions, :vbms_communication_packages, foreign_key: true, null: false - add_reference :vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false - add_reference :vbms_distributions, :updated_by, foreign_key: { to_table: :users} + safety_assured { add_reference(:vbms_distributions, :vbms_communication_package, foreign_key: { to_table: :vbms_communication_packages}, null: false) } + safety_assured { add_reference(:vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false) } + safety_assured { add_reference(:vbms_distributions, :updated_by, foreign_key: { to_table: :users} ) } end end diff --git a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb index ba1300bef61..f5b5ad9634f 100644 --- a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb +++ b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb @@ -1,7 +1,7 @@ class AddForeignKeysToVbmsDistributionDestinations < Caseflow::Migration def change - add_reference :vbms_distribution_destinations, :vbms_distributions, foreign_key: true, null: false - add_reference :vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false - add_reference :vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users} + safety_assured { add_reference(:vbms_distribution_destinations, :vbms_distribution, foreign_key: {to_table: :vbms_distrobutions} , null: false) } + safety_assured { add_reference(:vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false) } + safety_assured { add_reference(:vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users}) } end end From 6de11cf7cc68b1e9298a731225fbf11669fe5152 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 26 Apr 2023 15:45:28 -0400 Subject: [PATCH 015/308] APPEALS-21142 spelling errors. --- ...5195628_add_foreign_keys_to_vbms_communication_packages.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb index 2622fe6a478..08d15727842 100644 --- a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb +++ b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb @@ -1,7 +1,7 @@ class AddForeignKeysToVbmsCommunicationPackages < Caseflow::Migration def change safety_assured { add_reference(:vbms_communication_packages, :vbms_uploaded_document, foreign_key: { to_table: :vbms_uploaded_documents}, null: false) } - saftey_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}), null: false } - saftey_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}) } + safety_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}, null: false) } + safety_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}) } end end From 4095f13800a49379f94db007ce90b86ef62b9617 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 27 Apr 2023 10:30:43 -0400 Subject: [PATCH 016/308] APPEALS-21142 made corrections to model relationships and added safe indexing to new migrations. --- app/models/vbms_communication_package.rb | 4 ++-- app/models/vbms_distribution.rb | 6 ++++++ app/models/vbms_distribution_destination.rb | 6 ++++++ app/models/vbms_distrobution.rb | 6 ------ app/models/vbms_distrobution_destination.rb | 5 ----- ..._add_foreign_keys_to_vbms_communication_packages.rb | 10 +++++++--- ...426155344_add_foreign_keys_to_vbms_distributions.rb | 10 +++++++--- ...d_foreign_keys_to_vbms_distribution_destinations.rb | 10 +++++++--- 8 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 app/models/vbms_distribution.rb create mode 100644 app/models/vbms_distribution_destination.rb delete mode 100644 app/models/vbms_distrobution.rb delete mode 100644 app/models/vbms_distrobution_destination.rb diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 1cc7b2a7798..9bbe09b0eb5 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - belongs_to :vbms_uploaded_document - has_many :vbms_distributions + has_one :vbms_uploaded_document + belongs_to :vbms_distributions end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb new file mode 100644 index 00000000000..a6639310ac0 --- /dev/null +++ b/app/models/vbms_distribution.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class VbmsDistribution < CaseflowRecord + has_one :vbms_communication_package + has_many :vbms_distribution_destinations +end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb new file mode 100644 index 00000000000..c85f292c3b8 --- /dev/null +++ b/app/models/vbms_distribution_destination.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class VbmsDistributionDestination < CaseflowRecord + belongs_to :vbms_distributions +end + diff --git a/app/models/vbms_distrobution.rb b/app/models/vbms_distrobution.rb deleted file mode 100644 index 4458cff5621..00000000000 --- a/app/models/vbms_distrobution.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -class VbmsDistrobution < CaseflowRecord - belongs_to :vbms_communication_package - has_many :vbms_distribution_destinations -end diff --git a/app/models/vbms_distrobution_destination.rb b/app/models/vbms_distrobution_destination.rb deleted file mode 100644 index ab8e53f6f87..00000000000 --- a/app/models/vbms_distrobution_destination.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class VbmsDistrobutionDestination < CaseflowRecord - belongs_to :vbms_distribution -end diff --git a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb index 08d15727842..7d701819b09 100644 --- a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb +++ b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb @@ -1,7 +1,11 @@ class AddForeignKeysToVbmsCommunicationPackages < Caseflow::Migration def change - safety_assured { add_reference(:vbms_communication_packages, :vbms_uploaded_document, foreign_key: { to_table: :vbms_uploaded_documents}, null: false) } - safety_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}, null: false) } - safety_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}) } + safety_assured { add_reference(:vbms_communication_packages, :vbms_uploaded_document, foreign_key: { to_table: :vbms_uploaded_documents}, null: false, index: false) } + safety_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } + safety_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}, index: false) } + + add_safe_index :vbms_communication_packages, :vbms_uploaded_document_id, algorithm: :concurrently + add_safe_index :vbms_communication_packages, :created_by_id, algorithm: :concurrently + add_safe_index :vbms_communication_packages, :updated_by_id, algorithm: :concurrently end end diff --git a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb index fe5c12613cd..640a02ff261 100644 --- a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb +++ b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb @@ -1,7 +1,11 @@ class AddForeignKeysToVbmsDistributions < Caseflow::Migration def change - safety_assured { add_reference(:vbms_distributions, :vbms_communication_package, foreign_key: { to_table: :vbms_communication_packages}, null: false) } - safety_assured { add_reference(:vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false) } - safety_assured { add_reference(:vbms_distributions, :updated_by, foreign_key: { to_table: :users} ) } + safety_assured { add_reference(:vbms_distributions, :vbms_communication_package, foreign_key: { to_table: :vbms_communication_packages}, null: false, index: false) } + safety_assured { add_reference(:vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } + safety_assured { add_reference(:vbms_distributions, :updated_by, foreign_key: { to_table: :users}, index: false) } + + add_safe_index :vbms_distributions, :vbms_communication_package_id, algorithm: :concurrently + add_safe_index :vbms_distributions, :created_by_id, algorithm: :concurrently + add_safe_index :vbms_distributions, :updated_by_id, algorithm: :concurrently end end diff --git a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb index f5b5ad9634f..3de8370fb41 100644 --- a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb +++ b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb @@ -1,7 +1,11 @@ class AddForeignKeysToVbmsDistributionDestinations < Caseflow::Migration def change - safety_assured { add_reference(:vbms_distribution_destinations, :vbms_distribution, foreign_key: {to_table: :vbms_distrobutions} , null: false) } - safety_assured { add_reference(:vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false) } - safety_assured { add_reference(:vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users}) } + safety_assured { add_reference(:vbms_distribution_destinations, :vbms_distribution, foreign_key: {to_table: :vbms_distrobutions} , null: false, index: false) } + safety_assured { add_reference(:vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } + safety_assured { add_reference(:vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users}, index: false) } + + add_safe_index :vbms_distribution_destinations, :vbms_distribution_id, algorithm: :concurrently + add_safe_index :vbms_distribution_destinations, :created_by_id, algorithm: :concurrently + add_safe_index :vbms_distribution_destinations, :updated_by_id, algorithm: :concurrently end end From 3607216b40b8809e895c258d2400d7d83c10bf6a Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 27 Apr 2023 11:46:18 -0400 Subject: [PATCH 017/308] APPEALS-21142 consolidated migrations and schema matches feature branch at this point in time. Next running migrations to created tables for the newly created models. --- app/models/vbms_communication_package.rb | 4 +- app/models/vbms_distribution.rb | 4 +- app/models/vbms_distribution_destination.rb | 2 +- db/etl/schema.rb | 4 +- ...0230425144000_create_pacman_integration.rb | 55 +++++++++++++++++++ ...4000_create_vbms_communication_packages.rb | 11 ---- ...0230425151524_create_vbms_distrobutions.rb | 15 ----- ...4013_change_vbms_communication_packages.rb | 5 -- ...5_create_vbms_distrobution_destinations.rb | 24 -------- ...bms_distrobutions_to_vbms_distributions.rb | 5 -- ...tions_to_vbms_distribution_destinations.rb | 5 -- ...ign_keys_to_vbms_communication_packages.rb | 11 ---- ..._add_foreign_keys_to_vbms_distributions.rb | 11 ---- ..._keys_to_vbms_distribution_destinations.rb | 11 ---- db/schema.rb | 44 +-------------- 15 files changed, 63 insertions(+), 148 deletions(-) create mode 100644 db/migrate/20230425144000_create_pacman_integration.rb delete mode 100644 db/migrate/20230425144000_create_vbms_communication_packages.rb delete mode 100644 db/migrate/20230425151524_create_vbms_distrobutions.rb delete mode 100644 db/migrate/20230425154013_change_vbms_communication_packages.rb delete mode 100644 db/migrate/20230425171045_create_vbms_distrobution_destinations.rb delete mode 100644 db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb delete mode 100644 db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb delete mode 100644 db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb delete mode 100644 db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb delete mode 100644 db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 9bbe09b0eb5..296fc7673f0 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - has_one :vbms_uploaded_document - belongs_to :vbms_distributions + # has_one :vbms_uploaded_document + # belongs_to :vbms_distributions end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index a6639310ac0..7bca783cc7f 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - has_one :vbms_communication_package - has_many :vbms_distribution_destinations + # has_one :vbms_communication_package + # has_many :vbms_distribution_destinations end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index c85f292c3b8..044227eeeec 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - belongs_to :vbms_distributions + # belongs_to :vbms_distributions end diff --git a/db/etl/schema.rb b/db/etl/schema.rb index d487e01680c..ffbf660a2ef 100644 --- a/db/etl/schema.rb +++ b/db/etl/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_01_10_143457) do +ActiveRecord::Schema.define(version: 2022_01_07_125705) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,7 +42,7 @@ t.datetime "established_at", null: false, comment: "Timestamp for when the appeal was intaken successfully" t.boolean "legacy_opt_in_approved", comment: "Indicates whether a Veteran opted to withdraw matching issues from the legacy process. If there is a matching legacy issue and it is not withdrawn then it is ineligible for the decision review." t.string "poa_participant_id", limit: 20, comment: "Used to identify the power of attorney (POA)" - t.date "receipt_date", comment: "Receipt date of the NOD form" + t.date "receipt_date", null: false, comment: "Receipt date of the NOD form" t.string "status", limit: 32, null: false, comment: "Calculated BVA status based on Tasks" t.date "target_decision_date", comment: "If the appeal docket is direct review, this sets the target decision date for the appeal, which is one year after the receipt date." t.datetime "updated_at", null: false, comment: "Updated timestamp for the ETL record" diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb new file mode 100644 index 00000000000..c3679d83eb0 --- /dev/null +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -0,0 +1,55 @@ +class CreatePacmanIntegration < Caseflow::Migration + def change + create_table :vbms_communication_packages do |t| + t.string :file_number + t.bigint :document_referenced, default: [], array: true + t.string :status + t.string :comm_package_name, null: false + t.timestamps + + t.references :vbms_uploaded_document, index: true, foreign_key: { to_table: :vbms_uploaded_documents } + t.references :created_by , index: true, foreign_key: { to_table: :users } + t.references :updated_by, index: true, foreign_key: { to_table: :users } + end + + create_table :vbms_distributions do |t| + t.string :type, null: false + t.string :name, null: false + t.string :middle_name + t.string :last_name, null: false + t.string :participant_id + t.string :poa_code, null: false + t.string :claimant_station_of_jurisdiction, null: false + t.timestamps + + t.references :vbms_communication_package, index: true, foreign_key: { to_table: :vbms_communication_packages } + t.references :created_by , index: true, foreign_key: { to_table: :users } + t.references :updated_by, index: true, foreign_key: { to_table: :users } + + end + + create_table :vbms_distribution_destinations do |t| + t.string :type, null: false + t.string :address_line_1, null: false + t.string :address_line_2, null: false + t.string :address_line_3, null: false + t.string :address_line_4 + t.string :address_line_5 + t.string :address_line_6 + t.boolean :treat_line_2_as_addressee, null: false + t.boolean :treat_line_3_as_addressee + t.string :city, null: false + t.string :state, null: false + t.string :postal_code, null: false + t.string :country_name, null: false + t.string :country_code, null: false + t.string :email_address, null: false + t.string :phone_number, null: false + t.timestamps + + t.references :vbms_distribution, index: true, foreign_key: { to_table: :vbms_distributions } + t.references :created_by , index: true, foreign_key: { to_table: :users } + t.references :updated_by, index: true, foreign_key: { to_table: :users } + end + end +end diff --git a/db/migrate/20230425144000_create_vbms_communication_packages.rb b/db/migrate/20230425144000_create_vbms_communication_packages.rb deleted file mode 100644 index 3842d073ca6..00000000000 --- a/db/migrate/20230425144000_create_vbms_communication_packages.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateVbmsCommunicationPackages < Caseflow::Migration - def change - create_table :vbms_communication_packages do |t| - t.string :file_number - t.bigint :document_referenced, default: [], array: true - t.string :status - t.string :comm_package_name, null: false - t.timestamps - end - end -end diff --git a/db/migrate/20230425151524_create_vbms_distrobutions.rb b/db/migrate/20230425151524_create_vbms_distrobutions.rb deleted file mode 100644 index 142132771c5..00000000000 --- a/db/migrate/20230425151524_create_vbms_distrobutions.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateVbmsDistrobutions < Caseflow::Migration - def change - create_table :vbms_distrobutions do |t| - t.string :type, null: false - t.string :name, null: false - t.string :middle_name - t.string :last_name, null: false - t.string :participant_id - t.string :poa_code, null: false - t.string :claimant_station_oc_jurisdiction, null: false - t.timestamp :created_at, null: false - t.timestamp :updated_at - end - end -end diff --git a/db/migrate/20230425154013_change_vbms_communication_packages.rb b/db/migrate/20230425154013_change_vbms_communication_packages.rb deleted file mode 100644 index c0ae1770b27..00000000000 --- a/db/migrate/20230425154013_change_vbms_communication_packages.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ChangeVbmsCommunicationPackages < Caseflow::Migration - def change - change_column_null(:vbms_communication_packages, :updated_at, true) - end -end diff --git a/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb b/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb deleted file mode 100644 index 2bbf4b1c967..00000000000 --- a/db/migrate/20230425171045_create_vbms_distrobution_destinations.rb +++ /dev/null @@ -1,24 +0,0 @@ -class CreateVbmsDistrobutionDestinations < Caseflow::Migration - def change - create_table :vbms_distrobution_destinations do |t| - t.string :type, null: false - t.string :address_line_1, null: false - t.string :address_line_2, null: false - t.string :address_line_3, null: false - t.string :address_line_4 - t.string :address_line_5 - t.string :address_line_6 - t.boolean :treat_line_2_as_addressee, null: false - t.boolean :treat_line_3_as_addressee - t.string :city, null: false - t.string :state, null: false - t.string :postal_code, null: false - t.string :country_name, null: false - t.string :country_code, null: false - t.string :email_address, null: false - t.string :phone_number, null: false - t.timestamp :created_at, null: false - t.timestamp :updated_at - end - end -end diff --git a/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb b/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb deleted file mode 100644 index b3a34299575..00000000000 --- a/db/migrate/20230425190059_change_vbms_distrobutions_to_vbms_distributions.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ChangeVbmsDistrobutionsToVbmsDistributions < Caseflow::Migration - def change - safety_assured { rename_table :vbms_distrobutions, :vbms_distributions } - end -end diff --git a/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb b/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb deleted file mode 100644 index 989cc72f2c1..00000000000 --- a/db/migrate/20230425190546_change_vbms_distrobution_destinations_to_vbms_distribution_destinations.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ChangeVbmsDistrobutionDestinationsToVbmsDistributionDestinations < Caseflow::Migration - def change - safety_assured { rename_table :vbms_distrobution_destinations, :vbms_distribution_destinations } - end -end diff --git a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb b/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb deleted file mode 100644 index 7d701819b09..00000000000 --- a/db/migrate/20230425195628_add_foreign_keys_to_vbms_communication_packages.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddForeignKeysToVbmsCommunicationPackages < Caseflow::Migration - def change - safety_assured { add_reference(:vbms_communication_packages, :vbms_uploaded_document, foreign_key: { to_table: :vbms_uploaded_documents}, null: false, index: false) } - safety_assured { add_reference(:vbms_communication_packages, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } - safety_assured { add_reference(:vbms_communication_packages, :updated_by, foreign_key: { to_table: :users}, index: false) } - - add_safe_index :vbms_communication_packages, :vbms_uploaded_document_id, algorithm: :concurrently - add_safe_index :vbms_communication_packages, :created_by_id, algorithm: :concurrently - add_safe_index :vbms_communication_packages, :updated_by_id, algorithm: :concurrently - end -end diff --git a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb b/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb deleted file mode 100644 index 640a02ff261..00000000000 --- a/db/migrate/20230426155344_add_foreign_keys_to_vbms_distributions.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddForeignKeysToVbmsDistributions < Caseflow::Migration - def change - safety_assured { add_reference(:vbms_distributions, :vbms_communication_package, foreign_key: { to_table: :vbms_communication_packages}, null: false, index: false) } - safety_assured { add_reference(:vbms_distributions, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } - safety_assured { add_reference(:vbms_distributions, :updated_by, foreign_key: { to_table: :users}, index: false) } - - add_safe_index :vbms_distributions, :vbms_communication_package_id, algorithm: :concurrently - add_safe_index :vbms_distributions, :created_by_id, algorithm: :concurrently - add_safe_index :vbms_distributions, :updated_by_id, algorithm: :concurrently - end -end diff --git a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb b/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb deleted file mode 100644 index 3de8370fb41..00000000000 --- a/db/migrate/20230426155534_add_foreign_keys_to_vbms_distribution_destinations.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddForeignKeysToVbmsDistributionDestinations < Caseflow::Migration - def change - safety_assured { add_reference(:vbms_distribution_destinations, :vbms_distribution, foreign_key: {to_table: :vbms_distrobutions} , null: false, index: false) } - safety_assured { add_reference(:vbms_distribution_destinations, :created_by, foreign_key: { to_table: :users}, null: false, index: false) } - safety_assured { add_reference(:vbms_distribution_destinations, :updated_by, foreign_key: { to_table: :users}, index: false) } - - add_safe_index :vbms_distribution_destinations, :vbms_distribution_id, algorithm: :concurrently - add_safe_index :vbms_distribution_destinations, :created_by_id, algorithm: :concurrently - add_safe_index :vbms_distribution_destinations, :updated_by_id, algorithm: :concurrently - end -end diff --git a/db/schema.rb b/db/schema.rb index 3878623bc06..eafc2b8ab21 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: 2023_04_25_190546) do +ActiveRecord::Schema.define(version: 2023_03_17_164013) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1788,48 +1788,6 @@ t.index ["updated_at"], name: "index_users_on_updated_at" end - create_table "vbms_communication_packages", force: :cascade do |t| - t.string "comm_package_name", null: false - t.datetime "created_at", null: false - t.bigint "document_referenced", default: [], array: true - t.string "file_number" - t.string "status" - t.datetime "updated_at" - end - - create_table "vbms_distribution_destinations", force: :cascade do |t| - t.string "address_line_1", null: false - t.string "address_line_2", null: false - t.string "address_line_3", null: false - t.string "address_line_4" - t.string "address_line_5" - t.string "address_line_6" - t.string "city", null: false - t.string "country_code", null: false - t.string "country_name", null: false - t.datetime "created_at", null: false - t.string "email_address", null: false - t.string "phone_number", null: false - t.string "postal_code", null: false - t.string "state", null: false - t.boolean "treat_line_2_as_addressee", null: false - t.boolean "treat_line_3_as_addressee" - t.string "type", null: false - t.datetime "updated_at" - end - - create_table "vbms_distributions", force: :cascade do |t| - t.string "claimant_station_oc_jurisdiction", null: false - t.datetime "created_at", null: false - t.string "last_name", null: false - t.string "middle_name" - t.string "name", null: false - t.string "participant_id" - t.string "poa_code", null: false - t.string "type", null: false - t.datetime "updated_at" - end - create_table "vbms_uploaded_documents", force: :cascade do |t| t.bigint "appeal_id", comment: "Appeal/LegacyAppeal ID; use as FK to appeals/legacy_appeals" t.string "appeal_type", comment: "'Appeal' or 'LegacyAppeal'" From de2d02e109d9244a23409f1f5da118a314246321 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 27 Apr 2023 11:52:27 -0400 Subject: [PATCH 018/308] uncommented relationship syntax in models --- app/models/vbms_communication_package.rb | 4 ++-- app/models/vbms_distribution.rb | 4 ++-- app/models/vbms_distribution_destination.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 296fc7673f0..9bbe09b0eb5 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - # has_one :vbms_uploaded_document - # belongs_to :vbms_distributions + has_one :vbms_uploaded_document + belongs_to :vbms_distributions end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 7bca783cc7f..a6639310ac0 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - # has_one :vbms_communication_package - # has_many :vbms_distribution_destinations + has_one :vbms_communication_package + has_many :vbms_distribution_destinations end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 044227eeeec..c85f292c3b8 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - # belongs_to :vbms_distributions + belongs_to :vbms_distributions end From 257feca2f1780edf316d238b428e61bd7a6272bf Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 1 May 2023 10:26:29 -0400 Subject: [PATCH 019/308] created the file for vbms_comm_package_spec. --- spec/models/vbms_communication_package_spec.rb | 1 + 1 file changed, 1 insertion(+) create mode 100644 spec/models/vbms_communication_package_spec.rb diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb new file mode 100644 index 00000000000..8e9b8f90fa4 --- /dev/null +++ b/spec/models/vbms_communication_package_spec.rb @@ -0,0 +1 @@ +# frozen_string_literal: true From 3ec42f332da27c7d1372613469f20699b50d5ff2 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 1 May 2023 11:40:04 -0400 Subject: [PATCH 020/308] created test files for all newly created models. --- spec/models/vbms_communication_package_spec.rb | 4 ++++ spec/models/vbms_distribution_destination_spec.rb | 5 +++++ spec/models/vbms_distribution_spec.rb | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 spec/models/vbms_distribution_destination_spec.rb create mode 100644 spec/models/vbms_distribution_spec.rb diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 8e9b8f90fa4..ba47c52555f 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -1 +1,5 @@ # frozen_string_literal: true + +describe VbmsCommunicationPackage, :postgres do + +end diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb new file mode 100644 index 00000000000..3d9e41d2146 --- /dev/null +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +describe VbmsDistributionDestination, :postgres do + +end diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb new file mode 100644 index 00000000000..8e9f7c15fa2 --- /dev/null +++ b/spec/models/vbms_distribution_spec.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +describe VbmsDistribution, :postgres do + +end From e196a97eb2d77c3e3669ecf0953a86e814c567c3 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 1 May 2023 14:27:37 -0400 Subject: [PATCH 021/308] APPEALS-21142 fixed etl-schema rollback issue in branch in order to avoid pushing schema changes to branch. --- db/etl/schema.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/etl/schema.rb b/db/etl/schema.rb index ffbf660a2ef..d487e01680c 100644 --- a/db/etl/schema.rb +++ b/db/etl/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_01_07_125705) do +ActiveRecord::Schema.define(version: 2022_01_10_143457) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,7 +42,7 @@ t.datetime "established_at", null: false, comment: "Timestamp for when the appeal was intaken successfully" t.boolean "legacy_opt_in_approved", comment: "Indicates whether a Veteran opted to withdraw matching issues from the legacy process. If there is a matching legacy issue and it is not withdrawn then it is ineligible for the decision review." t.string "poa_participant_id", limit: 20, comment: "Used to identify the power of attorney (POA)" - t.date "receipt_date", null: false, comment: "Receipt date of the NOD form" + t.date "receipt_date", comment: "Receipt date of the NOD form" t.string "status", limit: 32, null: false, comment: "Calculated BVA status based on Tasks" t.date "target_decision_date", comment: "If the appeal docket is direct review, this sets the target decision date for the appeal, which is one year after the receipt date." t.datetime "updated_at", null: false, comment: "Updated timestamp for the ETL record" From 666ca017bf9ddd91b32ccc98b5bc0a782e8a8857 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 2 May 2023 10:03:55 -0400 Subject: [PATCH 022/308] APPEALS-21120 created files for service and fake --- app/services/external_api/pacman_service.rb | 109 ++++++++++++ .../external_api/pacman_service/response.rb | 54 ++++++ config/environments/test.rb | 2 + db/schema.rb | 7 +- lib/caseflow/error.rb | 6 + lib/fakes/pacman_service.rb | 164 ++++++++++++++++++ 6 files changed, 338 insertions(+), 4 deletions(-) create mode 100644 app/services/external_api/pacman_service.rb create mode 100644 app/services/external_api/pacman_service/response.rb create mode 100644 lib/fakes/pacman_service.rb diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb new file mode 100644 index 00000000000..f7d0255f7ec --- /dev/null +++ b/app/services/external_api/pacman_service.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +class ExternalApi::PacManService + BASE_URL = ENV["PACMAN_API_URL"] + SEND_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution" + SEND_PACKAGE_ENDPOINT = "package-manager-service/communication-package" + GET_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution/" + + class << self + def send_communication_package_request(file_number, name, document_references:) + document_references.each do |document_reference| + request = package_request(file_number, name, document_reference) + send_pacman_request(request) + end + end + + def send_distribution_request(package_id, recipient, destinations:) + destinations.each do |destination| + request = distribution_request(package_id, recipient, destination) + send_pacman_request(request) + end + end + + def get_distribution_request(distribution_id) + request = { + endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get + } + send_pacman_request(request) + end + + def package_request(file_number, name, document_reference) + request = { + body: { + fileNumber: file_number, + name: name, + documentReferences: { + id: document_reference[:id], + copies: document_reference[:copies] + } + }, + headers: HEADERS, + endpoint: SEND_PACKAGE_ENDPOINT, method: :post + } + request + end + + def distribution_request(package_id, recipient, destination) + request = { + body: { + communicationPackageId: package_id, + recipient: { + type: recipient.type, + name: recipient.name, + firstName: recipient.first_name, + middleName: recipient.middle_name, + lastName: recipient.last_name, + participant_id: recipient.participant_id, + poaCode: recipient.poa_code, + claimantStationOfJurisdiction: recipient.claimant_station_of_jurisdiction + }, + destinations: { + type: destination[:type], + addressLine1: destination[:addressLine1], + addressLine2: destination[:addressLine2], + addressLine3: destination[:addressLine3], + addressLine4: destination[:addressLine4], + addressLine5: destination[:addressLine5], + addressLine6: destination[:addressLine6], + treatLine2AsAddressee: destination[:treatLine2AsAddressee], + treatLine3AsAddressee: destination[:treatLine3AsAddressee], + city: destination[:city], + state: destination[:state], + postalCode: destination[:postalCode], + countryName: destination[:countryName], + emailAddress: destination[:emailAddress], + phoneNumber: destination[:phoneNumber] + } + }, + headers: HEADERS, + endpoint: SEND_PACKAGE_ENDPOINT, method: :post + } + request + end + + def send_pacman_request(query: {}, headers: {}, endpoint:, method: :get, body: nil) + url = URI.escape(BASE_URL + endpoint) + request = HTTPI::Request.new(url) + request.query = query + request.open_timeout = 30 + request.read_timeout = 30 + request.body = body.to_json unless body.nil? + # not sure how user validation will be handled + request.headers = headers.merge(apikey: ENV["PACMAN_API_KEY"]) + sleep 1 + + # FIXME idk what the url is + MetricsService.record("pacman #{method.to_s.upcase} request to #{url}", + service: :va_dot_gov, + name: endpoint) do + case method + when :get + HTTPI.get(request) + when :post + HTTPI.post(request) + end + end + end + end +end diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb new file mode 100644 index 00000000000..53952d090ba --- /dev/null +++ b/app/services/external_api/pacman_service/response.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +class ExternalApi::PacManService::Response + attr_reader :resp, :code + + def initialize(resp) + @resp = resp + @code = @resp.code + end + + def data; end + + def error + check_for_error + end + + def success? + !resp.error? + end + + def body + @body ||= begin + JSON.parse(resp.body) + rescue JSON::ParserError + {} + end + end + + private + + ERROR_LOOKUP = { + 400 => Caseflow::Error::PacManBadRequestError, + 403 => Caseflow::Error::PacManForbiddenError, + 404 => Caseflow::Error::PacManNotFoundError + }.freeze + + def check_for_error + return if success? + + message = error_message + + if ERROR_LOOKUP.key? code + ERROR_LOOKUP[code].new(code: code, message: message) + else + Caseflow::Error::PacManApiError.new(code: code, message: message) + end + end + + def error_message + return "No error message from PacMan" if body.empty? + + body&.error || "No error message from PacMan" + end +end diff --git a/config/environments/test.rb b/config/environments/test.rb index 739eeb2b3fb..856e2c97b21 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -112,4 +112,6 @@ ENV["CLAIM_EVIDENCE_EFOLDER_BASE_URL"] ||= "https://vefs-claimevidence-ui-uat.stage8.bip.va.gov" ENV['TEST_VACOLS_HOST'] ||= "localhost" + + ENV['PACMAN_API_URL'] ||= "who knows" end diff --git a/db/schema.rb b/db/schema.rb index a3711114e08..eafc2b8ab21 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -91,7 +91,7 @@ t.boolean "appeal_docketed", default: false, null: false, comment: "When true, appeal has been docketed" t.bigint "appeal_id", null: false, comment: "AMA or Legacy Appeal ID" t.string "appeal_type", null: false, comment: "Appeal Type (Appeal or LegacyAppeal)" - t.datetime "created_at", null: false + t.datetime "created_at", null: false, comment: "Date and Time the record was inserted into the table" t.bigint "created_by_id", null: false, comment: "User id of the user that inserted the record" t.boolean "decision_mailed", default: false, null: false, comment: "When true, appeal has decision mail request complete" t.boolean "hearing_postponed", default: false, null: false, comment: "When true, appeal has hearing postponed and no hearings scheduled" @@ -100,7 +100,7 @@ t.boolean "privacy_act_complete", default: false, null: false, comment: "When true, appeal has a privacy act request completed" t.boolean "privacy_act_pending", default: false, null: false, comment: "When true, appeal has a privacy act request still open" t.boolean "scheduled_in_error", default: false, null: false, comment: "When true, hearing was scheduled in error and none scheduled" - t.datetime "updated_at" + t.datetime "updated_at", comment: "Date and time the record was last updated" t.bigint "updated_by_id", comment: "User id of the last user that updated the record" t.boolean "vso_ihp_complete", default: false, null: false, comment: "When true, appeal has a VSO IHP request completed" t.boolean "vso_ihp_pending", default: false, null: false, comment: "When true, appeal has a VSO IHP request pending" @@ -1275,7 +1275,7 @@ t.string "recipient_email", comment: "Participant's Email Address" t.string "recipient_phone_number", comment: "Participants Phone Number" t.text "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_external_id" t.string "sms_notification_status", comment: "Status of SMS/Text Notification" 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" @@ -1577,7 +1577,6 @@ t.boolean "national_cemetery_administration", default: false t.boolean "no_special_issues", default: false, comment: "Affirmative no special issues, added belatedly" t.boolean "nonrating_issue", default: false - t.boolean "pact_act", default: false, comment: "The Sergeant First Class (SFC) Heath Robinson Honoring our Promise to Address Comprehensive Toxics (PACT) Act" t.boolean "pension_united_states", default: false t.boolean "private_attorney_or_agent", default: false t.boolean "radiation", default: false diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index cc884eb3af4..40cc7f4bdd6 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -447,4 +447,10 @@ class VANotifyNotFoundError < VANotifyApiError; end class VANotifyInternalServerError < VANotifyApiError; end class VANotifyRateLimitError < VANotifyApiError; end class EmptyQueueError < StandardError; end + + # PacMan errors + class PacManApiError < StandardError; end + class PacManBadRequestError < PacManApiError; end + class PacManForbiddenError < PacManApiError; end + class PacManNotFoundError < PacManApiError; end end diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb new file mode 100644 index 00000000000..ac871818cef --- /dev/null +++ b/lib/fakes/pacman_service.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +class Fakes::PacmanService < ExternalApi::PacmanService + class << self + def send_communication_package_request(file_number, name, document_references:) + document_references.each do |document_reference| + request = package_request(file_number, name, document_reference) + fake_package_request(request) + end + end + + def send_distribution_request(package_id, recipient, destinations:) + destinations.each do |destination| + request = distribution_request(package_id, recipient, destination) + fake_distribution_request(request) + end + end + + def get_distribution_request(distribution_id) + request = { + endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get + } + fake_distribution_response(request) + end + + private + + def bad_request_response + HTTPI::Response.new( + 400, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "participant id is not valid" + ) + ) + end + + def bad_access_response + HTTPI::Response.new( + 403, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "package cannot be created because of insufficient privileges" + ) + ) + end + + def distribution_not_found_response + HTTPI::Response.new( + 404, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "distribution does not exist at this time" + ) + ) + end + + def fake_package_request + HTTPI::Response.new( + 200, + {}, + OpenStruct.new( + "id": "", + "fileNumber": "073-claimant-appeal-file-number", + "name": "name", + "documentReferences": { + "id": "123", + "copies": 2 + }, + "status": "", + "createdDate": "", + "name": "" + ) + ) + end + + # rubocop:disable Metrics/MethodLength + def fake_distribution_request + HTTPI::Response.new( + 200, + {}, + OpenStruct.new( + "id": package_id, + "recipient": { + "type": recipient.type, + "name": recipient.name, + "firstName": recipient.first_name, + "middleName": recipient.middle_name, + "lastName": recipient.last_name, + "participant_id": recipient.participant_id, + "poaCode": recipient.poa_code, + "claimantStationOfJurisdiction": recipient.claimant_station_of_jurisdiction + }, + "description": "bad", + "communicationPackageId": "", + "destinations": { + "type": destination[:type], + "addressLine1": destination[:addressLine1], + "addressLine2": destination[:addressLine2], + "addressLine3": destination[:addressLine3], + "addressLine4": destination[:addressLine4], + "addressLine5": destination[:addressLine5], + "addressLine6": destination[:addressLine6], + "treatLine2AsAddressee": destination[:treatLine2AsAddressee], + "treatLine3AsAddressee": destination[:treatLine3AsAddressee], + "city": destination[:city], + "state": destination[:state], + "postalCode": destination[:postalCode], + "countryName": destination[:countryName], + "emailAddress": destination[:emailAddress], + "phoneNumber": destination[:phoneNumber] + }, + "status": "", + "sentToCbcmDate": "" + ) + ) + end + # rubocop:enable Metrics/MethodLength + + def fake_distribution_response(distribution_id) + HTTPI::Response.new( + 200, + {}, + OpenStruct.new( + "id": package_id, + "recipient": { + "type": recipient.type, + "name": recipient.name, + "firstName": recipient.first_name, + "middleName": recipient.middle_name, + "lastName": recipient.last_name, + "participant_id": recipient.participant_id, + "poaCode": recipient.poa_code, + "claimantStationOfJurisdiction": recipient.claimant_station_of_jurisdiction + }, + "description": "bad", + "communicationPackageId": "", + "destinations": { + "type": destination[:type], + "addressLine1": destination[:addressLine1], + "addressLine2": destination[:addressLine2], + "addressLine3": destination[:addressLine3], + "addressLine4": destination[:addressLine4], + "addressLine5": destination[:addressLine5], + "addressLine6": destination[:addressLine6], + "treatLine2AsAddressee": destination[:treatLine2AsAddressee], + "treatLine3AsAddressee": destination[:treatLine3AsAddressee], + "city": destination[:city], + "state": destination[:state], + "postalCode": destination[:postalCode], + "countryName": destination[:countryName], + "emailAddress": destination[:emailAddress], + "phoneNumber": destination[:phoneNumber] + }, + "status": "", + "sentToCbcmDate": "" + ) + ) + end + end +end From ab2475917da8cbfade8c8e038ba9cf9c644f969d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 2 May 2023 12:46:26 -0400 Subject: [PATCH 023/308] APPEALS-21120 updated fake --- lib/fakes/pacman_service.rb | 99 ++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index ac871818cef..279c4300f09 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -65,14 +65,13 @@ def fake_package_request OpenStruct.new( "id": "", "fileNumber": "073-claimant-appeal-file-number", - "name": "name", "documentReferences": { "id": "123", "copies": 2 }, "status": "", "createdDate": "", - "name": "" + "name": "name" ) ) end @@ -83,35 +82,35 @@ def fake_distribution_request 200, {}, OpenStruct.new( - "id": package_id, + "id": "12345", "recipient": { - "type": recipient.type, - "name": recipient.name, - "firstName": recipient.first_name, - "middleName": recipient.middle_name, - "lastName": recipient.last_name, - "participant_id": recipient.participant_id, - "poaCode": recipient.poa_code, - "claimantStationOfJurisdiction": recipient.claimant_station_of_jurisdiction + "type": "person", + "name": "bob joe", + "firstName": "bob", + "middleName": "", + "lastName": "joe", + "participant_id": "123455667", + "poaCode": "", + "claimantStationOfJurisdiction": "" }, "description": "bad", "communicationPackageId": "", "destinations": { - "type": destination[:type], - "addressLine1": destination[:addressLine1], - "addressLine2": destination[:addressLine2], - "addressLine3": destination[:addressLine3], - "addressLine4": destination[:addressLine4], - "addressLine5": destination[:addressLine5], - "addressLine6": destination[:addressLine6], - "treatLine2AsAddressee": destination[:treatLine2AsAddressee], - "treatLine3AsAddressee": destination[:treatLine3AsAddressee], - "city": destination[:city], - "state": destination[:state], - "postalCode": destination[:postalCode], - "countryName": destination[:countryName], - "emailAddress": destination[:emailAddress], - "phoneNumber": destination[:phoneNumber] + "type": "email", + "addressLine1": "", + "addressLine2": "", + "addressLine3": "", + "addressLine4": "", + "addressLine5": "", + "addressLine6": "", + "treatLine2AsAddressee": 0, + "treatLine3AsAddressee": 0, + "city": "", + "state": "", + "postalCode": "", + "countryName": "", + "emailAddress": "", + "phoneNumber": "" }, "status": "", "sentToCbcmDate": "" @@ -125,35 +124,35 @@ def fake_distribution_response(distribution_id) 200, {}, OpenStruct.new( - "id": package_id, + "id": "123232323", "recipient": { - "type": recipient.type, - "name": recipient.name, - "firstName": recipient.first_name, - "middleName": recipient.middle_name, - "lastName": recipient.last_name, - "participant_id": recipient.participant_id, - "poaCode": recipient.poa_code, - "claimantStationOfJurisdiction": recipient.claimant_station_of_jurisdiction + "type": "person", + "name": "bob joe", + "firstName": "bob", + "middleName": "", + "lastName": "joe", + "participant_id": "123455667", + "poaCode": "", + "claimantStationOfJurisdiction": "" }, "description": "bad", "communicationPackageId": "", "destinations": { - "type": destination[:type], - "addressLine1": destination[:addressLine1], - "addressLine2": destination[:addressLine2], - "addressLine3": destination[:addressLine3], - "addressLine4": destination[:addressLine4], - "addressLine5": destination[:addressLine5], - "addressLine6": destination[:addressLine6], - "treatLine2AsAddressee": destination[:treatLine2AsAddressee], - "treatLine3AsAddressee": destination[:treatLine3AsAddressee], - "city": destination[:city], - "state": destination[:state], - "postalCode": destination[:postalCode], - "countryName": destination[:countryName], - "emailAddress": destination[:emailAddress], - "phoneNumber": destination[:phoneNumber] + "type": "email", + "addressLine1": "", + "addressLine2": "", + "addressLine3": "", + "addressLine4": "", + "addressLine5": "", + "addressLine6": "", + "treatLine2AsAddressee": 0, + "treatLine3AsAddressee": 0, + "city": "", + "state": "", + "postalCode": "", + "countryName": "", + "emailAddress": "", + "phoneNumber": "" }, "status": "", "sentToCbcmDate": "" From 9969733b3c3158c2b7a9fa4af160bab833cbd988 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 2 May 2023 13:00:39 -0400 Subject: [PATCH 024/308] made spacing correction in hearings/appeals_controller.rb --- app/controllers/hearings/appeals_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/hearings/appeals_controller.rb b/app/controllers/hearings/appeals_controller.rb index ea14a60498c..32fb47ade8c 100644 --- a/app/controllers/hearings/appeals_controller.rb +++ b/app/controllers/hearings/appeals_controller.rb @@ -8,7 +8,6 @@ class Hearings::AppealsController < HearingsController def update appeal.update!(appeal_params) render json: { appeal: appeal.attributes_for_hearing } - end private From 1f6b5c13c453d691ec3a1e919d8fff60ce673655 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 3 May 2023 09:33:16 -0400 Subject: [PATCH 025/308] APPEALS-21142 made corrections to model relationships. --- app/models/vbms_communication_package.rb | 2 +- app/models/vbms_distribution.rb | 2 +- app/models/vbms_distribution_destination.rb | 3 +-- db/migrate/20230425144000_create_pacman_integration.rb | 6 ++++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 9bbe09b0eb5..88bcf1a3fbb 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord has_one :vbms_uploaded_document - belongs_to :vbms_distributions + has_many :vbms_distributions end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index a6639310ac0..86d14285bd3 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -2,5 +2,5 @@ class VbmsDistribution < CaseflowRecord has_one :vbms_communication_package - has_many :vbms_distribution_destinations + has_one :vbms_distribution_destination end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index c85f292c3b8..8e4fe661d94 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - belongs_to :vbms_distributions + belongs_to :vbms_distribution end - diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb index c3679d83eb0..639ac0a2a5f 100644 --- a/db/migrate/20230425144000_create_pacman_integration.rb +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -8,15 +8,17 @@ def change t.timestamps t.references :vbms_uploaded_document, index: true, foreign_key: { to_table: :vbms_uploaded_documents } + t.references :created_by , index: true, foreign_key: { to_table: :users } t.references :updated_by, index: true, foreign_key: { to_table: :users } end create_table :vbms_distributions do |t| t.string :type, null: false - t.string :name, null: false + t.string :name + t.string :first_name t.string :middle_name - t.string :last_name, null: false + t.string :last_name t.string :participant_id t.string :poa_code, null: false t.string :claimant_station_of_jurisdiction, null: false From f3cee07262445f0fad59ef3a2fcc0d3b9ec7b0c7 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 3 May 2023 14:52:05 -0400 Subject: [PATCH 026/308] attribute name changes --- db/migrate/20230425144000_create_pacman_integration.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb index 639ac0a2a5f..094e763f7fa 100644 --- a/db/migrate/20230425144000_create_pacman_integration.rb +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -14,7 +14,7 @@ def change end create_table :vbms_distributions do |t| - t.string :type, null: false + t.string :distribution_type, null: false t.string :name t.string :first_name t.string :middle_name @@ -31,7 +31,7 @@ def change end create_table :vbms_distribution_destinations do |t| - t.string :type, null: false + t.string :destination_type, null: false t.string :address_line_1, null: false t.string :address_line_2, null: false t.string :address_line_3, null: false From 4617857a4320a190aa7c7ac804c43719048e8432 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Wed, 3 May 2023 16:57:59 -0400 Subject: [PATCH 027/308] APPEALS-21119 Added create table and functions (rb) for new tables --- ...unication_packages_audit_table_function.rb | 22 +++++++++++++++++++ ...ution_destinations_audit_table_function.rb | 22 +++++++++++++++++++ ...vbms_distributions_audit_table_function.rb | 22 +++++++++++++++++++ ...reate_vbms_communication_packages_audit.rb | 10 ++++++++- ...te_vbms_distribution_destinations_audit.rb | 22 ++++++++++++++++++- .../tables/create_vbms_distributions_audit.rb | 14 +++++++++++- 6 files changed, 109 insertions(+), 3 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index e69de29bb2d..e6ac73502e0 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create or replace function caseflow_audit.add_row_to_vbms_communication_packages_audit() returns trigger + as + $add_row$ + begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; + end; + $add_row$ + language plpgsql;" +) diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index e69de29bb2d..79ef4745093 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create or replace function caseflow_audit.add_row_to_vbms_distribution_destinations_audit() returns trigger + as + $add_row$ + begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; + end; + $add_row$ + language plpgsql;" +) diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index e69de29bb2d..1d0e1169d62 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create or replace function caseflow_audit.add_row_to_vbms_distributions_audit() returns trigger + as + $add_row$ + begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; + end; + $add_row$ + language plpgsql;" +) diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index 516fcd1b0c2..c46e28a48a5 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -7,5 +7,13 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, - DATA FROM TABLE... + comm_package_name varchar NOT NULL, + created_at timestamp NOT NULL, + created_by_id int8 NULL, + document_referenced _int8 NULL DEFAULT '{}'::bigint[], + file_number varchar NULL, + status varchar NULL, + updated_at timestamp NOT NULL, + updated_by_id int8 NULL, + vbms_uploaded_document_id int8 NULL );") diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 2f333f274c7..8dbca650799 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -7,5 +7,25 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, - DATA FROM TABLE... + address_line_1 varchar NOT NULL, + address_line_2 varchar NOT NULL, + address_line_3 varchar NOT NULL, + address_line_4 varchar NULL, + address_line_5 varchar NULL, + address_line_6 varchar NULL, + city varchar NOT NULL, + country_code varchar NOT NULL, + country_name varchar NOT NULL, + created_at timestamp NOT NULL, + created_by_id int8 NULL, + destination_type varchar NOT NULL, + email_address varchar NOT NULL, + phone_number varchar NOT NULL, + postal_code varchar NOT NULL, + state varchar NOT NULL, + treat_line_2_as_addressee bool NOT NULL, + treat_line_3_as_addressee bool NULL, + updated_at timestamp NOT NULL, + updated_by_id int8 NULL, + vbms_distribution_id int8 NULL );") diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index 0170416026f..34e231ca373 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -7,5 +7,17 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, - DATA FROM TABLE... + claimant_station_of_jurisdiction varchar NOT NULL, + created_at timestamp NOT NULL, + created_by_id int8 NULL, + distribution_type varchar NOT NULL, + first_name varchar NULL, + last_name varchar NULL, + middle_name varchar NULL, + name varchar NULL, + participant_id varchar NULL, + poa_code varchar NOT NULL, + updated_at timestamp NOT NULL, + updated_by_id int8 NULL, + vbms_communication_package_id int8 NULL );") From 24cf9ed04ace60fd45535614c25e48f2aad355ce Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Wed, 3 May 2023 17:08:50 -0400 Subject: [PATCH 028/308] APPEALS-21119 Created triggers for new tables --- ...reate_vbms_communication_packages_audit_trigger.rb | 11 +++++++++++ ...te_vbms_distribution_destinations_audit_trigger.rb | 11 +++++++++++ .../create_vbms_distributions_audit_trigger.rb | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb index e69de29bb2d..0e6e50a6dd3 100644 --- a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create trigger vbms_communication_packages_audit_trigger + after insert or update or delete on public.vbms_communication_packages + for each row + execute procedure caseflow_audit.add_row_to_vbms_communication_packages_audit();" +) diff --git a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb index e69de29bb2d..be3900be339 100644 --- a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create trigger vbms_distribution_destinations_audit_trigger + after insert or update or delete on public.vbms_distribution_destinations + for each row + execute procedure caseflow_audit.add_row_to_vbms_distribution_destinations_audit();" +) diff --git a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb index e69de29bb2d..03e23e413cd 100644 --- a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create trigger vbms_distributions_audit_trigger + after insert or update or delete on public.vbms_distributions + for each row + execute procedure caseflow_audit.add_row_to_vbms_distributions_audit();" +) From 0938ff72c66c87297f889d5daa3026872ee92e41 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Wed, 3 May 2023 17:12:13 -0400 Subject: [PATCH 029/308] APPEALS-21119 Added trigger and function for vbms_uploaded_doc --- ...uploaded_documents_audit_table_function.rb | 22 +++++++++++++++++++ ...e_vbms_uploaded_documents_audit_trigger.rb | 11 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb index e69de29bb2d..977ba5f2745 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create or replace function caseflow_audit.add_row_to_vbms_uploaded_documents_audit() returns trigger + as + $add_row$ + begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; + end; + $add_row$ + language plpgsql;" +) diff --git a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb index e69de29bb2d..95ce9a8c00d 100644 --- a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "pg" + +conn = CaseflowRecord.connection +conn.execute( + "create trigger vbms_uploaded_documents_audit_trigger + after insert or update or delete on public.vbms_uploaded_documents + for each row + execute procedure caseflow_audit.add_row_to_vbms_uploaded_documents_audit();" +) From d211d95d66cebf0ea57fa9bc9c18a1cba74aec05 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 5 May 2023 15:34:22 -0400 Subject: [PATCH 030/308] PR requested changes made. --- ...0230425144000_create_pacman_integration.rb | 51 +++++++------ db/schema.rb | 72 ++++++++++++++++++- 2 files changed, 96 insertions(+), 27 deletions(-) diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb index 094e763f7fa..958ec784ce9 100644 --- a/db/migrate/20230425144000_create_pacman_integration.rb +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -1,27 +1,26 @@ class CreatePacmanIntegration < Caseflow::Migration def change create_table :vbms_communication_packages do |t| - t.string :file_number + t.string :file_number, comment: "number associated with the documents." t.bigint :document_referenced, default: [], array: true t.string :status t.string :comm_package_name, null: false t.timestamps t.references :vbms_uploaded_document, index: true, foreign_key: { to_table: :vbms_uploaded_documents } - t.references :created_by , index: true, foreign_key: { to_table: :users } t.references :updated_by, index: true, foreign_key: { to_table: :users } end create_table :vbms_distributions do |t| - t.string :distribution_type, null: false - t.string :name - t.string :first_name - t.string :middle_name - t.string :last_name - t.string :participant_id - t.string :poa_code, null: false - t.string :claimant_station_of_jurisdiction, null: false + t.string :recipient_type, null: false, comment: "Must be one of [person, organization, ro-colocated, System]." + t.string :name, comment: "should only be used for non-person entity names. Not null if [recipient_type] is organization, ro-colocated, or System." + t.string :first_name, comment: "recipient's first name. If Type is [person] then it cant be null." + t.string :middle_name, comment: "recipient's middle name." + t.string :last_name, comment: "recipient's last name. If Type is [person] then it cant be null." + t.string :participant_id, comment: "recipient's participant id." + t.string :poa_code, comment: "Can't be null if [recipient_type] is ro-colocated. The recipients POA code" + t.string :claimant_station_of_jurisdiction, comment: "Can't be null if [recipient_type] is ro-colocated." t.timestamps t.references :vbms_communication_package, index: true, foreign_key: { to_table: :vbms_communication_packages } @@ -31,26 +30,26 @@ def change end create_table :vbms_distribution_destinations do |t| - t.string :destination_type, null: false - t.string :address_line_1, null: false - t.string :address_line_2, null: false - t.string :address_line_3, null: false - t.string :address_line_4 - t.string :address_line_5 - t.string :address_line_6 - t.boolean :treat_line_2_as_addressee, null: false + t.string :destination_type, null: false, comment: "Must be 'domesticAddress', 'internationalAddress', 'militaryAddress', 'derived', 'email', or 'sms'. Cannot be 'physicalAddress'." + t.string :address_line_1, null: false, comment: "PII. If destination_type is domestic, international, or military then Must not be null." + t.string :address_line_2, comment: "PII. If treatLine2AsAddressee is [true] then must not be null" + t.string :address_line_3, comment: "PII. If treatLine3AsAddressee is [true] then must not be null" + t.string :address_line_4, comment: "PII." + t.string :address_line_5, comment: "PII." + t.string :address_line_6, comment: "PII." + t.boolean :treat_line_2_as_addressee t.boolean :treat_line_3_as_addressee - t.string :city, null: false - t.string :state, null: false - t.string :postal_code, null: false - t.string :country_name, null: false - t.string :country_code, null: false - t.string :email_address, null: false - t.string :phone_number, null: false + t.string :city, comment: "PII. If type is [domestic, international, military] then Must not be null" + t.string :state, comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" + t.string :postal_code + t.string :country_name + t.string :country_code,comment: "Must be exactly two-letter ISO 3166 code." + t.string :email_address + t.string :phone_number, comment: "PII." t.timestamps t.references :vbms_distribution, index: true, foreign_key: { to_table: :vbms_distributions } - t.references :created_by , index: true, foreign_key: { to_table: :users } + t.references :created_by, index: true, foreign_key: { to_table: :users } t.references :updated_by, index: true, foreign_key: { to_table: :users } end end diff --git a/db/schema.rb b/db/schema.rb index eafc2b8ab21..5948a787e37 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: 2023_03_17_164013) do +ActiveRecord::Schema.define(version: 2023_04_25_144000) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1788,6 +1788,67 @@ t.index ["updated_at"], name: "index_users_on_updated_at" end + create_table "vbms_communication_packages", force: :cascade do |t| + t.string "comm_package_name", null: false + t.datetime "created_at", null: false + t.bigint "created_by_id" + t.bigint "document_referenced", default: [], array: true + t.string "file_number", comment: "number associated with the documents." + t.string "status" + t.datetime "updated_at", null: false + t.bigint "updated_by_id" + t.bigint "vbms_uploaded_document_id" + t.index ["created_by_id"], name: "index_vbms_communication_packages_on_created_by_id" + t.index ["updated_by_id"], name: "index_vbms_communication_packages_on_updated_by_id" + t.index ["vbms_uploaded_document_id"], name: "index_vbms_communication_packages_on_vbms_uploaded_document_id" + end + + create_table "vbms_distribution_destinations", force: :cascade do |t| + t.string "address_line_1", null: false, comment: "PII. If destination_type is domestic, international, or military then Must not be null." + t.string "address_line_2", comment: "PII. If treatLine2AsAddressee is [true] then must not be null" + t.string "address_line_3", comment: "PII. If treatLine3AsAddressee is [true] then must not be null" + t.string "address_line_4", comment: "PII." + t.string "address_line_5", comment: "PII." + t.string "address_line_6", comment: "PII." + t.string "city", comment: "PII. If type is [domestic, international, military] then Must not be null" + t.string "country_code", comment: "Must be exactly two-letter ISO 3166 code." + t.string "country_name" + t.datetime "created_at", null: false + t.bigint "created_by_id" + t.string "destination_type", null: false, comment: "Must be 'domesticAddress', 'internationalAddress', 'militaryAddress', 'derived', 'email', or 'sms'. Cannot be 'physicalAddress'." + t.string "email_address" + t.string "phone_number", comment: "PII." + t.string "postal_code" + t.string "state", comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" + t.boolean "treat_line_2_as_addressee" + t.boolean "treat_line_3_as_addressee" + t.datetime "updated_at", null: false + t.bigint "updated_by_id" + t.bigint "vbms_distribution_id" + t.index ["created_by_id"], name: "index_vbms_distribution_destinations_on_created_by_id" + t.index ["updated_by_id"], name: "index_vbms_distribution_destinations_on_updated_by_id" + t.index ["vbms_distribution_id"], name: "index_vbms_distribution_destinations_on_vbms_distribution_id" + end + + create_table "vbms_distributions", force: :cascade do |t| + t.string "claimant_station_of_jurisdiction", comment: "Can't be null if [recipient_type] is ro-colocated." + t.datetime "created_at", null: false + t.bigint "created_by_id" + t.string "first_name", comment: "recipient's first name. If Type is [person] then it cant be null." + t.string "last_name", comment: "recipient's last name. If Type is [person] then it cant be null." + t.string "middle_name", comment: "recipient's middle name." + t.string "name", comment: "should only be used for non-person entity names. Not null if [recipient_type] is organization, ro-colocated, or System." + t.string "participant_id", comment: "recipient's participant id." + t.string "poa_code", comment: "Can't be null if [recipient_type] is ro-colocated. The recipients POA code" + t.string "recipient_type", null: false, comment: "Must be one of [person, organization, ro-colocated, System]." + t.datetime "updated_at", null: false + t.bigint "updated_by_id" + t.bigint "vbms_communication_package_id" + t.index ["created_by_id"], name: "index_vbms_distributions_on_created_by_id" + t.index ["updated_by_id"], name: "index_vbms_distributions_on_updated_by_id" + t.index ["vbms_communication_package_id"], name: "index_vbms_distributions_on_vbms_communication_package_id" + end + create_table "vbms_uploaded_documents", force: :cascade do |t| t.bigint "appeal_id", comment: "Appeal/LegacyAppeal ID; use as FK to appeals/legacy_appeals" t.string "appeal_type", comment: "'Appeal' or 'LegacyAppeal'" @@ -2067,6 +2128,15 @@ add_foreign_key "unrecognized_appellants", "users", column: "created_by_id" add_foreign_key "user_quotas", "team_quotas" add_foreign_key "user_quotas", "users" + add_foreign_key "vbms_communication_packages", "users", column: "created_by_id" + add_foreign_key "vbms_communication_packages", "users", column: "updated_by_id" + add_foreign_key "vbms_communication_packages", "vbms_uploaded_documents" + add_foreign_key "vbms_distribution_destinations", "users", column: "created_by_id" + add_foreign_key "vbms_distribution_destinations", "users", column: "updated_by_id" + add_foreign_key "vbms_distribution_destinations", "vbms_distributions" + add_foreign_key "vbms_distributions", "users", column: "created_by_id" + add_foreign_key "vbms_distributions", "users", column: "updated_by_id" + add_foreign_key "vbms_distributions", "vbms_communication_packages" add_foreign_key "virtual_hearing_establishments", "virtual_hearings" add_foreign_key "virtual_hearings", "users", column: "created_by_id" add_foreign_key "virtual_hearings", "users", column: "updated_by_id" From b9ccee0e23faf0c9de264dfc56784477885cbeee Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 8 May 2023 11:53:59 -0400 Subject: [PATCH 031/308] branch init --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index a0ac88a66a2..f577714b8da 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,6 +12,7 @@ def bgs end def create + appeal = nil # Find veteran from appeal id and check with db if params["appeal_id"].present? From 75e1ecb55577bc27c8181dc5e65903bc9e3cb859 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Mon, 8 May 2023 14:47:33 -0400 Subject: [PATCH 032/308] APPEALS-21120 spec file added --- app/services/external_api/pacman_service.rb | 5 +- config/initializers/pacman.rb | 1 + lib/fakes/pacman_service.rb | 2 +- .../external_api/pacman_service_spec.rb | 121 ++++++++++++++++++ 4 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 config/initializers/pacman.rb create mode 100644 spec/services/external_api/pacman_service_spec.rb diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index f7d0255f7ec..0148fd25db4 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -93,9 +93,8 @@ def send_pacman_request(query: {}, headers: {}, endpoint:, method: :get, body: n request.headers = headers.merge(apikey: ENV["PACMAN_API_KEY"]) sleep 1 - # FIXME idk what the url is - MetricsService.record("pacman #{method.to_s.upcase} request to #{url}", - service: :va_dot_gov, + MetricsService.record("pacman service #{method.to_s.upcase} request to #{url}", + service: :pacman, name: endpoint) do case method when :get diff --git a/config/initializers/pacman.rb b/config/initializers/pacman.rb new file mode 100644 index 00000000000..7a6b9b24355 --- /dev/null +++ b/config/initializers/pacman.rb @@ -0,0 +1 @@ +PacManService = (ApplicationController.dependencies_faked? ? Fakes::PacManService : ExternalApi::PacManService) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 279c4300f09..d2c0602434b 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Fakes::PacmanService < ExternalApi::PacmanService +class Fakes::PacManService < ExternalApi::PacManService class << self def send_communication_package_request(file_number, name, document_references:) document_references.each do |document_reference| diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb new file mode 100644 index 00000000000..ca973f5bb3d --- /dev/null +++ b/spec/services/external_api/pacman_service_spec.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +describe ExternalApi::PacManService do + let(:client_secret) { "SOME-FAKE-KEY" } + let(:service_id) { "SOME-FAKE-SERVICE" } + let(:error_response_body) { { "result": "error", "message": { "token": ["error"] } }.to_json } + let(:participant_id) { "+1234567890" } + let(:phone_number) { "+19876543210" } + let(:status) { "in-progress" } + let(:first_name) { "Bob" } + let(:docket_number) { "1234567" } + let(:success_response) do + HTTPI::Response.new(200, {}, notification_response_body) + end + let(:sms_success_response) do + HTTPI::Response.new(200, {}, sms_notification_response_body) + end + let(:status_success_response) do + HTTPI::Response.new(200, {}, status_response_body) + end + let(:error_response) do + HTTPI::Response.new(400, {}, error_response_body) + end + let(:forbidden_response) do + HTTPI::Response.new(403, {}, error_response_body) + end + let(:not_found_response) do + HTTPI::Response.new(404, {}, error_response_body) + end + + context "get distribution" do + it "gets correct distribution" do + end + context "bad request" do + it "returns 400 PacManBadRequestError" do + + end + end + context "forbidden" do + it "returns 403 PacManForbiddenError" do + + end + end + context "not found" do + it "returns 404 PacManNotFoundError" do + + end + end + end + + context "creates and submits distribution" do + it "successfully sends distribution" do + end + context "bad request" do + it "returns 400 PacManBadRequestError" do + + end + end + context "forbidden" do + it "returns 403 PacManForbiddenError" do + + end + end + context "not found" do + it "returns 404 PacManNotFoundError" do + + end + end + end + + context "creates and sends communication package" do + it "successfully sends package" do + end + context "bad request" do + it "returns 400 PacManBadRequestError" do + + end + end + context "forbidden" do + it "returns 403 PacManForbiddenError" do + + end + end + end + + describe "response failure" do + let!(:error_code) { nil } + + before(:each) do + allow(VADotGovService).to receive(:send_va_dot_gov_request) + .and_return(HTTPI::Response.new(error_code, {}, {}.to_json)) + end + + context "429" do + let!(:error_code) { 400 } + + it "throws Caseflow::Error::VaDotGovLimitError" do + expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) + .to be_an_instance_of(Caseflow::Error::VaDotGovLimitError) + end + end + + context "400" do + let!(:error_code) { 403 } + + it "throws Caseflow::Error::VaDotGovRequestError" do + expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) + .to be_an_instance_of(Caseflow::Error::VaDotGovRequestError) + end + end + + context "500" do + let!(:error_code) { 404 } + + it "throws Caseflow::Error::VaDotGovServerError" do + expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) + .to be_an_instance_of(Caseflow::Error::VaDotGovServerError) + end + end + end +end From 8753dde1a572cd399f33b1ff57ad55a4763200d7 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Mon, 8 May 2023 16:12:22 -0400 Subject: [PATCH 033/308] APPEALS-21120 updated spec --- config/environments/test.rb | 2 +- lib/fakes/pacman_service.rb | 50 +++++++++---------- .../external_api/pacman_service_spec.rb | 46 ++++++++++++++++- 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 856e2c97b21..2631a9d04d1 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -113,5 +113,5 @@ ENV['TEST_VACOLS_HOST'] ||= "localhost" - ENV['PACMAN_API_URL'] ||= "who knows" + ENV['PACMAN_API_URL'] ||= "http://pacman.staging.bip.va.gov" end diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index d2c0602434b..eb115e99d39 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -58,6 +58,7 @@ def distribution_not_found_response ) end + # POST: /package-manager-service/communication-package def fake_package_request HTTPI::Response.new( 200, @@ -77,6 +78,7 @@ def fake_package_request end # rubocop:disable Metrics/MethodLength + # POST: /package-manager-service/distribution def fake_distribution_request HTTPI::Response.new( 200, @@ -119,40 +121,38 @@ def fake_distribution_request end # rubocop:enable Metrics/MethodLength + # GET: /package-manager-service/distribution/{id} def fake_distribution_response(distribution_id) HTTPI::Response.new( 200, {}, OpenStruct.new( - "id": "123232323", + "id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", "recipient": { - "type": "person", - "name": "bob joe", - "firstName": "bob", - "middleName": "", - "lastName": "joe", - "participant_id": "123455667", - "poaCode": "", - "claimantStationOfJurisdiction": "" + "type": "system", + "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name": "VBMS-C" }, - "description": "bad", - "communicationPackageId": "", + "description": "Staging Mailing Distribution", + "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", "destinations": { - "type": "email", - "addressLine1": "", - "addressLine2": "", - "addressLine3": "", - "addressLine4": "", - "addressLine5": "", + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": null, + "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", + "addressLine1": "POSTMASTER GENERAL", + "addressLine2": "UNITED STATES POSTAL SERVICE", + "addressLine3": "475 LENFANT PLZ SW RM 10022", + "addressLine4": "SUITE 123", + "addressLine5": "APO AE 09001-5275", "addressLine6": "", - "treatLine2AsAddressee": 0, - "treatLine3AsAddressee": 0, - "city": "", - "state": "", - "postalCode": "", - "countryName": "", - "emailAddress": "", - "phoneNumber": "" + "treatLine2AsAddressee": true, + "treatLine3AsAddressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postalCode": "12345", + "countryName": "UNITED STATES", + "countryCode": "us" }, "status": "", "sentToCbcmDate": "" diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index ca973f5bb3d..b774143159a 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -28,8 +28,50 @@ HTTPI::Response.new(404, {}, error_response_body) end + let(:distribution) do + {"id": "123232323", + "recipient": { + "type": "person", + "name": "bob joe", + "firstName": "bob", + "middleName": "", + "lastName": "joe", + "participant_id": "123455667", + "poaCode": "", + "claimantStationOfJurisdiction": "" + }, + "description": "bad", + "communicationPackageId": "", + "destinations": { + "type": "email", + "addressLine1": "", + "addressLine2": "", + "addressLine3": "", + "addressLine4": "", + "addressLine5": "", + "addressLine6": "", + "treatLine2AsAddressee": 0, + "treatLine3AsAddressee": 0, + "city": "", + "state": "", + "postalCode": "", + "countryName": "", + "emailAddress": "", + "phoneNumber": "" + }, + "status": "", + "sentToCbcmDate": ""}.to_json + end + + let(:get_distribution_success_response) do + HTTPI::Response.new(200, {}, distribution) + end + context "get distribution" do + subject { ExternalApi::PacManService.get_distribution_request(distribution["id"]) } it "gets correct distribution" do + allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) + expect(subject.body.to_json).to eq(get_distribution_success_response) end context "bad request" do it "returns 400 PacManBadRequestError" do @@ -42,8 +84,10 @@ end end context "not found" do + subject { ExternalApi::PacManService.get_distribution_request("fake") } it "returns 404 PacManNotFoundError" do - + allow(HTTPI).to receive(:get).and_return(not_found_response) + expect { subject }.to raise_error Caseflow::Error::PacManNotFoundError end end end From 2654ceb6a7c614ab6b212242490a3349a0ae24c3 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 9 May 2023 11:12:34 -0400 Subject: [PATCH 034/308] APPEALS-21119 Updated null constraints to match tables --- ...te_vbms_distribution_destinations_audit.rb | 20 +++++++++---------- .../tables/create_vbms_distributions_audit.rb | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 8dbca650799..7f23391acb5 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -8,22 +8,22 @@ type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, address_line_1 varchar NOT NULL, - address_line_2 varchar NOT NULL, - address_line_3 varchar NOT NULL, + address_line_2 varchar NULL, + address_line_3 varchar NULL, address_line_4 varchar NULL, address_line_5 varchar NULL, address_line_6 varchar NULL, - city varchar NOT NULL, - country_code varchar NOT NULL, - country_name varchar NOT NULL, + city varchar NULL, + country_code varchar NULL, + country_name varchar NULL, created_at timestamp NOT NULL, created_by_id int8 NULL, destination_type varchar NOT NULL, - email_address varchar NOT NULL, - phone_number varchar NOT NULL, - postal_code varchar NOT NULL, - state varchar NOT NULL, - treat_line_2_as_addressee bool NOT NULL, + email_address varchar NULL, + phone_number varchar NULL, + postal_code varchar NULL, + state varchar NULL, + treat_line_2_as_addressee bool NULL, treat_line_3_as_addressee bool NULL, updated_at timestamp NOT NULL, updated_by_id int8 NULL, diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index 34e231ca373..e7b2a0b4e2d 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -7,16 +7,16 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, - claimant_station_of_jurisdiction varchar NOT NULL, + claimant_station_of_jurisdiction varchar NULL, created_at timestamp NOT NULL, created_by_id int8 NULL, - distribution_type varchar NOT NULL, first_name varchar NULL, last_name varchar NULL, middle_name varchar NULL, name varchar NULL, participant_id varchar NULL, - poa_code varchar NOT NULL, + poa_code varchar NULL, + recipient_type varchar NOT NULL, updated_at timestamp NOT NULL, updated_by_id int8 NULL, vbms_communication_package_id int8 NULL From e8c58036b413250985a78159749de5ae2534cefb Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 9 May 2023 13:57:29 -0400 Subject: [PATCH 035/308] APPEALS-21119 Updated Makefile, added teardown scripts (SQL only) --- Makefile.example | 9 +++++++++ db/scripts/audit/pacman_integration_teardown.sql | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 db/scripts/audit/pacman_integration_teardown.sql diff --git a/Makefile.example b/Makefile.example index d174fd713a8..93ee443be86 100644 --- a/Makefile.example +++ b/Makefile.example @@ -143,6 +143,15 @@ audit: ## Create caseflow_audit schema, tables, and triggers in postgres bundle exec rails r db/scripts/audit/tables/create_appeal_states_audit.rb bundle exec rails r db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb bundle exec rails r db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb + bundle exec rails r db/scripts/audit/tables/create_vbms_communication_packages_audit.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb + bundle exec rails r db/scripts/audit/tables/create_vbms_distributions_audit.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb + bundle exec rails r db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb audit-remove: ## Remove caseflow_audit schema, tables and triggers in postgres bundle exec rails r db/scripts/audit/remove_caseflow_audit_schema.rb diff --git a/db/scripts/audit/pacman_integration_teardown.sql b/db/scripts/audit/pacman_integration_teardown.sql new file mode 100644 index 00000000000..11cdac54b82 --- /dev/null +++ b/db/scripts/audit/pacman_integration_teardown.sql @@ -0,0 +1,8 @@ +drop table caseflow_audit.vbms_communication_packages_audit; +drop trigger vbms_communication_packages_audit_trigger; +drop table caseflow_audit.vbms_distributions_audit; +drop trigger vbms_distributions_audit_trigger; +drop table caseflow_audit.vbms_distribution_destinations_audit; +drop trigger vbms_distribution_destinations_audit_trigger; +drop table caseflow_audit.vbms_uploaded_documents_audit; +drop trigger vbms_uploaded_documents_audit_trigger; From b54b59c66d7549468e0f7871a83c766bf0d91886 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 9 May 2023 14:26:42 -0400 Subject: [PATCH 036/308] APPEALS-21120 updated spec test --- app/services/external_api/pacman_service.rb | 32 +-- lib/fakes/pacman_service.rb | 29 +- .../external_api/pacman_service_spec.rb | 249 +++++++++++------- 3 files changed, 173 insertions(+), 137 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 0148fd25db4..f26a4e7bd63 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -7,18 +7,14 @@ class ExternalApi::PacManService GET_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution/" class << self - def send_communication_package_request(file_number, name, document_references:) - document_references.each do |document_reference| - request = package_request(file_number, name, document_reference) - send_pacman_request(request) - end + def send_communication_package_request(file_number, name, document_references) + request = package_request(file_number, name, document_references) + send_pacman_request(request) end - def send_distribution_request(package_id, recipient, destinations:) - destinations.each do |destination| - request = distribution_request(package_id, recipient, destination) - send_pacman_request(request) - end + def send_distribution_request(package_id, recipient, destinations) + request = distribution_request(package_id, recipient, destinations) + send_pacman_request(request) end def get_distribution_request(distribution_id) @@ -49,14 +45,14 @@ def distribution_request(package_id, recipient, destination) body: { communicationPackageId: package_id, recipient: { - type: recipient.type, - name: recipient.name, - firstName: recipient.first_name, - middleName: recipient.middle_name, - lastName: recipient.last_name, - participant_id: recipient.participant_id, - poaCode: recipient.poa_code, - claimantStationOfJurisdiction: recipient.claimant_station_of_jurisdiction + type: recipient[:type], + name: recipient[:name], + firstName: recipient[:first_name], + middleName: recipient[:middle_name], + lastName: recipient[:last_name], + participant_id: recipient[:participant_id], + poaCode: recipient[:poa_code], + claimantStationOfJurisdiction: recipient[:claimant_station_of_jurisdiction] }, destinations: { type: destination[:type], diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index eb115e99d39..ccc8c838708 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -2,18 +2,14 @@ class Fakes::PacManService < ExternalApi::PacManService class << self - def send_communication_package_request(file_number, name, document_references:) - document_references.each do |document_reference| - request = package_request(file_number, name, document_reference) - fake_package_request(request) - end + def send_communication_package_request(file_number, name, document_references) + request = package_request(file_number, name, document_reference) + fake_package_request(request) end - def send_distribution_request(package_id, recipient, destinations:) - destinations.each do |destination| - request = distribution_request(package_id, recipient, destination) - fake_distribution_request(request) - end + def send_distribution_request(package_id, recipient, destinations) + request = distribution_request(package_id, recipient, destination) + fake_distribution_request(request) end def get_distribution_request(distribution_id) @@ -64,15 +60,14 @@ def fake_package_request 200, {}, OpenStruct.new( - "id": "", - "fileNumber": "073-claimant-appeal-file-number", + "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", + "fileNumber": "123456789", "documentReferences": { - "id": "123", - "copies": 2 + "id": "23233175-6a87-4cd4-b327-f20cf5ef1222", + "copies": 1 }, - "status": "", - "createdDate": "", - "name": "name" + "status": "NEW", + "createDate": "" ) ) end diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index b774143159a..7dded555021 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -4,20 +4,6 @@ let(:client_secret) { "SOME-FAKE-KEY" } let(:service_id) { "SOME-FAKE-SERVICE" } let(:error_response_body) { { "result": "error", "message": { "token": ["error"] } }.to_json } - let(:participant_id) { "+1234567890" } - let(:phone_number) { "+19876543210" } - let(:status) { "in-progress" } - let(:first_name) { "Bob" } - let(:docket_number) { "1234567" } - let(:success_response) do - HTTPI::Response.new(200, {}, notification_response_body) - end - let(:sms_success_response) do - HTTPI::Response.new(200, {}, sms_notification_response_body) - end - let(:status_success_response) do - HTTPI::Response.new(200, {}, status_response_body) - end let(:error_response) do HTTPI::Response.new(400, {}, error_response_body) end @@ -29,60 +15,143 @@ end let(:distribution) do - {"id": "123232323", - "recipient": { - "type": "person", - "name": "bob joe", - "firstName": "bob", - "middleName": "", - "lastName": "joe", - "participant_id": "123455667", - "poaCode": "", - "claimantStationOfJurisdiction": "" - }, - "description": "bad", - "communicationPackageId": "", - "destinations": { - "type": "email", - "addressLine1": "", - "addressLine2": "", - "addressLine3": "", - "addressLine4": "", - "addressLine5": "", - "addressLine6": "", - "treatLine2AsAddressee": 0, - "treatLine3AsAddressee": 0, - "city": "", - "state": "", - "postalCode": "", - "countryName": "", - "emailAddress": "", - "phoneNumber": "" - }, - "status": "", - "sentToCbcmDate": ""}.to_json + { + "id": "123232323", + "recipient": { + "type": "person", + "name": "bob joe", + "firstName": "bob", + "middleName": "", + "lastName": "joe", + "participant_id": "123455667", + "poaCode": "", + "claimantStationOfJurisdiction": "" + }, + "description": "bad", + "communicationPackageId": "", + "destinations": { + "type": "email", + "addressLine1": "", + "addressLine2": "", + "addressLine3": "", + "addressLine4": "", + "addressLine5": "", + "addressLine6": "", + "treatLine2AsAddressee": 0, + "treatLine3AsAddressee": 0, + "city": "", + "state": "", + "postalCode": "", + "countryName": "", + "emailAddress": "", + "phoneNumber": "" + }, + "status": "", + "sentToCbcmDate": "" + }.to_json + end + + let(:distribution_post_request) do + { + "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "recipient": { + "type": "system", + "name": "VBMS-C" + }, + "destinations": { + "type": "domesticAddress", + "addressLine1": "123 Test St.", + "addressLine2": "", + "addressLine3": "", + "addressLine4": "", + "addressLine5": "", + "addressLine6": "", + "city": "Anytown", + "postalCode": "12345", + "state": "DC", + "countryName": "United States of America", + "countryCode": "01" + } + }.to_json + end + + let(:distribution_post_response) do + { + "id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "recipient": { + "type": "system", + "id": "2c6592fc-b3af-48ff-8263-c581c2f0a68b", + "name": "VBMS-C" + }, + "description": "Staging Distribution", + "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations": { + "type": "physicalAddress", + "id": "5378bfbd-eff5-470c-bbc4-c7fd3c863a50", + "status": null, + "cbcmSendAttemptDate": "2022-06-06T16:35:28.017", + "addressLine1": "POSTMASTER GENERAL", + "addressLine2": "UNITED STATES POSTAL SERVICE", + "addressLine3": "475 LENFANT PLZ SW RM 10022", + "addressLine4": "SUITE 123", + "addressLine5": "APO AE 09001-5275", + "addressLine6": "", + "treatLine2AsAddressee": false, + "treatLine3AsAddressee": false, + "city": "WASHINGTON DC", + "state": "DC", + "postalCode": "12345", + "countryName": "UNITED STATES", + "countryCode": "us" + }, + "status": null, + "sentToCbcmDate": null + }.to_json + end + + let(:package_post_request) do + { + "fileNumber": "123456789", + "name": "ABC abc 1234 !*+,-.:;=?", + "documentReferences": { + "id": "3aec91cc-a88d-4b9c-9183-84bed583bbcc", + "copies": 1 + } + }.to_json + end + + let(:package_post_response) do + { + "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", + "fileNumber": "123456789", + "documentReferences": { + "id": "23233175-6a87-4cd4-b327-f20cf5ef1222", + "copies": 1 + }, + "status": "NEW", + "createDate": "" + }.to_json end let(:get_distribution_success_response) do HTTPI::Response.new(200, {}, distribution) end + let(:post_distribution_success_response) do + HTTPI::Response.new(201, {}, distribution_post_response) + end + + let(:post_package_success_response) do + HTTPI::Response.new(201, {}, package_post_response) + end + context "get distribution" do subject { ExternalApi::PacManService.get_distribution_request(distribution["id"]) } it "gets correct distribution" do + subject allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) expect(subject.body.to_json).to eq(get_distribution_success_response) end - context "bad request" do - it "returns 400 PacManBadRequestError" do - - end - end - context "forbidden" do - it "returns 403 PacManForbiddenError" do - - end - end context "not found" do subject { ExternalApi::PacManService.get_distribution_request("fake") } it "returns 404 PacManNotFoundError" do @@ -93,17 +162,14 @@ end context "creates and submits distribution" do - it "successfully sends distribution" do + subject do + ExternalApi::PacManService.send_distribution_request(distribution_post_request["communicationPackageId"], + distribution_post_request["recipient"], + distribution_post_request["destinations"]) end - context "bad request" do - it "returns 400 PacManBadRequestError" do - - end - end - context "forbidden" do - it "returns 403 PacManForbiddenError" do - - end + it "successfully sends distribution" do + allow(HTTPI).to receive(:post).and_return(post_distribution_success_response) + expect(subject.body.to_json).to eq(post_distribution_success_response) end context "not found" do it "returns 404 PacManNotFoundError" do @@ -113,52 +179,31 @@ end context "creates and sends communication package" do - it "successfully sends package" do + subject do + ExternalApi::PacManService.send_communication_package_request(package_post_request["file_number"], + package_post_request["name"], + package_post_request["document_references"]) end - context "bad request" do - it "returns 400 PacManBadRequestError" do - - end - end - context "forbidden" do - it "returns 403 PacManForbiddenError" do - - end + it "successfully sends package" do + allow(HTTPI).to receive(:post).and_return(post_package_success_response) + expect(subject.body.to_json).to eq(post_package_success_response) end end describe "response failure" do - let!(:error_code) { nil } - - before(:each) do - allow(VADotGovService).to receive(:send_va_dot_gov_request) - .and_return(HTTPI::Response.new(error_code, {}, {}.to_json)) - end - - context "429" do - let!(:error_code) { 400 } - - it "throws Caseflow::Error::VaDotGovLimitError" do - expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) - .to be_an_instance_of(Caseflow::Error::VaDotGovLimitError) - end - end + subject { ExternalApi::PacManService.get_distribution_request(distribution["id"]) } context "400" do - let!(:error_code) { 403 } - - it "throws Caseflow::Error::VaDotGovRequestError" do - expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) - .to be_an_instance_of(Caseflow::Error::VaDotGovRequestError) + it "throws Caseflow::Error::PacManBadRequestError" do + allow(HTTPI).to receive(:get).and_return(error_response) + expect { subject }.to raise_error Caseflow::Error::PacManBadRequestError end end - context "500" do - let!(:error_code) { 404 } - - it "throws Caseflow::Error::VaDotGovServerError" do - expect(VADotGovService.get_facility_data(ids: ["vba_372"]).error) - .to be_an_instance_of(Caseflow::Error::VaDotGovServerError) + context "403" do + it "throws Caseflow::Error::PacManForbiddenError" do + allow(HTTPI).to receive(:get).and_return(forbidden_response) + expect { subject }.to raise_error Caseflow::Error::PacManForbiddenError end end end From a2f85839f4442d3bb536387fc90d9fdf623b3788 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 9 May 2023 15:18:05 -0400 Subject: [PATCH 037/308] APPEALS-21119 Updated order of columns on creation. Updated table names in functions --- ...unication_packages_audit_table_function.rb | 6 ++--- ...ution_destinations_audit_table_function.rb | 6 ++--- ...vbms_distributions_audit_table_function.rb | 6 ++--- ...uploaded_documents_audit_table_function.rb | 6 ++--- ...reate_vbms_communication_packages_audit.rb | 12 +++++----- ...te_vbms_distribution_destinations_audit.rb | 20 ++++++++-------- .../tables/create_vbms_distributions_audit.rb | 16 ++++++------- .../create_vbms_uploaded_documents_audit.rb | 24 +++++++++---------- 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index e6ac73502e0..3810f3ff895 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -9,11 +9,11 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_communication_packages select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index 79ef4745093..afcd1f4ecea 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -9,11 +9,11 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distribution_destinations select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 1d0e1169d62..52c3d07ba8c 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -9,11 +9,11 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distributions select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb index 977ba5f2745..029e7e051ee 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb @@ -9,11 +9,11 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'D', OLD.*; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'U', NEW.*; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_uploaded_documents select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'I', NEW.*; end if; return null; end; diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index c46e28a48a5..df1bdc0142f 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -7,13 +7,13 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, - comm_package_name varchar NOT NULL, - created_at timestamp NOT NULL, - created_by_id int8 NULL, - document_referenced _int8 NULL DEFAULT '{}'::bigint[], file_number varchar NULL, + document_referenced _int8 NULL DEFAULT '{}'::bigint[], status varchar NULL, + comm_package_name varchar NOT NULL, + created_at timestamp NOT NULL, updated_at timestamp NOT NULL, - updated_by_id int8 NULL, - vbms_uploaded_document_id int8 NULL + vbms_uploaded_document_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL );") diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 7f23391acb5..a44300f6076 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -7,25 +7,25 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, + destination_type varchar NOT NULL, address_line_1 varchar NOT NULL, address_line_2 varchar NULL, address_line_3 varchar NULL, address_line_4 varchar NULL, address_line_5 varchar NULL, address_line_6 varchar NULL, + treat_line_2_as_addressee bool NULL, + treat_line_3_as_addressee bool NULL, city varchar NULL, - country_code varchar NULL, + state varchar NULL, + postal_code varchar NULL, country_name varchar NULL, - created_at timestamp NOT NULL, - created_by_id int8 NULL, - destination_type varchar NOT NULL, + country_code varchar NULL, email_address varchar NULL, phone_number varchar NULL, - postal_code varchar NULL, - state varchar NULL, - treat_line_2_as_addressee bool NULL, - treat_line_3_as_addressee bool NULL, + created_at timestamp NOT NULL, updated_at timestamp NOT NULL, - updated_by_id int8 NULL, - vbms_distribution_id int8 NULL + vbms_distribution_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL );") diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index e7b2a0b4e2d..c98bfc16c9f 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -7,17 +7,17 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, - claimant_station_of_jurisdiction varchar NULL, - created_at timestamp NOT NULL, - created_by_id int8 NULL, + recipient_type varchar NOT NULL, + name varchar NULL, first_name varchar NULL, - last_name varchar NULL, middle_name varchar NULL, - name varchar NULL, + last_name varchar NULL, participant_id varchar NULL, poa_code varchar NULL, - recipient_type varchar NOT NULL, + claimant_station_of_jurisdiction varchar NULL, + created_at timestamp NOT NULL, updated_at timestamp NOT NULL, - updated_by_id int8 NULL, - vbms_communication_package_id int8 NULL + vbms_communication_package_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL );") diff --git a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb index 929ca934df5..c8c916cef43 100644 --- a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb +++ b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb @@ -7,19 +7,19 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_uploaded_documents_id bigint not null, - appeal_id int8, - appeal_type varchar, - attempted_at timestamp, - canceled_at timestamp, + appeal_id int8 NULL, + appeal_type varchar NULL, + attempted_at timestamp NULL, + canceled_at timestamp NULL, created_at timestamp NOT NULL, - document_name varchar, - document_subject varchar, + document_name varchar NULL, + document_subject varchar NULL, document_type varchar NOT NULL, - error varchar, - last_submitted_at timestamp, - processed_at timestamp, - submitted_at timestamp, + error varchar NULL, + last_submitted_at timestamp NULL, + processed_at timestamp NULL, + submitted_at timestamp NULL, updated_at timestamp NOT NULL, - uploaded_to_vbms_at timestamp, - veteran_file_number varchar + uploaded_to_vbms_at timestamp NULL, + veteran_file_number varchar NULL );") From 741218bc6608efdcaa97cddd2d88fc0d6d2a258a Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 9 May 2023 15:33:20 -0400 Subject: [PATCH 038/308] APPEALS-21119 Added SQL to files for new tables --- ...eate_vbms_communication_packages_audit.sql | 14 ++++++++++ ...e_vbms_distribution_destinations_audit.sql | 26 +++++++++++++++++++ .../create_vbms_distributions_audit.sql | 18 +++++++++++++ 3 files changed, 58 insertions(+) diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index e69de29bb2d..767f562c463 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -0,0 +1,14 @@ +create table caseflow_audit.vbms_communication_packages_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_communication_package_id bigint not null, + file_number varchar NULL, + document_referenced _int8 NULL DEFAULT '{}'::bigint[], + status varchar NULL, + comm_package_name varchar NOT NULL, + created_at timestamp NOT NULL, + updated_at timestamp NOT NULL, + vbms_uploaded_document_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL + ); diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index e69de29bb2d..b36bc275374 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -0,0 +1,26 @@ +create table caseflow_audit.vbms_distribution_destinations_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_distribution_destinations_id bigint not null, + destination_type varchar NOT NULL, + address_line_1 varchar NOT NULL, + address_line_2 varchar NULL, + address_line_3 varchar NULL, + address_line_4 varchar NULL, + address_line_5 varchar NULL, + address_line_6 varchar NULL, + treat_line_2_as_addressee bool NULL, + treat_line_3_as_addressee bool NULL, + city varchar NULL, + state varchar NULL, + postal_code varchar NULL, + country_name varchar NULL, + country_code varchar NULL, + email_address varchar NULL, + phone_number varchar NULL, + created_at timestamp NOT NULL, + updated_at timestamp NOT NULL, + vbms_distribution_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL + ); diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql index e69de29bb2d..03f16de76b2 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.sql @@ -0,0 +1,18 @@ +create table caseflow_audit.vbms_distributions_audit ( + id BIGSERIAL PRIMARY KEY, + type_of_change CHAR(1) not null, + vbms_distributions_id bigint not null, + recipient_type varchar NOT NULL, + name varchar NULL, + first_name varchar NULL, + middle_name varchar NULL, + last_name varchar NULL, + participant_id varchar NULL, + poa_code varchar NULL, + claimant_station_of_jurisdiction varchar NULL, + created_at timestamp NOT NULL, + updated_at timestamp NOT NULL, + vbms_communication_package_id int8 NULL, + created_by_id int8 NULL, + updated_by_id int8 NULL + ); From cb048858627388a10ba2b12ff3fb8bdefce6880a Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 9 May 2023 15:46:35 -0400 Subject: [PATCH 039/308] APPEALS-21120 changed PacMan to Pacman --- app/services/external_api/pacman_service.rb | 6 ++++- .../external_api/pacman_service/response.rb | 14 +++++----- config/initializers/pacman.rb | 2 +- lib/caseflow/error.rb | 10 +++---- lib/fakes/pacman_service.rb | 2 +- .../external_api/pacman_service_spec.rb | 26 +++++++++---------- 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index f26a4e7bd63..63a54b14ff8 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true -class ExternalApi::PacManService +require "json" +require "base64" +require "digest" + +class ExternalApi::PacmanService BASE_URL = ENV["PACMAN_API_URL"] SEND_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution" SEND_PACKAGE_ENDPOINT = "package-manager-service/communication-package" diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb index 53952d090ba..1b3613a4495 100644 --- a/app/services/external_api/pacman_service/response.rb +++ b/app/services/external_api/pacman_service/response.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ExternalApi::PacManService::Response +class ExternalApi::PacmanService::Response attr_reader :resp, :code def initialize(resp) @@ -29,9 +29,9 @@ def body private ERROR_LOOKUP = { - 400 => Caseflow::Error::PacManBadRequestError, - 403 => Caseflow::Error::PacManForbiddenError, - 404 => Caseflow::Error::PacManNotFoundError + 400 => Caseflow::Error::PacmanBadRequestError, + 403 => Caseflow::Error::PacmanForbiddenError, + 404 => Caseflow::Error::PacmanNotFoundError }.freeze def check_for_error @@ -42,13 +42,13 @@ def check_for_error if ERROR_LOOKUP.key? code ERROR_LOOKUP[code].new(code: code, message: message) else - Caseflow::Error::PacManApiError.new(code: code, message: message) + Caseflow::Error::PacmanApiError.new(code: code, message: message) end end def error_message - return "No error message from PacMan" if body.empty? + return "No error message from Pacman" if body.empty? - body&.error || "No error message from PacMan" + body&.error || "No error message from Pacman" end end diff --git a/config/initializers/pacman.rb b/config/initializers/pacman.rb index 7a6b9b24355..481795e510d 100644 --- a/config/initializers/pacman.rb +++ b/config/initializers/pacman.rb @@ -1 +1 @@ -PacManService = (ApplicationController.dependencies_faked? ? Fakes::PacManService : ExternalApi::PacManService) +PacmanService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index 40cc7f4bdd6..ca88a9f0455 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -448,9 +448,9 @@ class VANotifyInternalServerError < VANotifyApiError; end class VANotifyRateLimitError < VANotifyApiError; end class EmptyQueueError < StandardError; end - # PacMan errors - class PacManApiError < StandardError; end - class PacManBadRequestError < PacManApiError; end - class PacManForbiddenError < PacManApiError; end - class PacManNotFoundError < PacManApiError; end + # Pacman errors + class PacmanApiError < StandardError; end + class PacmanBadRequestError < PacmanApiError; end + class PacmanForbiddenError < PacmanApiError; end + class PacmanNotFoundError < PacmanApiError; end end diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index ccc8c838708..2a1f33ced65 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Fakes::PacManService < ExternalApi::PacManService +class Fakes::PacmanService < ExternalApi::PacmanService class << self def send_communication_package_request(file_number, name, document_references) request = package_request(file_number, name, document_reference) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 7dded555021..7b16545c12c 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe ExternalApi::PacManService do +describe ExternalApi::PacmanService do let(:client_secret) { "SOME-FAKE-KEY" } let(:service_id) { "SOME-FAKE-SERVICE" } let(:error_response_body) { { "result": "error", "message": { "token": ["error"] } }.to_json } @@ -146,24 +146,24 @@ end context "get distribution" do - subject { ExternalApi::PacManService.get_distribution_request(distribution["id"]) } + subject { ExternalApi::PacmanService.get_distribution_request(distribution["id"]) } it "gets correct distribution" do subject allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) expect(subject.body.to_json).to eq(get_distribution_success_response) end context "not found" do - subject { ExternalApi::PacManService.get_distribution_request("fake") } - it "returns 404 PacManNotFoundError" do + subject { ExternalApi::PacmanService.get_distribution_request("fake") } + it "returns 404 PacmanNotFoundError" do allow(HTTPI).to receive(:get).and_return(not_found_response) - expect { subject }.to raise_error Caseflow::Error::PacManNotFoundError + expect { subject }.to raise_error Caseflow::Error::PacmanNotFoundError end end end context "creates and submits distribution" do subject do - ExternalApi::PacManService.send_distribution_request(distribution_post_request["communicationPackageId"], + ExternalApi::PacmanService.send_distribution_request(distribution_post_request["communicationPackageId"], distribution_post_request["recipient"], distribution_post_request["destinations"]) end @@ -172,7 +172,7 @@ expect(subject.body.to_json).to eq(post_distribution_success_response) end context "not found" do - it "returns 404 PacManNotFoundError" do + it "returns 404 PacmanNotFoundError" do end end @@ -180,7 +180,7 @@ context "creates and sends communication package" do subject do - ExternalApi::PacManService.send_communication_package_request(package_post_request["file_number"], + ExternalApi::PacmanService.send_communication_package_request(package_post_request["file_number"], package_post_request["name"], package_post_request["document_references"]) end @@ -191,19 +191,19 @@ end describe "response failure" do - subject { ExternalApi::PacManService.get_distribution_request(distribution["id"]) } + subject { ExternalApi::PacmanService.get_distribution_request(distribution["id"]) } context "400" do - it "throws Caseflow::Error::PacManBadRequestError" do + it "throws Caseflow::Error::PacmanBadRequestError" do allow(HTTPI).to receive(:get).and_return(error_response) - expect { subject }.to raise_error Caseflow::Error::PacManBadRequestError + expect { subject }.to raise_error Caseflow::Error::PacmanBadRequestError end end context "403" do - it "throws Caseflow::Error::PacManForbiddenError" do + it "throws Caseflow::Error::PacmanForbiddenError" do allow(HTTPI).to receive(:get).and_return(forbidden_response) - expect { subject }.to raise_error Caseflow::Error::PacManForbiddenError + expect { subject }.to raise_error Caseflow::Error::PacmanForbiddenError end end end From ecf9ccdcf4fd044c7e68a737afa5bfe490df2add Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 9 May 2023 16:13:24 -0400 Subject: [PATCH 040/308] APPEALS-21120 updated error response --- app/services/external_api/pacman_service/response.rb | 3 ++- config/environments/development.rb | 2 ++ lib/caseflow/error.rb | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb index 1b3613a4495..1e35a914f4a 100644 --- a/app/services/external_api/pacman_service/response.rb +++ b/app/services/external_api/pacman_service/response.rb @@ -31,7 +31,8 @@ def body ERROR_LOOKUP = { 400 => Caseflow::Error::PacmanBadRequestError, 403 => Caseflow::Error::PacmanForbiddenError, - 404 => Caseflow::Error::PacmanNotFoundError + 404 => Caseflow::Error::PacmanNotFoundError, + 500 => Caseflow::Error::PacmanInternalServerError }.freeze def check_for_error diff --git a/config/environments/development.rb b/config/environments/development.rb index 6db1fb94106..44dcd3c8aeb 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -98,6 +98,8 @@ # Notifications page eFolder link ENV["CLAIM_EVIDENCE_EFOLDER_BASE_URL"] ||= "https://vefs-claimevidence-ui-uat.stage8.bip.va.gov" + ENV["PACMAN_API_URL"] ||= "https://pacman-dev.dev.bip.va.gov/" + if ENV["WITH_TEST_EMAIL_SERVER"] config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index ca88a9f0455..e7601fc7ca3 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -453,4 +453,5 @@ class PacmanApiError < StandardError; end class PacmanBadRequestError < PacmanApiError; end class PacmanForbiddenError < PacmanApiError; end class PacmanNotFoundError < PacmanApiError; end + class PacmanInternalServerError < PacmanApiError; end end From 9e2a4ce64ab2e8ed26b63837405568e723ea1ff3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 10 May 2023 14:46:39 -0400 Subject: [PATCH 041/308] Create validations for VbmsCommunicationPackage (minus validations for document_referenced) --- app/models/vbms_communication_package.rb | 13 +++++++++++++ db/schema.rb | 7 ++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 88bcf1a3fbb..ceaf5c9310b 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -2,4 +2,17 @@ class VbmsCommunicationPackage < CaseflowRecord has_one :vbms_uploaded_document has_many :vbms_distributions + + validates :file_number, :comm_package_name, :document_referenced, presence: true + + # file_number format can be validated with bgs_service.fetch_verteran_info(file_number) + # – Would this validation be more appropriate in PacMan controller and not here? + + # PacMan docs suggested multiline ^ and $ anchors for regex, but I changed to \A and \Z as suggested by rails log + validates :comm_package_name, format: { with: /\A[\w !*+,-.:;=?]{1,225}\Z/ } + + # document_referenced has current data type of array of bigint values + # - if you try and store object with "id" and "copies" keys into db it will be converted to nil object + # - need to solve before being able to validate "id" and "copies" + validates :document_referenced, length: { minimum: 1 } end diff --git a/db/schema.rb b/db/schema.rb index 5948a787e37..4c8aae09434 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -91,7 +91,7 @@ t.boolean "appeal_docketed", default: false, null: false, comment: "When true, appeal has been docketed" t.bigint "appeal_id", null: false, comment: "AMA or Legacy Appeal ID" t.string "appeal_type", null: false, comment: "Appeal Type (Appeal or LegacyAppeal)" - t.datetime "created_at", null: false, comment: "Date and Time the record was inserted into the table" + t.datetime "created_at", null: false t.bigint "created_by_id", null: false, comment: "User id of the user that inserted the record" t.boolean "decision_mailed", default: false, null: false, comment: "When true, appeal has decision mail request complete" t.boolean "hearing_postponed", default: false, null: false, comment: "When true, appeal has hearing postponed and no hearings scheduled" @@ -100,7 +100,7 @@ t.boolean "privacy_act_complete", default: false, null: false, comment: "When true, appeal has a privacy act request completed" t.boolean "privacy_act_pending", default: false, null: false, comment: "When true, appeal has a privacy act request still open" t.boolean "scheduled_in_error", default: false, null: false, comment: "When true, hearing was scheduled in error and none scheduled" - t.datetime "updated_at", comment: "Date and time the record was last updated" + t.datetime "updated_at" t.bigint "updated_by_id", comment: "User id of the last user that updated the record" t.boolean "vso_ihp_complete", default: false, null: false, comment: "When true, appeal has a VSO IHP request completed" t.boolean "vso_ihp_pending", default: false, null: false, comment: "When true, appeal has a VSO IHP request pending" @@ -1275,7 +1275,7 @@ t.string "recipient_email", comment: "Participant's Email Address" t.string "recipient_phone_number", comment: "Participants Phone Number" t.text "sms_notification_content", comment: "Full SMS Text Content of Notification" - t.string "sms_notification_external_id" + 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.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" @@ -1577,6 +1577,7 @@ t.boolean "national_cemetery_administration", default: false t.boolean "no_special_issues", default: false, comment: "Affirmative no special issues, added belatedly" t.boolean "nonrating_issue", default: false + t.boolean "pact_act", default: false, comment: "The Sergeant First Class (SFC) Heath Robinson Honoring our Promise to Address Comprehensive Toxics (PACT) Act" t.boolean "pension_united_states", default: false t.boolean "private_attorney_or_agent", default: false t.boolean "radiation", default: false From 9128e6d113a42c00cd5c7d70a9690c706089b160 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 10 May 2023 15:29:22 -0400 Subject: [PATCH 042/308] Added call to bgs service to validate veteran file number --- app/models/vbms_communication_package.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index ceaf5c9310b..1ff6103e71f 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -5,8 +5,8 @@ class VbmsCommunicationPackage < CaseflowRecord validates :file_number, :comm_package_name, :document_referenced, presence: true - # file_number format can be validated with bgs_service.fetch_verteran_info(file_number) - # – Would this validation be more appropriate in PacMan controller and not here? + # Would this validation already happen/be more appropriate in the PacMan controller? + validate :file_number_matches_bgs # PacMan docs suggested multiline ^ and $ anchors for regex, but I changed to \A and \Z as suggested by rails log validates :comm_package_name, format: { with: /\A[\w !*+,-.:;=?]{1,225}\Z/ } @@ -15,4 +15,14 @@ class VbmsCommunicationPackage < CaseflowRecord # - if you try and store object with "id" and "copies" keys into db it will be converted to nil object # - need to solve before being able to validate "id" and "copies" validates :document_referenced, length: { minimum: 1 } + + def bgs_service + @bgs_service || BGSService.new + end + + def file_number_matches_bgs + if bgs_service.fetch_veteran_info(file_number).nil? + errors.add(:file_number, "does not match a valid veteran file number") + end + end end From c8b8cc224bd15a2a7cab57a550ea425aa0699405 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 10 May 2023 15:37:29 -0400 Subject: [PATCH 043/308] Updated file_number_matches_bgs custom validation on VbmsCommunicationPackage --- app/models/vbms_communication_package.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 1ff6103e71f..48d08d5e35b 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -5,9 +5,6 @@ class VbmsCommunicationPackage < CaseflowRecord validates :file_number, :comm_package_name, :document_referenced, presence: true - # Would this validation already happen/be more appropriate in the PacMan controller? - validate :file_number_matches_bgs - # PacMan docs suggested multiline ^ and $ anchors for regex, but I changed to \A and \Z as suggested by rails log validates :comm_package_name, format: { with: /\A[\w !*+,-.:;=?]{1,225}\Z/ } @@ -16,6 +13,9 @@ class VbmsCommunicationPackage < CaseflowRecord # - need to solve before being able to validate "id" and "copies" validates :document_referenced, length: { minimum: 1 } + # This validation currently takes place in PrepareDocumentUploadToVbms... any reason it would need to take place again in model? + validate :file_number_matches_bgs + def bgs_service @bgs_service || BGSService.new end From 0067219182bc2bccbf0d28ea1629f863fed29b7b Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 10 May 2023 16:37:59 -0400 Subject: [PATCH 044/308] Completed validations for VbmsDistribution --- app/models/vbms_distribution.rb | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 86d14285bd3..5e57c7e5ff7 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,6 +1,24 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - has_one :vbms_communication_package + # Should this association be "belongs_to" instead of "has_one"? Because FK sits on this table + belongs_to :vbms_communication_package, optional: false + # has_one :vbms_communication_package has_one :vbms_distribution_destination + + validates :recipient_type, presence: true, inclusion: { in: %w(organization person system ro-colocated)} + validates :name, presence: true, unless: :is_person? + validates :first_name, presence: true, if: :is_person? + validates :last_name, presence: true, if: :is_person? + validates :poa_code, presence: true, if: :is_ro_colocated? + validates :claimant_station_of_jurisdiction, presence: true, if: :is_ro_colocated? + + def is_person? + recipient_type == "person" + end + + def is_ro_colocated? + recipient_type == "ro-colocated" + end + end From d17b053b4eb14b83d21ead4c06faee5df184c8c1 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 09:21:47 -0400 Subject: [PATCH 045/308] APPEALS-21120 updated rspec tests --- app/services/external_api/pacman_service.rb | 9 +- config/environments/development.rb | 2 +- config/initializers/pacman.rb | 2 +- .../external_api/pacman_service_spec.rb | 196 +++++++++--------- 4 files changed, 101 insertions(+), 108 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 63a54b14ff8..897ae5e5813 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -6,9 +6,12 @@ class ExternalApi::PacmanService BASE_URL = ENV["PACMAN_API_URL"] - SEND_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution" - SEND_PACKAGE_ENDPOINT = "package-manager-service/communication-package" - GET_DISTRIBUTION_ENDPOINT = "package-manager-service/distribution/" + SEND_DISTRIBUTION_ENDPOINT = "/package-manager-service/distribution" + SEND_PACKAGE_ENDPOINT = "/package-manager-service/communication-package" + GET_DISTRIBUTION_ENDPOINT = "/package-manager-service/distribution/" + HEADERS = { + "Content-Type": "application/json", Accept: "application/json" + }.freeze class << self def send_communication_package_request(file_number, name, document_references) diff --git a/config/environments/development.rb b/config/environments/development.rb index 44dcd3c8aeb..73343ce7233 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -98,7 +98,7 @@ # Notifications page eFolder link ENV["CLAIM_EVIDENCE_EFOLDER_BASE_URL"] ||= "https://vefs-claimevidence-ui-uat.stage8.bip.va.gov" - ENV["PACMAN_API_URL"] ||= "https://pacman-dev.dev.bip.va.gov/" + ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov/" if ENV["WITH_TEST_EMAIL_SERVER"] config.action_mailer.delivery_method = :smtp diff --git a/config/initializers/pacman.rb b/config/initializers/pacman.rb index 481795e510d..9dded20eed5 100644 --- a/config/initializers/pacman.rb +++ b/config/initializers/pacman.rb @@ -1 +1 @@ -PacmanService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) +PacManService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 7b16545c12c..f442bc8c959 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true describe ExternalApi::PacmanService do - let(:client_secret) { "SOME-FAKE-KEY" } - let(:service_id) { "SOME-FAKE-SERVICE" } - let(:error_response_body) { { "result": "error", "message": { "token": ["error"] } }.to_json } + let(:error_response_body) { { "result": "error", "message": { "token": ["error"] } }.as_json } let(:error_response) do HTTPI::Response.new(400, {}, error_response_body) end @@ -16,121 +14,118 @@ let(:distribution) do { - "id": "123232323", - "recipient": { - "type": "person", - "name": "bob joe", - "firstName": "bob", - "middleName": "", - "lastName": "joe", - "participant_id": "123455667", - "poaCode": "", - "claimantStationOfJurisdiction": "" + "id" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "recipient" => { + "type" => "system", + "id" => "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name" => "VBMS-C" }, - "description": "bad", - "communicationPackageId": "", - "destinations": { - "type": "email", - "addressLine1": "", - "addressLine2": "", - "addressLine3": "", - "addressLine4": "", - "addressLine5": "", - "addressLine6": "", - "treatLine2AsAddressee": 0, - "treatLine3AsAddressee": 0, - "city": "", - "state": "", - "postalCode": "", - "countryName": "", - "emailAddress": "", - "phoneNumber": "" + "description" => "Staging Mailing Distribution", + "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations" => { + "type" => "physicalAddress", + "id" => "28440040-51a5-4d2a-81a2-28730827be14", + "status" => "", + "cbcmSendAttemptDate" => "2022-06-06T16:35:27.996", + "addressLine1" => "POSTMASTER GENERAL", + "addressLine2" => "UNITED STATES POSTAL SERVICE", + "addressLine3" => "475 LENFANT PLZ SW RM 10022", + "addressLine4" => "SUITE 123", + "addressLine5" => "APO AE 09001-5275", + "addressLine6" => "", + "treatLine2AsAddressee" => true, + "treatLine3AsAddressee" => true, + "city" => "WASHINGTON DC", + "state" => "DC", + "postalCode" => "12345", + "countryName" => "UNITED STATES", + "countryCode" => "us" }, - "status": "", - "sentToCbcmDate": "" - }.to_json + "status" => "", + "sentToCbcmDate" => "" + }.as_json end let(:distribution_post_request) do { - "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "recipient": { - "type": "system", - "name": "VBMS-C" + "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "recipient" => { + "type" => "system", + "name" => "VBMS-C" }, - "destinations": { - "type": "domesticAddress", - "addressLine1": "123 Test St.", - "addressLine2": "", - "addressLine3": "", - "addressLine4": "", - "addressLine5": "", - "addressLine6": "", - "city": "Anytown", - "postalCode": "12345", - "state": "DC", - "countryName": "United States of America", - "countryCode": "01" + "destinations" => { + "type" => "domesticAddress", + "addressLine1" => "123 Test St.", + "addressLine2" => "", + "addressLine3" => "", + "addressLine4" => "", + "addressLine5" => "", + "addressLine6" => "", + "city" => "Anytown", + "postalCode" => "12345", + "state" => "DC", + "countryName" => "United States of America", + "countryCode" => "01" } - }.to_json + }.as_json end let(:distribution_post_response) do { - "id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "recipient": { - "type": "system", - "id": "2c6592fc-b3af-48ff-8263-c581c2f0a68b", - "name": "VBMS-C" + "id" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "recipient" => { + "type" => "system", + "id" => "2c6592fc-b3af-48ff-8263-c581c2f0a68b", + "name" => "VBMS-C" }, - "description": "Staging Distribution", - "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations": { - "type": "physicalAddress", - "id": "5378bfbd-eff5-470c-bbc4-c7fd3c863a50", - "status": null, - "cbcmSendAttemptDate": "2022-06-06T16:35:28.017", - "addressLine1": "POSTMASTER GENERAL", - "addressLine2": "UNITED STATES POSTAL SERVICE", - "addressLine3": "475 LENFANT PLZ SW RM 10022", - "addressLine4": "SUITE 123", - "addressLine5": "APO AE 09001-5275", - "addressLine6": "", - "treatLine2AsAddressee": false, - "treatLine3AsAddressee": false, - "city": "WASHINGTON DC", - "state": "DC", - "postalCode": "12345", - "countryName": "UNITED STATES", - "countryCode": "us" + "description" => "Staging Distribution", + "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations" => { + "type" => "physicalAddress", + "id" => "5378bfbd-eff5-470c-bbc4-c7fd3c863a50", + "status" => "null", + "cbcmSendAttemptDate" => "2022-06-06T16:35:28.017", + "addressLine1" => "POSTMASTER GENERAL", + "addressLine2" => "UNITED STATES POSTAL SERVICE", + "addressLine3" => "475 LENFANT PLZ SW RM 10022", + "addressLine4" => "SUITE 123", + "addressLine5" => "APO AE 09001-5275", + "addressLine6" => "", + "treatLine2AsAddressee" => false, + "treatLine3AsAddressee" => false, + "city" => "WASHINGTON DC", + "state" => "DC", + "postalCode" => "12345", + "countryName" => "UNITED STATES", + "countryCode" => "us" }, - "status": null, - "sentToCbcmDate": null - }.to_json + "status" => "null", + "sentToCbcmDate" => "null" + }.as_json end let(:package_post_request) do { - "fileNumber": "123456789", - "name": "ABC abc 1234 !*+,-.:;=?", - "documentReferences": { - "id": "3aec91cc-a88d-4b9c-9183-84bed583bbcc", - "copies": 1 + "fileNumber" => "123456789", + "name" => "ABC abc 1234 !*+,-.:;=?", + "documentReferences" => { + "id" => "3aec91cc-a88d-4b9c-9183-84bed583bbcc", + "copies" => 1 } - }.to_json + }.as_json end let(:package_post_response) do { - "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", - "fileNumber": "123456789", - "documentReferences": { - "id": "23233175-6a87-4cd4-b327-f20cf5ef1222", - "copies": 1 + "id" => "24eb6a66-3833-4de6-bea4-4b614e55d5ac", + "fileNumber" => "123456789", + "documentReferences" => { + "id" => "23233175-6a87-4cd4-b327-f20cf5ef1222", + "copies" => 1 }, - "status": "NEW", - "createDate": "" - }.to_json + "status" => "NEW", + "createDate" => "" + }.as_json end let(:get_distribution_success_response) do @@ -150,7 +145,7 @@ it "gets correct distribution" do subject allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) - expect(subject.body.to_json).to eq(get_distribution_success_response) + expect(subject.body.as_json).to eq(get_distribution_success_response.body) end context "not found" do subject { ExternalApi::PacmanService.get_distribution_request("fake") } @@ -169,12 +164,7 @@ end it "successfully sends distribution" do allow(HTTPI).to receive(:post).and_return(post_distribution_success_response) - expect(subject.body.to_json).to eq(post_distribution_success_response) - end - context "not found" do - it "returns 404 PacmanNotFoundError" do - - end + expect(subject.body.as_json).to eq(post_distribution_success_response.body) end end @@ -182,11 +172,11 @@ subject do ExternalApi::PacmanService.send_communication_package_request(package_post_request["file_number"], package_post_request["name"], - package_post_request["document_references"]) + package_post_request["documentReferences"]) end it "successfully sends package" do allow(HTTPI).to receive(:post).and_return(post_package_success_response) - expect(subject.body.to_json).to eq(post_package_success_response) + expect(subject.body.as_json).to include(post_package_success_response.body) end end From 10636667ad0d75351ddbf32815b9486afbc48310 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 10:24:22 -0400 Subject: [PATCH 046/308] Refactored validations in VbmsDistribution --- app/models/vbms_communication_package.rb | 5 ++++- app/models/vbms_distribution.rb | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 48d08d5e35b..f03b9f2b3b6 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - has_one :vbms_uploaded_document + # Changed this association to "belongs_to" instead of "has_one" because FK sits on this table. Is that correct? + # – I also set to optional false, requiring the assocation to an existing vbms_uploaded_document. Is that correct? + belongs_to :vbms_uploaded_document, optional: false + # has_one :vbms_uploaded_document has_many :vbms_distributions validates :file_number, :comm_package_name, :document_referenced, presence: true diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 5e57c7e5ff7..006aa0c9d66 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,17 +1,15 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - # Should this association be "belongs_to" instead of "has_one"? Because FK sits on this table + # Changed this association to "belongs_to" instead of "has_one" because FK sits on this table. Is that correct? belongs_to :vbms_communication_package, optional: false # has_one :vbms_communication_package has_one :vbms_distribution_destination validates :recipient_type, presence: true, inclusion: { in: %w(organization person system ro-colocated)} + validates :first_name, :last_name, presence: true, if: :is_person? validates :name, presence: true, unless: :is_person? - validates :first_name, presence: true, if: :is_person? - validates :last_name, presence: true, if: :is_person? - validates :poa_code, presence: true, if: :is_ro_colocated? - validates :claimant_station_of_jurisdiction, presence: true, if: :is_ro_colocated? + validates :poa_code, :claimant_station_of_jurisdiction, presence: true, if: :is_ro_colocated? def is_person? recipient_type == "person" From d36ceee7372c2d2f330002f7b36a2fecbda3ff90 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 10:29:24 -0400 Subject: [PATCH 047/308] APPEALS-21120 added comments --- app/services/external_api/pacman_service.rb | 38 +++++++++++++++++++++ lib/fakes/pacman_service.rb | 6 ++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 897ae5e5813..d50f422188d 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -14,16 +14,37 @@ class ExternalApi::PacmanService }.freeze class << self + # Purpose: Creates and sends communication package + # POST: /package-manager-service/communication-package + # + # takes in file_number(string), name(string), document_reference(json of strings) + # + # Response: JSON of created package from Pacman API + # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_package_request' method def send_communication_package_request(file_number, name, document_references) request = package_request(file_number, name, document_references) send_pacman_request(request) end + # Purpose: Creates and sends distribution + # POST: /package-manager-service/distribution + # + # takes in package_id(string), recipient(json of strings), destinations(json of strings) + # + # Response: JSON of created distribution from Pacman API + # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_request' method def send_distribution_request(package_id, recipient, destinations) request = distribution_request(package_id, recipient, destinations) send_pacman_request(request) end + # Purpose: Gets distribution from distribution id + # POST: /package-manager-service/distribution + # + # takes in distribution_id(string) + # + # Response: JSON of distribution from Pacman API + # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_response' method def get_distribution_request(distribution_id) request = { endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get @@ -31,6 +52,13 @@ def get_distribution_request(distribution_id) send_pacman_request(request) end + private + + # Purpose: Builds package request + # + # takes in file_number(string), name(string), document_reference(json of strings) + # + # Response: package request hash def package_request(file_number, name, document_reference) request = { body: { @@ -47,6 +75,11 @@ def package_request(file_number, name, document_reference) request end + # Purpose: Builds distribution request + # + # takes in package_id(string), recipient(json of strings), destinations(json of strings) + # + # Response: Distribution request hash def distribution_request(package_id, recipient, destination) request = { body: { @@ -85,6 +118,11 @@ def distribution_request(package_id, recipient, destination) request end + # Purpose: Build and send the request to the server + # + # Params: general requirements for HTTP request + # + # Return: service_response: JSON from Pacman or error def send_pacman_request(query: {}, headers: {}, endpoint:, method: :get, body: nil) url = URI.escape(BASE_URL + endpoint) request = HTTPI::Request.new(url) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 2a1f33ced65..d3ec510753a 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -57,7 +57,7 @@ def distribution_not_found_response # POST: /package-manager-service/communication-package def fake_package_request HTTPI::Response.new( - 200, + 201, {}, OpenStruct.new( "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", @@ -76,7 +76,7 @@ def fake_package_request # POST: /package-manager-service/distribution def fake_distribution_request HTTPI::Response.new( - 200, + 201, {}, OpenStruct.new( "id": "12345", @@ -114,7 +114,6 @@ def fake_distribution_request ) ) end - # rubocop:enable Metrics/MethodLength # GET: /package-manager-service/distribution/{id} def fake_distribution_response(distribution_id) @@ -154,5 +153,6 @@ def fake_distribution_response(distribution_id) ) ) end + # rubocop:enable Metrics/MethodLength end end From 3bcdd06b2024ad6c7cac57916e05fa61ec9fdb65 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 11 May 2023 11:16:35 -0400 Subject: [PATCH 048/308] Appeals-21123 updated create method in upload_vbms_document_controller to utilize distribution/destination params --- .../api/v1/upload_vbms_document_controller.rb | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index f577714b8da..1b2be7c20c0 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,6 +12,11 @@ def bgs end def create + if address_params.present? && recipient_params.present? + MailRequest.new(params) + elsif !address_params.present? || !recipient_params.present? + # log_some_error + end appeal = nil # Find veteran from appeal id and check with db @@ -39,4 +44,37 @@ def create render json: result.errors[0], status: :bad_request end end + + def destination_params + params.permit( + :address_line_1, + :address_line_2, + :address_line_3, + :address_line_4, + :address_line_5, + :address_line_6, + :city, + :country_code, + :postal_code, + :state, + :treat_line_2_as_addressee, + :treat_line_3_as_addressee, + :country_name, + :email_address, + :phone_number + ) + end + + def recipient_params + params.permit( + :recipient_type, + :name, + :first_name, + :middle_name, + :last_name, + :participant_id, + :poa_code, + :claimant_station_of_jurisdiction + ) + end end From fc075899cdf932c3194a63bf430315550470599b Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 11 May 2023 11:19:14 -0400 Subject: [PATCH 049/308] Appeals-21123 updated error.rb, providing a new error type that can be sent back to IDT client. --- lib/caseflow/error.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index cc884eb3af4..75f7c9ef639 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -340,6 +340,7 @@ class MustImplementInSubclass < StandardError; end class AttributeNotLoaded < StandardError; end class VeteranNotFound < StandardError; end class AppealNotFound < StandardError; end + class MissingRecipientInfo < StandardError; end class EstablishClaimFailedInVBMS < StandardError attr_reader :error_code From 140fd4fdb36d4939188fefc279e0feb399259984 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 11 May 2023 11:36:42 -0400 Subject: [PATCH 050/308] linting changes to exiting lines of code. Added new error for use in vbms_document_upload_controller when expected params aren't included --- app/controllers/idt/api/v1/base_controller.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 8b2f72cf16f..df7ed124723 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -16,7 +16,8 @@ class Idt::Api::V1::BaseController < ActionController::Base if error.class.method_defined?(:serialize_response) render(error.serialize_response) else - render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, status: :internal_server_error + render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, + status: :internal_server_error end end # :nocov: @@ -32,7 +33,16 @@ class Idt::Api::V1::BaseController < ActionController::Base log_error(error) uuid = SecureRandom.uuid Rails.logger.error("IDT Standard Error ID: " + uuid) - render(json: { message: "IDT Standard Error ID: " + uuid + " Please enter a file number in the 'FILENUMBER' header" }, status: :unprocessable_entity) + render(json: { message: "IDT Standard Error ID: " + uuid + " Please enter a file number in the 'FILENUMBER' header" }, + status: :unprocessable_entity) + end + + rescue_from Caseflow::Error::MissingRecipientInfo do |error| + log_error(error) + uuid = SecureRandom.uuid + Rails.logger.error("IDT Standard Error ID: " + uuid) + render(json: { message: "IDT Standard Error ID: " + uuid + " Not enough address/recipient information " }, + status: :bad_request) end rescue_from Caseflow::Error::VeteranNotFound do |error| From bbe21c7ecd6ea23e7d6086b185578fc0279cf38e Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 11 May 2023 11:38:21 -0400 Subject: [PATCH 051/308] APPEALS-21123 created new mail_request class that will handle object creation and also keep controller thin. --- app/workflows/mail_request.rb | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 app/workflows/mail_request.rb diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb new file mode 100644 index 00000000000..94fe5f40524 --- /dev/null +++ b/app/workflows/mail_request.rb @@ -0,0 +1,76 @@ +#frozen_string_literal: true + +class MailRequest + include ActiveModel::Model + + # ask about what should be validated... + # Could put them in a frozen array.....only having to reference that in future calls + + EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ + :address_line_1, + :address_line_2, + :address_line_3, + :address_line_4, + :address_line_5, :address_line_6, + :city, + :country_code, + :postal_code, + :state, + :treat_line_2_as_addressee, + :treat_line_3_as_addressee, + :country_name, :email_address, + :phone_number, :recipient_type, + :name, + :first_name, + :middle_name, + :last_name, + :participant_id, + :poa_code, + :claimant_station_of_jurisdiction + ] + + def initialize(params) + @params = params.slice(EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS) + end + + def create_a_vbms_distribution + VbmsDistribution.create(recipient_params_parse) + end + + def create_a_vbms_distribution_destination + VbmsDistributionDestination.create(destination_params_parse) + end + + def destination_params_parse + { + address_line_1: @params.address_line_1, + address_line_2: @params.address_line_2, + address_line_3: @params.address_line_3, + address_line_4: @params.address_line_4, + address_line_5: @params.address_line_5, + address_line_6: @params.address_line_6, + city: @params.city, + country_code: @params.country, + postal_code: @params.postal_code, + state: @params.state, + treat_line_2_as_addressee: @params.treat_line_2_as_addressee, + treat_line_3_as_addressee: @params.treat_line_3_as_addressee, + country_name: @params.country_name, + email_address: @params.email_address, + phone_number: @params.phone_number + } + end + + def recipient_params_parse + { + recipient_type: @params, + name: @params.name, + first_name: @params.first_name, + middle_name: @params.middle_name, + last_name: @params.last_name, + participant_id: @params.participant_id, + poa_code: @params.poa_code, + claimant_station_of_jurisdiction: @params.claimant_station_of_jurisdiction + } + end +end From 222e6c00b88b0a92a1347ab680eab0da746b9481 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 12:20:52 -0400 Subject: [PATCH 052/308] Completed validations for VbmsDistributionDestination --- app/models/vbms_communication_package.rb | 13 ------ app/models/vbms_distribution_destination.rb | 46 ++++++++++++++++++++- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index f03b9f2b3b6..133d694591a 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -15,17 +15,4 @@ class VbmsCommunicationPackage < CaseflowRecord # - if you try and store object with "id" and "copies" keys into db it will be converted to nil object # - need to solve before being able to validate "id" and "copies" validates :document_referenced, length: { minimum: 1 } - - # This validation currently takes place in PrepareDocumentUploadToVbms... any reason it would need to take place again in model? - validate :file_number_matches_bgs - - def bgs_service - @bgs_service || BGSService.new - end - - def file_number_matches_bgs - if bgs_service.fetch_veteran_info(file_number).nil? - errors.add(:file_number, "does not match a valid veteran file number") - end - end end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 8e4fe661d94..8a60a0d3c7d 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,5 +1,49 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - belongs_to :vbms_distribution + belongs_to :vbms_distribution, optional: false + + with_options presence: true do + validates :destination_type, inclusion: { in: %w(domesticAddress internationalAddress militaryAddress derived email sms) } + validates :address_line_1, :city, :country_code, if: :is_physical_mail? + validates :address_line_2, if: :treat_line_2_as_addressee + validates :address_line_3, if: :treat_line_3_as_addressee + validates :state, :postal_code, if: :is_us_address? + validates :country_name, if: -> { destination_type == "internationalAddress" } + validates :email_address, if: -> { destination_type == "email" } + validates :phone_number, if: -> { destination_type == "sms" } + end + + validate :is_valid_country_code?, if: :is_physical_mail? + validate :is_valid_us_state_code?, if: :is_us_address? + + def is_physical_mail? + %w(domesticAddress internationalAddress militaryAddress).include?(destination_type) + end + + def is_us_address? + %w(domesticAddress militaryAddress).include?(destination_type) + end + + def is_valid_country_code? + unless iso_country_codes.include?(country_code) + errors.add(:country_code, "is not a valid ISO 3166-2 code") + end + end + + def is_valid_us_state_code? + unless iso_us_state_codes.include?(state) + errors.add(:state, "is not a valid ISO 3166-2 code") + end + end + + # Are these country and state codes available in a hard coded constant? + + def iso_country_codes + @iso_country_codes ||= ISO3166::Country.codes + end + + def iso_us_state_codes + @iso_us_state_codes ||= ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys + end end From 6a9e0c605252eb8d328ec6273f7aca09b2af1f90 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 12:28:14 -0400 Subject: [PATCH 053/308] Refactored VbmsDistribution --- app/models/vbms_distribution.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 006aa0c9d66..04065974fbc 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -6,10 +6,12 @@ class VbmsDistribution < CaseflowRecord # has_one :vbms_communication_package has_one :vbms_distribution_destination - validates :recipient_type, presence: true, inclusion: { in: %w(organization person system ro-colocated)} - validates :first_name, :last_name, presence: true, if: :is_person? - validates :name, presence: true, unless: :is_person? - validates :poa_code, :claimant_station_of_jurisdiction, presence: true, if: :is_ro_colocated? + with_options presence: true do + validates :recipient_type, inclusion: { in: %w(organization person system ro-colocated)} + validates :first_name, :last_name, if: :is_person? + validates :name, unless: :is_person? + validates :poa_code, :claimant_station_of_jurisdiction, if: :is_ro_colocated? + end def is_person? recipient_type == "person" From 810914378e54737ea08062203c6f88b4d01ce523 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 14:11:53 -0400 Subject: [PATCH 054/308] Removed comments --- app/models/vbms_communication_package.rb | 8 +------- app/models/vbms_distribution.rb | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 133d694591a..16d38e887e2 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,18 +1,12 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - # Changed this association to "belongs_to" instead of "has_one" because FK sits on this table. Is that correct? - # – I also set to optional false, requiring the assocation to an existing vbms_uploaded_document. Is that correct? belongs_to :vbms_uploaded_document, optional: false - # has_one :vbms_uploaded_document has_many :vbms_distributions validates :file_number, :comm_package_name, :document_referenced, presence: true - - # PacMan docs suggested multiline ^ and $ anchors for regex, but I changed to \A and \Z as suggested by rails log validates :comm_package_name, format: { with: /\A[\w !*+,-.:;=?]{1,225}\Z/ } # document_referenced has current data type of array of bigint values - # - if you try and store object with "id" and "copies" keys into db it will be converted to nil object # - need to solve before being able to validate "id" and "copies" - validates :document_referenced, length: { minimum: 1 } + # validates :document_referenced, length: { minimum: 1 } end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 04065974fbc..c35091a913a 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - # Changed this association to "belongs_to" instead of "has_one" because FK sits on this table. Is that correct? belongs_to :vbms_communication_package, optional: false - # has_one :vbms_communication_package has_one :vbms_distribution_destination with_options presence: true do From 7fa7c1ba1dd769674db58f9d85cdc001e6906451 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 14:38:23 -0400 Subject: [PATCH 055/308] APPEALS-21120 updated rspec and fake --- lib/fakes/pacman_service.rb | 11 ++++++----- spec/services/external_api/pacman_service_spec.rb | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index d3ec510753a..98481bb1198 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -13,10 +13,11 @@ def send_distribution_request(package_id, recipient, destinations) end def get_distribution_request(distribution_id) - request = { - endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get - } - fake_distribution_response(request) + if distribution_id != "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431" + return distribution_not_found_response + end + + fake_distribution_response(distribution_id) end private @@ -132,7 +133,7 @@ def fake_distribution_response(distribution_id) "destinations": { "type": "physicalAddress", "id": "28440040-51a5-4d2a-81a2-28730827be14", - "status": null, + "status": "", "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", "addressLine1": "POSTMASTER GENERAL", "addressLine2": "UNITED STATES POSTAL SERVICE", diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index f442bc8c959..c731f305d90 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -141,17 +141,17 @@ end context "get distribution" do - subject { ExternalApi::PacmanService.get_distribution_request(distribution["id"]) } + subject { Fakes::PacmanService.get_distribution_request(distribution["id"]) } it "gets correct distribution" do subject allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) - expect(subject.body.as_json).to eq(get_distribution_success_response.body) + expect(subject.body.as_json["table"]).to eq(get_distribution_success_response.body) end context "not found" do - subject { ExternalApi::PacmanService.get_distribution_request("fake") } + subject { Fakes::PacmanService.get_distribution_request("fake") } it "returns 404 PacmanNotFoundError" do allow(HTTPI).to receive(:get).and_return(not_found_response) - expect { subject }.to raise_error Caseflow::Error::PacmanNotFoundError + expect(subject.code).to eq(not_found_response.code) end end end @@ -186,14 +186,14 @@ context "400" do it "throws Caseflow::Error::PacmanBadRequestError" do allow(HTTPI).to receive(:get).and_return(error_response) - expect { subject }.to raise_error Caseflow::Error::PacmanBadRequestError + expect(subject).to eq(error_response) end end context "403" do it "throws Caseflow::Error::PacmanForbiddenError" do allow(HTTPI).to receive(:get).and_return(forbidden_response) - expect { subject }.to raise_error Caseflow::Error::PacmanForbiddenError + expect(subject).to eq(forbidden_response) end end end From e41fb716e4c29d8fa39c9904f324f658f660baa2 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 14:53:33 -0400 Subject: [PATCH 056/308] APPEALS-21118 created job file --- app/jobs/mail_request_job.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 app/jobs/mail_request_job.rb diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb new file mode 100644 index 00000000000..38b909e70b5 --- /dev/null +++ b/app/jobs/mail_request_job.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# This job syncs an EndProductEstablishment (end product manager) with up to date BGS and VBMS data +class MailRequestJob < CaseflowJob + queue_with_priority :low_priority + application_attr :intake + + def perform(vbms_comm_package) + ExternalApi:: + end +end From 084cab358b9cec8d448288aaf61f5e8fd0bb953e Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 15:00:55 -0400 Subject: [PATCH 057/308] APPEALS-21120 fixed typo --- lib/fakes/pacman_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 98481bb1198..f84a5ea34a5 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -3,12 +3,12 @@ class Fakes::PacmanService < ExternalApi::PacmanService class << self def send_communication_package_request(file_number, name, document_references) - request = package_request(file_number, name, document_reference) + request = package_request(file_number, name, document_references) fake_package_request(request) end def send_distribution_request(package_id, recipient, destinations) - request = distribution_request(package_id, recipient, destination) + request = distribution_request(package_id, recipient, destinations) fake_distribution_request(request) end From 0ab95adc454b80d76d8ba76e24c834a2ce92b17c Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 15:26:16 -0400 Subject: [PATCH 058/308] APPEALS-21120 fixed fake --- lib/fakes/pacman_service.rb | 49 ++++++++----------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index f84a5ea34a5..45c282b24a6 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -3,13 +3,11 @@ class Fakes::PacmanService < ExternalApi::PacmanService class << self def send_communication_package_request(file_number, name, document_references) - request = package_request(file_number, name, document_references) - fake_package_request(request) + fake_package_request(file_number, name, document_references) end def send_distribution_request(package_id, recipient, destinations) - request = distribution_request(package_id, recipient, destinations) - fake_distribution_request(request) + fake_distribution_request(package_id, recipient, destinations) end def get_distribution_request(distribution_id) @@ -56,17 +54,15 @@ def distribution_not_found_response end # POST: /package-manager-service/communication-package - def fake_package_request + def fake_package_request(file_number, name, document_references) HTTPI::Response.new( 201, {}, OpenStruct.new( "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", - "fileNumber": "123456789", - "documentReferences": { - "id": "23233175-6a87-4cd4-b327-f20cf5ef1222", - "copies": 1 - }, + "fileNumber": file_number, + "name": name, + "documentReferences": document_references, "status": "NEW", "createDate": "" ) @@ -75,41 +71,16 @@ def fake_package_request # rubocop:disable Metrics/MethodLength # POST: /package-manager-service/distribution - def fake_distribution_request + def fake_distribution_request(package_id, recipient, destinations) HTTPI::Response.new( 201, {}, OpenStruct.new( "id": "12345", - "recipient": { - "type": "person", - "name": "bob joe", - "firstName": "bob", - "middleName": "", - "lastName": "joe", - "participant_id": "123455667", - "poaCode": "", - "claimantStationOfJurisdiction": "" - }, + "recipient": recipient, "description": "bad", - "communicationPackageId": "", - "destinations": { - "type": "email", - "addressLine1": "", - "addressLine2": "", - "addressLine3": "", - "addressLine4": "", - "addressLine5": "", - "addressLine6": "", - "treatLine2AsAddressee": 0, - "treatLine3AsAddressee": 0, - "city": "", - "state": "", - "postalCode": "", - "countryName": "", - "emailAddress": "", - "phoneNumber": "" - }, + "communicationPackageId": package_id, + "destinations": destinations, "status": "", "sentToCbcmDate": "" ) From 98af93f04dc22a9b057af43bbc01dcc53bdfecbd Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 15:31:29 -0400 Subject: [PATCH 059/308] Updated regex for comm_package_name --- app/models/vbms_communication_package.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 16d38e887e2..0906fc52477 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -4,7 +4,7 @@ class VbmsCommunicationPackage < CaseflowRecord has_many :vbms_distributions validates :file_number, :comm_package_name, :document_referenced, presence: true - validates :comm_package_name, format: { with: /\A[\w !*+,-.:;=?]{1,225}\Z/ } + validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } # document_referenced has current data type of array of bigint values # - need to solve before being able to validate "id" and "copies" From 6d9818acb44797df9a7c5ce5a66b4fb335990535 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 15:48:26 -0400 Subject: [PATCH 060/308] APPEALS-21118 added pacman calls --- app/jobs/mail_request_job.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 38b909e70b5..8b7c1f91d98 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -6,6 +6,9 @@ class MailRequestJob < CaseflowJob application_attr :intake def perform(vbms_comm_package) - ExternalApi:: + package = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, + vbms_comm_package.comm_package_name, + vbms_comm_package.document_referenced) + distribution = ExternalApi::PacmanService.send_distribution_request(package_id, recipient, destinations) end end From 908ad26f94f0bda14f085326633c554dc502435c Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 11 May 2023 15:53:25 -0400 Subject: [PATCH 061/308] APPEALS-21120 added comments to response --- app/services/external_api/pacman_service/response.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb index 1e35a914f4a..139fb50ec87 100644 --- a/app/services/external_api/pacman_service/response.rb +++ b/app/services/external_api/pacman_service/response.rb @@ -10,14 +10,17 @@ def initialize(resp) def data; end + # Wrapper method to check for errors def error check_for_error end + # Checks if there is no error def success? !resp.error? end + # Parses response body to an object def body @body ||= begin JSON.parse(resp.body) @@ -28,6 +31,7 @@ def body private + # Error codes and their associated error ERROR_LOOKUP = { 400 => Caseflow::Error::PacmanBadRequestError, 403 => Caseflow::Error::PacmanForbiddenError, @@ -35,6 +39,7 @@ def body 500 => Caseflow::Error::PacmanInternalServerError }.freeze + # Checks for error and returns if found def check_for_error return if success? @@ -47,6 +52,7 @@ def check_for_error end end + # Gets the error message from the response def error_message return "No error message from Pacman" if body.empty? From fa3eba0ca3edb380ca9dd131e2f976040c798540 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Thu, 11 May 2023 15:58:51 -0400 Subject: [PATCH 062/308] APPEALS-21119 Closed all connections at end of executable rb files --- db/scripts/audit/create_caseflow_audit_schema.rb | 1 + .../functions/add_row_to_appeal_states_audit_table_function.rb | 1 + ...dd_row_to_vbms_communication_packages_audit_table_function.rb | 1 + ...row_to_vbms_distribution_destinations_audit_table_function.rb | 1 + .../add_row_to_vbms_distributions_audit_table_function.rb | 1 + .../add_row_to_vbms_uploaded_documents_audit_table_function.rb | 1 + db/scripts/audit/remove_caseflow_audit_schema.rb | 1 + db/scripts/audit/tables/create_appeal_states_audit.rb | 1 + .../audit/tables/create_vbms_communication_packages_audit.rb | 1 + .../audit/tables/create_vbms_distribution_destinations_audit.rb | 1 + db/scripts/audit/tables/create_vbms_distributions_audit.rb | 1 + db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb | 1 + db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb | 1 + .../triggers/create_vbms_communication_packages_audit_trigger.rb | 1 + .../create_vbms_distribution_destinations_audit_trigger.rb | 1 + .../audit/triggers/create_vbms_distributions_audit_trigger.rb | 1 + .../triggers/create_vbms_uploaded_documents_audit_trigger.rb | 1 + 17 files changed, 17 insertions(+) diff --git a/db/scripts/audit/create_caseflow_audit_schema.rb b/db/scripts/audit/create_caseflow_audit_schema.rb index 034de127e11..fc70b54e1a8 100644 --- a/db/scripts/audit/create_caseflow_audit_schema.rb +++ b/db/scripts/audit/create_caseflow_audit_schema.rb @@ -4,3 +4,4 @@ conn = CaseflowRecord.connection conn.execute("create schema caseflow_audit;") +conn.close diff --git a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb index ec98d929ba0..34ce8582389 100644 --- a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb @@ -20,3 +20,4 @@ $appeal_states_audit$ language plpgsql;" ) +conn.close diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index 3810f3ff895..df370785325 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -20,3 +20,4 @@ $add_row$ language plpgsql;" ) +conn.close diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index afcd1f4ecea..a2e69fb7fce 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -20,3 +20,4 @@ $add_row$ language plpgsql;" ) +conn.close diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 52c3d07ba8c..19d015d4162 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -20,3 +20,4 @@ $add_row$ language plpgsql;" ) +conn.close diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb index 029e7e051ee..b59a54de15e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb @@ -20,3 +20,4 @@ $add_row$ language plpgsql;" ) +conn.close diff --git a/db/scripts/audit/remove_caseflow_audit_schema.rb b/db/scripts/audit/remove_caseflow_audit_schema.rb index 78df1a206aa..344617e8aa8 100644 --- a/db/scripts/audit/remove_caseflow_audit_schema.rb +++ b/db/scripts/audit/remove_caseflow_audit_schema.rb @@ -6,3 +6,4 @@ conn.execute( "drop schema IF EXISTS caseflow_audit CASCADE;" ) +conn.close diff --git a/db/scripts/audit/tables/create_appeal_states_audit.rb b/db/scripts/audit/tables/create_appeal_states_audit.rb index b72634dabc8..6a8c61dc23a 100644 --- a/db/scripts/audit/tables/create_appeal_states_audit.rb +++ b/db/scripts/audit/tables/create_appeal_states_audit.rb @@ -25,3 +25,4 @@ vso_ihp_complete boolean not null, vso_ihp_pending boolean not null );") +conn.close diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index df1bdc0142f..f7aaa1b5156 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -17,3 +17,4 @@ created_by_id int8 NULL, updated_by_id int8 NULL );") +conn.close diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index a44300f6076..48664479ef3 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -29,3 +29,4 @@ created_by_id int8 NULL, updated_by_id int8 NULL );") +conn.close diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index c98bfc16c9f..e61e3eed950 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -21,3 +21,4 @@ created_by_id int8 NULL, updated_by_id int8 NULL );") +conn.close diff --git a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb index c8c916cef43..511b1da5da8 100644 --- a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb +++ b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb @@ -23,3 +23,4 @@ uploaded_to_vbms_at timestamp NULL, veteran_file_number varchar NULL );") +conn.close diff --git a/db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb b/db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb index 29b9b32a5a6..08c226671ce 100644 --- a/db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb @@ -9,3 +9,4 @@ for each row execute procedure caseflow_audit.add_row_to_appeal_states_audit();" ) +conn.close diff --git a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb index 0e6e50a6dd3..fee24fae47b 100644 --- a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb @@ -9,3 +9,4 @@ for each row execute procedure caseflow_audit.add_row_to_vbms_communication_packages_audit();" ) +conn.close diff --git a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb index be3900be339..d118a5e982f 100644 --- a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb @@ -9,3 +9,4 @@ for each row execute procedure caseflow_audit.add_row_to_vbms_distribution_destinations_audit();" ) +conn.close diff --git a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb index 03e23e413cd..77a47db6060 100644 --- a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb @@ -9,3 +9,4 @@ for each row execute procedure caseflow_audit.add_row_to_vbms_distributions_audit();" ) +conn.close diff --git a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb index 95ce9a8c00d..6856ec44376 100644 --- a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb +++ b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb @@ -9,3 +9,4 @@ for each row execute procedure caseflow_audit.add_row_to_vbms_uploaded_documents_audit();" ) +conn.close From 5de386f17879ffa5f60afc93fbf8754d84ca4d4b Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 16:10:06 -0400 Subject: [PATCH 063/308] Created unit tests for VbmsCommunicationPackage --- .../models/vbms_communication_package_spec.rb | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index ba47c52555f..ae30c83687c 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -1,5 +1,41 @@ # frozen_string_literal: true describe VbmsCommunicationPackage, :postgres do + let(:package) do + VbmsCommunicationPackage.new( + file_number: "329780002", + comm_package_name: "Test Package Name", + vbms_uploaded_document: VbmsUploadedDocument.new(document_type: "Test Doc Type") + ) + end + it "is valid with valid attributes" do + expect(package).to be_valid + end + + it "is not valid without a filenumber" do + package.filenumber = nil + expect(package).to_not be_valid + + package.filenumber = "" + expect(package).to_not be_valid + end + + it "is not valid without a communication package name" do + package.comm_package_name = nil + expect(package).to_not be_valid + + package.comm_package_name = "" + expect(package).to_not be_valid + end + + it "is not valid if communication package name exceeds 255 characters" do + package.comm_package_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + expect(package).to_not be_valid + end + + it "is not valid without a user friendly communication package name" do + package.comm_package_name = "(Test Package Name)" + expect(package).to_not be_valid + end end From 45c1c8118a505b09620f0ef3f391edeec6932a24 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 11 May 2023 17:02:07 -0400 Subject: [PATCH 064/308] Updated unit tests for VbmsCommunicationPackage and completed unit tests for VbmsDistribution --- .../models/vbms_communication_package_spec.rb | 15 +- spec/models/vbms_distribution_spec.rb | 147 ++++++++++++++++++ 2 files changed, 159 insertions(+), 3 deletions(-) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index ae30c83687c..39d6d712a79 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -5,7 +5,7 @@ VbmsCommunicationPackage.new( file_number: "329780002", comm_package_name: "Test Package Name", - vbms_uploaded_document: VbmsUploadedDocument.new(document_type: "Test Doc Type") + vbms_uploaded_document: class_double(VbmsUploadedDocument) ) end @@ -13,18 +13,22 @@ expect(package).to be_valid end - it "is not valid without a filenumber" do + it "is not valid with nil filenumber" do package.filenumber = nil expect(package).to_not be_valid + end + it "is not valid with empty string as filenumber" do package.filenumber = "" expect(package).to_not be_valid end - it "is not valid without a communication package name" do + it "is not valid with nil communication package name" do package.comm_package_name = nil expect(package).to_not be_valid + end + it "is not valid with empty string as communication package name" do package.comm_package_name = "" expect(package).to_not be_valid end @@ -38,4 +42,9 @@ package.comm_package_name = "(Test Package Name)" expect(package).to_not be_valid end + + it "is not valid without an associated VbmsUploadedDocument" do + package.vbms_uploaded_document = nil + expect(package).to_not be_valid + end end diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 8e9f7c15fa2..a2a8eedbf30 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -1,5 +1,152 @@ # frozen_string_literal: true describe VbmsDistribution, :postgres do + let(:package) { class_double(VbmsCommunicationPackage) } + context "recipient type is nil or incorrect" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: nil, + vbms_communication_package: package, + first_name: "First", + last_name: "Last" + ) + end + + it "is not valid with nil recipient type" do + expect(distribution).to_not be_valid + end + + it "is not valid with incorrect recipient type" do + distribution.recipient_type = "Person" + expect(distribution).to_not be_valid + end + end + + context "recipient is person" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: "person", + vbms_communication_package: package, + first_name: "First", + last_name: "Last" + ) + end + + it "is valid person with valid attributes" do + expect(distribution).to be_valid + end + + it "is not valid with nil first name" do + distribution.first_name = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as first name" do + distribution.first_name = "" + expect(distribution).to be_valid + end + + it "is not valid with nil last name" do + distribution.first_name = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as last name" do + distribution.first_name = "" + expect(distribution).to be_valid + end + end + + context "recipient is organization" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: "organization", + vbms_communication_package: package, + name: "Organization" + ) + end + + it "is valid organization with valid attributes" do + expect(distribution).to be_valid + end + + it "is not valid with nil name" do + distribution.name = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as name" do + distribution.name = "" + expect(distribution).to be_valid + end + end + + context "recipient is system" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: "system", + vbms_communication_package: package, + name: "System" + ) + end + + it "is valid system with valid attributes" do + expect(distribution).to be_valid + end + + it "is not valid with nil name" do + distribution.name = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as name" do + distribution.name = "" + expect(distribution).to be_valid + end + end + + context "recipient is ro-colocated" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: "ro-colocated", + vbms_communication_package: package, + name: "Ro-Colocated" + ) + end + + it "is valid ro-colocated with valid attributes" do + expect(distribution).to be_valid + end + + it "is not valid with nil name" do + distribution.name = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as name" do + distribution.name = "" + expect(distribution).to be_valid + end + + it "is not valid with nil poa code" do + distribution.poa_code = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as poa code" do + distribution.poa_code = "" + expect(distribution).to be_valid + end + + it "is not valid with nil claimant station of jurisdiction" do + distribution.claimant_station_of_jurisdiction = nil + expect(distribution).to be_valid + end + + it "is not valid with empty string as claimant station of jurisdiction" do + distribution.claimant_station_of_jurisdiction = "" + expect(distribution).to be_valid + end + end end From 0f1df2b4f831b98ebd3b080aebb72247f37ba153 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 10:40:38 -0400 Subject: [PATCH 065/308] Refactored unit tests for VbmsCommunicationPackage --- .../models/vbms_communication_package_spec.rb | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 39d6d712a79..8395fa1f4d0 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -4,7 +4,7 @@ let(:package) do VbmsCommunicationPackage.new( file_number: "329780002", - comm_package_name: "Test Package Name", + comm_package_name: "test package name", vbms_uploaded_document: class_double(VbmsUploadedDocument) ) end @@ -13,33 +13,25 @@ expect(package).to be_valid end - it "is not valid with nil filenumber" do + it "is not valid without a filenumber" do package.filenumber = nil expect(package).to_not be_valid end - it "is not valid with empty string as filenumber" do - package.filenumber = "" - expect(package).to_not be_valid - end - - it "is not valid with nil communication package name" do + it "is not valid without a communication package name" do package.comm_package_name = nil expect(package).to_not be_valid end - it "is not valid with empty string as communication package name" do - package.comm_package_name = "" - expect(package).to_not be_valid - end - it "is not valid if communication package name exceeds 255 characters" do - package.comm_package_name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + invalid_package_name = "" + 256.times { invalid_package_name << "x" } + package.comm_package_name = invalid_package_name expect(package).to_not be_valid end it "is not valid without a user friendly communication package name" do - package.comm_package_name = "(Test Package Name)" + package.comm_package_name = "(test package name with parentheses)" expect(package).to_not be_valid end From efd14391a32d508d372fb82597e9986ce1b50a05 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 11:48:43 -0400 Subject: [PATCH 066/308] Refactored VbmsDistribution unit tests --- spec/models/vbms_distribution_spec.rb | 55 +++++---------------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index a2a8eedbf30..8c29fca8b5c 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -13,7 +13,7 @@ ) end - it "is not valid with nil recipient type" do + it "is not valid without a recipient type" do expect(distribution).to_not be_valid end @@ -23,7 +23,7 @@ end end - context "recipient is person" do + context "recipient type is person" do let(:distribution) do VbmsDistribution.new( recipient_type: "person", @@ -37,28 +37,18 @@ expect(distribution).to be_valid end - it "is not valid with nil first name" do + it "is not valid without a first name" do distribution.first_name = nil expect(distribution).to be_valid end - it "is not valid with empty string as first name" do - distribution.first_name = "" - expect(distribution).to be_valid - end - - it "is not valid with nil last name" do + it "is not valid without a last name" do distribution.first_name = nil expect(distribution).to be_valid end - - it "is not valid with empty string as last name" do - distribution.first_name = "" - expect(distribution).to be_valid - end end - context "recipient is organization" do + context "recipient type is organization" do let(:distribution) do VbmsDistribution.new( recipient_type: "organization", @@ -71,15 +61,10 @@ expect(distribution).to be_valid end - it "is not valid with nil name" do + it "is not valid without a name" do distribution.name = nil expect(distribution).to be_valid end - - it "is not valid with empty string as name" do - distribution.name = "" - expect(distribution).to be_valid - end end context "recipient is system" do @@ -95,15 +80,10 @@ expect(distribution).to be_valid end - it "is not valid with nil name" do + it "is not valid without a name" do distribution.name = nil expect(distribution).to be_valid end - - it "is not valid with empty string as name" do - distribution.name = "" - expect(distribution).to be_valid - end end context "recipient is ro-colocated" do @@ -119,34 +99,19 @@ expect(distribution).to be_valid end - it "is not valid with nil name" do + it "is not valid without a name" do distribution.name = nil expect(distribution).to be_valid end - it "is not valid with empty string as name" do - distribution.name = "" - expect(distribution).to be_valid - end - - it "is not valid with nil poa code" do + it "is not valid without a poa code" do distribution.poa_code = nil expect(distribution).to be_valid end - it "is not valid with empty string as poa code" do - distribution.poa_code = "" - expect(distribution).to be_valid - end - - it "is not valid with nil claimant station of jurisdiction" do + it "is not valid without a claimant station of jurisdiction" do distribution.claimant_station_of_jurisdiction = nil expect(distribution).to be_valid end - - it "is not valid with empty string as claimant station of jurisdiction" do - distribution.claimant_station_of_jurisdiction = "" - expect(distribution).to be_valid - end end end From 7eddca27aaa4d64c67ae2e053feceaf67c7b923d Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 12:41:50 -0400 Subject: [PATCH 067/308] Completed unit tests for VbmsDistributionDestination --- .../vbms_distribution_destination_spec.rb | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 3d9e41d2146..e47d6f77e18 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -1,5 +1,183 @@ # frozen_string_literal: true describe VbmsDistributionDestination, :postgres do + let(:distribution) { class_double(VbmsDistribution) } + context "destination type is nil or incorrect" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: nil, + vbms_distribution: distribution, + ) + end + + it "is not valid without a destination type" do + expect(destination).to_not be_valid + end + + it "is not valid with incorrect destination type" do + destination.recipient_type = "DomesticAddress" + expect(destination).to_not be_valid + end + end + + context "destination type is domesticAddress" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "domesticAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + state: "NY", + postal_code: "11385", + country_code: "US" + ) + end + + it "is valid with valid attributes" do + expect(destination).to be_valid + end + + it "is not valid without an associated VbmsDistribution" do + destination.vbms_distribution = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 1" do + destination.address_line_1 = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 2 if treat_line_2_as_addressee is true" do + destination.treat_line_2_as_addressee = true + destination.address_line_2 = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 3 if treat_line_3_as_addressee is true" do + destination.treat_line_3_as_addressee = true + destination.address_line_3 = nil + expect(destination).to_not be_valid + end + + it "is not valid without a city" do + destination.city = nil + expect(destination).to_not be_valid + end + + it "is not valid without a state" do + destination.state = nil + expect(destination).to_not be_valid + end + + it "is not valid without a two-letter ISO 3166-2 state code" do + destination.state = "XX" + expect(destination).to_not be_valid + end + + it "is not valid without a postal code" do + destination.postal_code = nil + expect(destination).to_not be_valid + end + + it "is not valid without a country code" do + destination.country_code = nil + expect(destination).to_not be_valid + end + + it "is not valid without a two-letter ISO 3166-2 country code" do + destination.country_code = "XX" + expect(destination).to_not be_valid + end + end + + context "destination type is internationalAddress" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "internationalAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + country_name: "France", + country_code: "FR" + ) + end + + it "is valid with valid attributes" do + expect(destination).to be_valid + end + + it "is not valid without an associated VbmsDistribution" do + destination.vbms_distribution = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 1" do + destination.address_line_1 = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 2 if treat_line_2_as_addressee is true" do + destination.treat_line_2_as_addressee = true + destination.address_line_2 = nil + expect(destination).to_not be_valid + end + + it "is not valid without an address line 3 if treat_line_3_as_addressee is true" do + destination.treat_line_3_as_addressee = true + destination.address_line_3 = nil + expect(destination).to_not be_valid + end + + it "is not valid without a city" do + destination.city = nil + expect(destination).to_not be_valid + end + + it "is not valid without a country name" do + destination.country_name = nil + expect(destination).to_not be_valid + end + + it "is not valid without a two-letter ISO 3166-2 country code" do + destination.country_code = "XX" + expect(destination).to_not be_valid + end + end + + context "destination type is email" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "email", + email_address: "email@email.com" + ) + end + + it "is valid with valid attributes" do + expect(destination).to be_valid + end + + it "is invalid without an email address" do + destination.email_address = nil + expect(destination).to_not be_valid + end + end + + context "destination type is sms" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "sms", + phone_number: "555-5555" + ) + end + + it "is valid with valid attributes" do + expect(destination).to be_valid + end + + it "is invalid without a phone number" do + destination.phone_number = nil + expect(destination).to_not be_valid + end + end end From 36bdd96930c81951fba1883913b0fe8af4a81490 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 14:15:26 -0400 Subject: [PATCH 068/308] Refactored VbmsDistribution with shared examples --- spec/models/vbms_distribution_spec.rb | 47 ++++++++++++--------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 8c29fca8b5c..109a18312c3 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -23,6 +23,12 @@ end end + shared_examples "distribution has valid attributes" do + it "is valid with valid attributes" do + expect(distribution).to be_valid + end + end + context "recipient type is person" do let(:distribution) do VbmsDistribution.new( @@ -33,9 +39,7 @@ ) end - it "is valid person with valid attributes" do - expect(distribution).to be_valid - end + include_examples "distribution has valid attributes" it "is not valid without a first name" do distribution.first_name = nil @@ -48,6 +52,13 @@ end end + shared_examples "recipient type is not person" do + it "is not valid without a name" do + distribution.name = nil + expect(distribution).to be_valid + end + end + context "recipient type is organization" do let(:distribution) do VbmsDistribution.new( @@ -57,14 +68,8 @@ ) end - it "is valid organization with valid attributes" do - expect(distribution).to be_valid - end - - it "is not valid without a name" do - distribution.name = nil - expect(distribution).to be_valid - end + include_examples "distribution has valid attributes" + include_examples "recipient type is not person" end context "recipient is system" do @@ -76,14 +81,8 @@ ) end - it "is valid system with valid attributes" do - expect(distribution).to be_valid - end - - it "is not valid without a name" do - distribution.name = nil - expect(distribution).to be_valid - end + include_examples "distribution has valid attributes" + include_examples "recipient type is not person" end context "recipient is ro-colocated" do @@ -95,14 +94,8 @@ ) end - it "is valid ro-colocated with valid attributes" do - expect(distribution).to be_valid - end - - it "is not valid without a name" do - distribution.name = nil - expect(distribution).to be_valid - end + include_examples "distribution has valid attributes" + include_examples "recipient type is not person" it "is not valid without a poa code" do distribution.poa_code = nil From ccd77797380cb615f748fe39e4b14504e3891613 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 14:55:59 -0400 Subject: [PATCH 069/308] Refactored unit tests for VbmsDistributionDestinaiton and VbmsDistribution --- .../vbms_distribution_destination_spec.rb | 113 ++++++++---------- spec/models/vbms_distribution_spec.rb | 15 ++- 2 files changed, 62 insertions(+), 66 deletions(-) diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index e47d6f77e18..637199619f9 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -21,28 +21,18 @@ end end - context "destination type is domesticAddress" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: "domesticAddress", - vbms_distribution: distribution, - address_line_1: "address line 1", - city: "city", - state: "NY", - postal_code: "11385", - country_code: "US" - ) - end - + shared_examples "destination has valid attributes and associations" do it "is valid with valid attributes" do - expect(destination).to be_valid + expect(distribution).to be_valid end it "is not valid without an associated VbmsDistribution" do destination.vbms_distribution = nil expect(destination).to_not be_valid end + end + share_examples "destination is a physical mailing address" do it "is not valid without an address line 1" do destination.address_line_1 = nil expect(destination).to_not be_valid @@ -65,6 +55,18 @@ expect(destination).to_not be_valid end + it "is not valid without a country code" do + destination.country_code = nil + expect(destination).to_not be_valid + end + + it "is not valid without a two-letter ISO 3166-2 country code" do + destination.country_code = "XX" + expect(destination).to_not be_valid + end + end + + shared_examples "destination is a US address" do it "is not valid without a state" do destination.state = nil expect(destination).to_not be_valid @@ -79,16 +81,42 @@ destination.postal_code = nil expect(destination).to_not be_valid end + end - it "is not valid without a country code" do - destination.country_code = nil - expect(destination).to_not be_valid + context "destination type is domesticAddress" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "domesticAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + state: "NY", + postal_code: "11385", + country_code: "US" + ) end - it "is not valid without a two-letter ISO 3166-2 country code" do - destination.country_code = "XX" - expect(destination).to_not be_valid + include_examples "destination has valid attributes and associations" + include_examples "destination is a physical mailing address" + includes_examples "destination is a US address" + end + + context "destination type is militaryAddress" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "militaryAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + state: "NY", + postal_code: "11385", + country_code: "US" + ) end + + include_examples "destination has valid attributes and associations" + include_examples "destination is a physical mailing address" + includes_examples "destination is a US address" end context "destination type is internationalAddress" do @@ -103,46 +131,13 @@ ) end - it "is valid with valid attributes" do - expect(destination).to be_valid - end - - it "is not valid without an associated VbmsDistribution" do - destination.vbms_distribution = nil - expect(destination).to_not be_valid - end - - it "is not valid without an address line 1" do - destination.address_line_1 = nil - expect(destination).to_not be_valid - end - - it "is not valid without an address line 2 if treat_line_2_as_addressee is true" do - destination.treat_line_2_as_addressee = true - destination.address_line_2 = nil - expect(destination).to_not be_valid - end - - it "is not valid without an address line 3 if treat_line_3_as_addressee is true" do - destination.treat_line_3_as_addressee = true - destination.address_line_3 = nil - expect(destination).to_not be_valid - end - - it "is not valid without a city" do - destination.city = nil - expect(destination).to_not be_valid - end + include_examples "destination has valid attributes and associations" + include_examples "destination is a physical mailing address" it "is not valid without a country name" do destination.country_name = nil expect(destination).to_not be_valid end - - it "is not valid without a two-letter ISO 3166-2 country code" do - destination.country_code = "XX" - expect(destination).to_not be_valid - end end context "destination type is email" do @@ -153,9 +148,7 @@ ) end - it "is valid with valid attributes" do - expect(destination).to be_valid - end + include_examples "destination has valid attributes and associations" it "is invalid without an email address" do destination.email_address = nil @@ -171,9 +164,7 @@ ) end - it "is valid with valid attributes" do - expect(destination).to be_valid - end + include_examples "destination has valid attributes and associations" it "is invalid without a phone number" do destination.phone_number = nil diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 109a18312c3..8ba80d7e142 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -23,10 +23,15 @@ end end - shared_examples "distribution has valid attributes" do + shared_examples "distribution has valid attributes and associations" do it "is valid with valid attributes" do expect(distribution).to be_valid end + + it "is not valid without an associated VbmsCommunicationPackage" do + destination.vbms_communication_package = nil + expect(destination).to_not be_valid + end end context "recipient type is person" do @@ -39,7 +44,7 @@ ) end - include_examples "distribution has valid attributes" + include_examples "distribution has valid attributes and associations" it "is not valid without a first name" do distribution.first_name = nil @@ -68,7 +73,7 @@ ) end - include_examples "distribution has valid attributes" + include_examples "distribution has valid attributes and associations" include_examples "recipient type is not person" end @@ -81,7 +86,7 @@ ) end - include_examples "distribution has valid attributes" + include_examples "distribution has valid attributes and associations" include_examples "recipient type is not person" end @@ -94,7 +99,7 @@ ) end - include_examples "distribution has valid attributes" + include_examples "distribution has valid attributes and associations" include_examples "recipient type is not person" it "is not valid without a poa code" do From 85d529dcefeae09a7703f790afe8c7c0430bf20b Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Fri, 12 May 2023 15:19:32 -0400 Subject: [PATCH 070/308] APPEALS-21119 Edited old migration. Replaced document_referenced (ary) with copies (int) and updated audit scripts --- db/migrate/20230425144000_create_pacman_integration.rb | 2 +- db/schema.rb | 2 +- .../audit/tables/create_vbms_communication_packages_audit.rb | 2 +- .../audit/tables/create_vbms_communication_packages_audit.sql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb index 958ec784ce9..a1ca1a8b514 100644 --- a/db/migrate/20230425144000_create_pacman_integration.rb +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -2,7 +2,7 @@ class CreatePacmanIntegration < Caseflow::Migration def change create_table :vbms_communication_packages do |t| t.string :file_number, comment: "number associated with the documents." - t.bigint :document_referenced, default: [], array: true + t.bigint :copies, default: 1 t.string :status t.string :comm_package_name, null: false t.timestamps diff --git a/db/schema.rb b/db/schema.rb index 5948a787e37..9b5b3b841f6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1790,9 +1790,9 @@ create_table "vbms_communication_packages", force: :cascade do |t| t.string "comm_package_name", null: false + t.bigint "copies", default: 1 t.datetime "created_at", null: false t.bigint "created_by_id" - t.bigint "document_referenced", default: [], array: true t.string "file_number", comment: "number associated with the documents." t.string "status" t.datetime "updated_at", null: false diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index f7aaa1b5156..a13fac0c276 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -8,7 +8,7 @@ type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, file_number varchar NULL, - document_referenced _int8 NULL DEFAULT '{}'::bigint[], + copies int8 NULL DEFAULT 1, status varchar NULL, comm_package_name varchar NOT NULL, created_at timestamp NOT NULL, diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 767f562c463..31c0b8f960d 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -3,7 +3,7 @@ create table caseflow_audit.vbms_communication_packages_audit ( type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, file_number varchar NULL, - document_referenced _int8 NULL DEFAULT '{}'::bigint[], + copies int8 NULL DEFAULT 1, status varchar NULL, comm_package_name varchar NOT NULL, created_at timestamp NOT NULL, From 00ab925dcb6dccbc589e49e7ff6b3039cfdc4f37 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 12 May 2023 16:01:44 -0400 Subject: [PATCH 071/308] Fixed formatting on VbmsDistribution --- app/models/vbms_distribution.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index c35091a913a..a40de33abe6 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -5,7 +5,7 @@ class VbmsDistribution < CaseflowRecord has_one :vbms_distribution_destination with_options presence: true do - validates :recipient_type, inclusion: { in: %w(organization person system ro-colocated)} + validates :recipient_type, inclusion: { in: %w(organization person system ro-colocated) } validates :first_name, :last_name, if: :is_person? validates :name, unless: :is_person? validates :poa_code, :claimant_station_of_jurisdiction, if: :is_ro_colocated? From 1445516b905b2e6ce99f3331fda0f3b1470b1676 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 15 May 2023 10:11:29 -0400 Subject: [PATCH 072/308] Fixed typo --- spec/models/vbms_distribution_destination_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 637199619f9..6c2a8f75a89 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -32,7 +32,7 @@ end end - share_examples "destination is a physical mailing address" do + shared_examples "destination is a physical mailing address" do it "is not valid without an address line 1" do destination.address_line_1 = nil expect(destination).to_not be_valid From 09c5cd2c0ef2876a93c5f66620e62dfe79caf31f Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 15 May 2023 13:36:22 -0400 Subject: [PATCH 073/308] Updated unit tests and tests passing for VbmsCommunicationPackage, VbmsDistribution, and VbmsDistributionDestination --- .../models/vbms_communication_package_spec.rb | 14 +++-- .../vbms_distribution_destination_spec.rb | 58 +++++++++++-------- spec/models/vbms_distribution_spec.rb | 20 ++++--- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 8395fa1f4d0..43658c7e466 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -5,7 +5,8 @@ VbmsCommunicationPackage.new( file_number: "329780002", comm_package_name: "test package name", - vbms_uploaded_document: class_double(VbmsUploadedDocument) + document_referenced: [1], + vbms_uploaded_document: VbmsUploadedDocument.new ) end @@ -14,7 +15,7 @@ end it "is not valid without a filenumber" do - package.filenumber = nil + package.file_number = nil expect(package).to_not be_valid end @@ -24,9 +25,7 @@ end it "is not valid if communication package name exceeds 255 characters" do - invalid_package_name = "" - 256.times { invalid_package_name << "x" } - package.comm_package_name = invalid_package_name + package.comm_package_name = "x" * 256 expect(package).to_not be_valid end @@ -35,6 +34,11 @@ expect(package).to_not be_valid end + it "is not valid without a document referenced" do + package.document_referenced = nil + expect(package).to_not be_valid + end + it "is not valid without an associated VbmsUploadedDocument" do package.vbms_uploaded_document = nil expect(package).to_not be_valid diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 6c2a8f75a89..3448c1e9266 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -1,29 +1,11 @@ # frozen_string_literal: true describe VbmsDistributionDestination, :postgres do - let(:distribution) { class_double(VbmsDistribution) } - - context "destination type is nil or incorrect" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: nil, - vbms_distribution: distribution, - ) - end - - it "is not valid without a destination type" do - expect(destination).to_not be_valid - end - - it "is not valid with incorrect destination type" do - destination.recipient_type = "DomesticAddress" - expect(destination).to_not be_valid - end - end + let(:distribution) { VbmsDistribution.new } shared_examples "destination has valid attributes and associations" do it "is valid with valid attributes" do - expect(distribution).to be_valid + expect(destination).to be_valid end it "is not valid without an associated VbmsDistribution" do @@ -98,7 +80,7 @@ include_examples "destination has valid attributes and associations" include_examples "destination is a physical mailing address" - includes_examples "destination is a US address" + include_examples "destination is a US address" end context "destination type is militaryAddress" do @@ -116,7 +98,7 @@ include_examples "destination has valid attributes and associations" include_examples "destination is a physical mailing address" - includes_examples "destination is a US address" + include_examples "destination is a US address" end context "destination type is internationalAddress" do @@ -144,7 +126,8 @@ let(:destination) do VbmsDistributionDestination.new( destination_type: "email", - email_address: "email@email.com" + email_address: "email@email.com", + vbms_distribution: distribution ) end @@ -160,7 +143,8 @@ let(:destination) do VbmsDistributionDestination.new( destination_type: "sms", - phone_number: "555-5555" + phone_number: "555-5555", + vbms_distribution: distribution ) end @@ -171,4 +155,30 @@ expect(destination).to_not be_valid end end + + context "destination type is nil or incorrect" do + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "domesticAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + state: "NY", + postal_code: "11385", + country_code: "US" + ) + end + + include_examples "destination has valid attributes and associations" + + it "is not valid without a destination type" do + destination.destination_type = nil + expect(destination).to_not be_valid + end + + it "is not valid with incorrect destination type" do + destination.destination_type = "DomesticAddress" + expect(destination).to_not be_valid + end + end end diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 8ba80d7e142..ed66b191771 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true describe VbmsDistribution, :postgres do - let(:package) { class_double(VbmsCommunicationPackage) } + let(:package) { VbmsCommunicationPackage.new } context "recipient type is nil or incorrect" do let(:distribution) do @@ -29,8 +29,8 @@ end it "is not valid without an associated VbmsCommunicationPackage" do - destination.vbms_communication_package = nil - expect(destination).to_not be_valid + distribution.vbms_communication_package = nil + expect(distribution).to_not be_valid end end @@ -48,19 +48,19 @@ it "is not valid without a first name" do distribution.first_name = nil - expect(distribution).to be_valid + expect(distribution).to_not be_valid end it "is not valid without a last name" do distribution.first_name = nil - expect(distribution).to be_valid + expect(distribution).to_not be_valid end end shared_examples "recipient type is not person" do it "is not valid without a name" do distribution.name = nil - expect(distribution).to be_valid + expect(distribution).to_not be_valid end end @@ -95,7 +95,9 @@ VbmsDistribution.new( recipient_type: "ro-colocated", vbms_communication_package: package, - name: "Ro-Colocated" + name: "Ro-Colocated", + poa_code: "poa code", + claimant_station_of_jurisdiction: "claimant station" ) end @@ -104,12 +106,12 @@ it "is not valid without a poa code" do distribution.poa_code = nil - expect(distribution).to be_valid + expect(distribution).to_not be_valid end it "is not valid without a claimant station of jurisdiction" do distribution.claimant_station_of_jurisdiction = nil - expect(distribution).to be_valid + expect(distribution).to_not be_valid end end end From 482a01a037c63fddb6affd69cf59f20584579385 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 15 May 2023 14:14:30 -0400 Subject: [PATCH 074/308] Refactored unit tests and increased code coverage --- .../vbms_distribution_destination_spec.rb | 21 +++-- spec/models/vbms_distribution_spec.rb | 80 +++++++++++++------ 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 3448c1e9266..89197da2527 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -3,11 +3,13 @@ describe VbmsDistributionDestination, :postgres do let(:distribution) { VbmsDistribution.new } - shared_examples "destination has valid attributes and associations" do + shared_examples "destination has valid attributes" do it "is valid with valid attributes" do expect(destination).to be_valid end + end + shared_examples "destination has valid associations" do it "is not valid without an associated VbmsDistribution" do destination.vbms_distribution = nil expect(destination).to_not be_valid @@ -78,7 +80,8 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" + include_examples "destination has valid associations" include_examples "destination is a physical mailing address" include_examples "destination is a US address" end @@ -96,7 +99,8 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" + include_examples "destination has valid associations" include_examples "destination is a physical mailing address" include_examples "destination is a US address" end @@ -113,7 +117,8 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" + include_examples "destination has valid associations" include_examples "destination is a physical mailing address" it "is not valid without a country name" do @@ -131,7 +136,8 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" + include_examples "destination has valid associations" it "is invalid without an email address" do destination.email_address = nil @@ -148,7 +154,8 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" + include_examples "destination has valid associations" it "is invalid without a phone number" do destination.phone_number = nil @@ -169,7 +176,7 @@ ) end - include_examples "destination has valid attributes and associations" + include_examples "destination has valid attributes" it "is not valid without a destination type" do destination.destination_type = nil diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index ed66b191771..5d96cd22b6d 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -3,37 +3,25 @@ describe VbmsDistribution, :postgres do let(:package) { VbmsCommunicationPackage.new } - context "recipient type is nil or incorrect" do - let(:distribution) do - VbmsDistribution.new( - recipient_type: nil, - vbms_communication_package: package, - first_name: "First", - last_name: "Last" - ) - end - - it "is not valid without a recipient type" do - expect(distribution).to_not be_valid - end - - it "is not valid with incorrect recipient type" do - distribution.recipient_type = "Person" - expect(distribution).to_not be_valid - end - end - - shared_examples "distribution has valid attributes and associations" do + shared_examples "distribution has valid attributes" do it "is valid with valid attributes" do expect(distribution).to be_valid end + end + shared_examples "distribution has valid associations" do it "is not valid without an associated VbmsCommunicationPackage" do distribution.vbms_communication_package = nil expect(distribution).to_not be_valid end end + shared_examples "recipient type is not ro-colocated" do + it "is not ro-colocated" do + expect(distribution.is_ro_colocated?).to be false + end + end + context "recipient type is person" do let(:distribution) do VbmsDistribution.new( @@ -44,7 +32,13 @@ ) end - include_examples "distribution has valid attributes and associations" + include_examples "distribution has valid attributes" + include_examples "distribution has valid associations" + include_examples "recipient type is not ro-colocated" + + it "is a person" do + expect(distribution.is_person?).to be true + end it "is not valid without a first name" do distribution.first_name = nil @@ -58,6 +52,10 @@ end shared_examples "recipient type is not person" do + it "is not a person" do + expect(distribution.is_person?).to be false + end + it "is not valid without a name" do distribution.name = nil expect(distribution).to_not be_valid @@ -73,8 +71,10 @@ ) end - include_examples "distribution has valid attributes and associations" + include_examples "distribution has valid attributes" + include_examples "distribution has valid associations" include_examples "recipient type is not person" + include_examples "recipient type is not ro-colocated" end context "recipient is system" do @@ -86,8 +86,10 @@ ) end - include_examples "distribution has valid attributes and associations" + include_examples "distribution has valid attributes" + include_examples "distribution has valid associations" include_examples "recipient type is not person" + include_examples "recipient type is not ro-colocated" end context "recipient is ro-colocated" do @@ -101,9 +103,14 @@ ) end - include_examples "distribution has valid attributes and associations" + include_examples "distribution has valid attributes" + include_examples "distribution has valid associations" include_examples "recipient type is not person" + it "is ro-colocated" do + expect(distribution.is_ro_colocated?).to be true + end + it "is not valid without a poa code" do distribution.poa_code = nil expect(distribution).to_not be_valid @@ -114,4 +121,27 @@ expect(distribution).to_not be_valid end end + + context "recipient type is nil or incorrect" do + let(:distribution) do + VbmsDistribution.new( + recipient_type: "person", + vbms_communication_package: package, + first_name: "First", + last_name: "Last" + ) + end + + include_examples "distribution has valid attributes" + + it "is not valid without a recipient type" do + distribution.recipient_type = nil + expect(distribution).to_not be_valid + end + + it "is not valid with incorrect recipient type" do + distribution.recipient_type = "Person" + expect(distribution).to_not be_valid + end + end end From 7ed921ac5fa0025e2e70f674a44af8790caea8a3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 15 May 2023 15:09:00 -0400 Subject: [PATCH 075/308] Refactored unit tests --- spec/models/vbms_distribution_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 5d96cd22b6d..1cf78dc963d 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -18,7 +18,7 @@ shared_examples "recipient type is not ro-colocated" do it "is not ro-colocated" do - expect(distribution.is_ro_colocated?).to be false + expect(distribution.is_ro_colocated?).to eq(false) end end @@ -37,7 +37,7 @@ include_examples "recipient type is not ro-colocated" it "is a person" do - expect(distribution.is_person?).to be true + expect(distribution.is_person?).to eq(true) end it "is not valid without a first name" do @@ -53,7 +53,7 @@ shared_examples "recipient type is not person" do it "is not a person" do - expect(distribution.is_person?).to be false + expect(distribution.is_person?).to eq(false) end it "is not valid without a name" do From aadae0da32abaca6d280b949014319cf9421da80 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 09:07:01 -0400 Subject: [PATCH 076/308] Refactored VbmsCommunicationPackage model and rspec to include document referenced length --- app/models/vbms_communication_package.rb | 6 +++--- spec/models/vbms_communication_package_spec.rb | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 0906fc52477..6603cb8d84e 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -6,7 +6,7 @@ class VbmsCommunicationPackage < CaseflowRecord validates :file_number, :comm_package_name, :document_referenced, presence: true validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } - # document_referenced has current data type of array of bigint values - # - need to solve before being able to validate "id" and "copies" - # validates :document_referenced, length: { minimum: 1 } + validates :document_referenced, length: { minimum: 1 } + # - document_referenced has current data type of array of bigint values + # - need to change before being able to validate nested values of "id" and "copies" end diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 43658c7e466..a88a24bbd1a 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -39,6 +39,11 @@ expect(package).to_not be_valid end + it "is not valid with less than one document referenced" do + package.document_referenced = [] + expect(package).to_not be_valid + end + it "is not valid without an associated VbmsUploadedDocument" do package.vbms_uploaded_document = nil expect(package).to_not be_valid From dc9744e932917001c89cfb58de7e5891f74143a3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 09:26:40 -0400 Subject: [PATCH 077/308] Refactored VbmsDistribution and unit tests to reduce repetition --- app/models/vbms_distribution.rb | 1 - spec/models/vbms_distribution_spec.rb | 74 ++++++++++----------------- 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index a40de33abe6..347b701c96d 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -18,5 +18,4 @@ def is_person? def is_ro_colocated? recipient_type == "ro-colocated" end - end diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 1cf78dc963d..b35ef7a8c64 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -9,11 +9,30 @@ end end - shared_examples "distribution has valid associations" do - it "is not valid without an associated VbmsCommunicationPackage" do - distribution.vbms_communication_package = nil - expect(distribution).to_not be_valid - end + let(:distribution) do + VbmsDistribution.new( + recipient_type: "person", + vbms_communication_package: package, + first_name: "First", + last_name: "Last" + ) + end + + include_examples "distribution has valid attributes" + + it "is not valid without an associated VbmsCommunicationPackage" do + distribution.vbms_communication_package = nil + expect(distribution).to_not be_valid + end + + it "is not valid without a recipient type" do + distribution.recipient_type = nil + expect(distribution).to_not be_valid + end + + it "is not valid with incorrect recipient type" do + distribution.recipient_type = "Person" + expect(distribution).to_not be_valid end shared_examples "recipient type is not ro-colocated" do @@ -23,23 +42,12 @@ end context "recipient type is person" do - let(:distribution) do - VbmsDistribution.new( - recipient_type: "person", - vbms_communication_package: package, - first_name: "First", - last_name: "Last" - ) - end - - include_examples "distribution has valid attributes" - include_examples "distribution has valid associations" - include_examples "recipient type is not ro-colocated" - it "is a person" do expect(distribution.is_person?).to eq(true) end + include_examples "recipient type is not ro-colocated" + it "is not valid without a first name" do distribution.first_name = nil expect(distribution).to_not be_valid @@ -72,12 +80,11 @@ end include_examples "distribution has valid attributes" - include_examples "distribution has valid associations" include_examples "recipient type is not person" include_examples "recipient type is not ro-colocated" end - context "recipient is system" do + context "recipient type is system" do let(:distribution) do VbmsDistribution.new( recipient_type: "system", @@ -87,7 +94,6 @@ end include_examples "distribution has valid attributes" - include_examples "distribution has valid associations" include_examples "recipient type is not person" include_examples "recipient type is not ro-colocated" end @@ -104,11 +110,10 @@ end include_examples "distribution has valid attributes" - include_examples "distribution has valid associations" include_examples "recipient type is not person" it "is ro-colocated" do - expect(distribution.is_ro_colocated?).to be true + expect(distribution.is_ro_colocated?).to eq(true) end it "is not valid without a poa code" do @@ -121,27 +126,4 @@ expect(distribution).to_not be_valid end end - - context "recipient type is nil or incorrect" do - let(:distribution) do - VbmsDistribution.new( - recipient_type: "person", - vbms_communication_package: package, - first_name: "First", - last_name: "Last" - ) - end - - include_examples "distribution has valid attributes" - - it "is not valid without a recipient type" do - distribution.recipient_type = nil - expect(distribution).to_not be_valid - end - - it "is not valid with incorrect recipient type" do - distribution.recipient_type = "Person" - expect(distribution).to_not be_valid - end - end end From 9689f45190f495fae158b731d1fa5568e4a78b8a Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 09:48:53 -0400 Subject: [PATCH 078/308] Refactored VbmsDistribution unit test --- spec/models/vbms_distribution_spec.rb | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index b35ef7a8c64..3afcdb6718b 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -35,19 +35,7 @@ expect(distribution).to_not be_valid end - shared_examples "recipient type is not ro-colocated" do - it "is not ro-colocated" do - expect(distribution.is_ro_colocated?).to eq(false) - end - end - context "recipient type is person" do - it "is a person" do - expect(distribution.is_person?).to eq(true) - end - - include_examples "recipient type is not ro-colocated" - it "is not valid without a first name" do distribution.first_name = nil expect(distribution).to_not be_valid @@ -60,10 +48,6 @@ end shared_examples "recipient type is not person" do - it "is not a person" do - expect(distribution.is_person?).to eq(false) - end - it "is not valid without a name" do distribution.name = nil expect(distribution).to_not be_valid @@ -81,7 +65,6 @@ include_examples "distribution has valid attributes" include_examples "recipient type is not person" - include_examples "recipient type is not ro-colocated" end context "recipient type is system" do @@ -95,7 +78,6 @@ include_examples "distribution has valid attributes" include_examples "recipient type is not person" - include_examples "recipient type is not ro-colocated" end context "recipient is ro-colocated" do @@ -112,10 +94,6 @@ include_examples "distribution has valid attributes" include_examples "recipient type is not person" - it "is ro-colocated" do - expect(distribution.is_ro_colocated?).to eq(true) - end - it "is not valid without a poa code" do distribution.poa_code = nil expect(distribution).to_not be_valid From 9e548dd11f2f9165bf600b7cdfe54286d75e2271 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 09:57:57 -0400 Subject: [PATCH 079/308] Refactored VbmsDistributionDestination --- app/models/vbms_distribution_destination.rb | 2 +- .../vbms_distribution_destination_spec.rb | 75 +++++++------------ 2 files changed, 28 insertions(+), 49 deletions(-) diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 8a60a0d3c7d..96cc94321ae 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -37,7 +37,7 @@ def is_valid_us_state_code? end end - # Are these country and state codes available in a hard coded constant? + # Are these country and state codes available in a hard coded constant – or should I create? def iso_country_codes @iso_country_codes ||= ISO3166::Country.codes diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 89197da2527..59b84c58a07 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -9,11 +9,33 @@ end end - shared_examples "destination has valid associations" do - it "is not valid without an associated VbmsDistribution" do - destination.vbms_distribution = nil - expect(destination).to_not be_valid - end + let(:destination) do + VbmsDistributionDestination.new( + destination_type: "domesticAddress", + vbms_distribution: distribution, + address_line_1: "address line 1", + city: "city", + state: "NY", + postal_code: "11385", + country_code: "US" + ) + end + + include_examples "destination has valid attributes" + + it "is not valid without a destination type" do + destination.destination_type = nil + expect(destination).to_not be_valid + end + + it "is not valid with incorrect destination type" do + destination.destination_type = "DomesticAddress" + expect(destination).to_not be_valid + end + + it "is not valid without an associated VbmsDistribution" do + destination.vbms_distribution = nil + expect(destination).to_not be_valid end shared_examples "destination is a physical mailing address" do @@ -68,20 +90,7 @@ end context "destination type is domesticAddress" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: "domesticAddress", - vbms_distribution: distribution, - address_line_1: "address line 1", - city: "city", - state: "NY", - postal_code: "11385", - country_code: "US" - ) - end - include_examples "destination has valid attributes" - include_examples "destination has valid associations" include_examples "destination is a physical mailing address" include_examples "destination is a US address" end @@ -100,7 +109,6 @@ end include_examples "destination has valid attributes" - include_examples "destination has valid associations" include_examples "destination is a physical mailing address" include_examples "destination is a US address" end @@ -118,7 +126,6 @@ end include_examples "destination has valid attributes" - include_examples "destination has valid associations" include_examples "destination is a physical mailing address" it "is not valid without a country name" do @@ -137,7 +144,6 @@ end include_examples "destination has valid attributes" - include_examples "destination has valid associations" it "is invalid without an email address" do destination.email_address = nil @@ -155,37 +161,10 @@ end include_examples "destination has valid attributes" - include_examples "destination has valid associations" it "is invalid without a phone number" do destination.phone_number = nil expect(destination).to_not be_valid end end - - context "destination type is nil or incorrect" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: "domesticAddress", - vbms_distribution: distribution, - address_line_1: "address line 1", - city: "city", - state: "NY", - postal_code: "11385", - country_code: "US" - ) - end - - include_examples "destination has valid attributes" - - it "is not valid without a destination type" do - destination.destination_type = nil - expect(destination).to_not be_valid - end - - it "is not valid with incorrect destination type" do - destination.destination_type = "DomesticAddress" - expect(destination).to_not be_valid - end - end end From 6449ae95186b4f57b587bf44bf1d00fce7c3e916 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 13:14:15 -0400 Subject: [PATCH 080/308] Refactored VbmsDistribution conditional validation --- app/models/vbms_distribution.rb | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 347b701c96d..3e3bc5e32ab 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -6,16 +6,12 @@ class VbmsDistribution < CaseflowRecord with_options presence: true do validates :recipient_type, inclusion: { in: %w(organization person system ro-colocated) } - validates :first_name, :last_name, if: :is_person? - validates :name, unless: :is_person? - validates :poa_code, :claimant_station_of_jurisdiction, if: :is_ro_colocated? + validates :first_name, :last_name, if: -> { recipient_type == "person" } + validates :name, if: :is_not_a_person? + validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } end - def is_person? - recipient_type == "person" - end - - def is_ro_colocated? - recipient_type == "ro-colocated" + def is_not_a_person? + %w(organization system ro-colocated).include?(recipient_type) end end From 4f4fa26a6f94fdf07f39cea2929e4189a5c4c331 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 14:50:32 -0400 Subject: [PATCH 081/308] Discarded changes that were made to schema when running db:migrate on this feature branch --- db/schema.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 4c8aae09434..5948a787e37 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -91,7 +91,7 @@ t.boolean "appeal_docketed", default: false, null: false, comment: "When true, appeal has been docketed" t.bigint "appeal_id", null: false, comment: "AMA or Legacy Appeal ID" t.string "appeal_type", null: false, comment: "Appeal Type (Appeal or LegacyAppeal)" - t.datetime "created_at", null: false + t.datetime "created_at", null: false, comment: "Date and Time the record was inserted into the table" t.bigint "created_by_id", null: false, comment: "User id of the user that inserted the record" t.boolean "decision_mailed", default: false, null: false, comment: "When true, appeal has decision mail request complete" t.boolean "hearing_postponed", default: false, null: false, comment: "When true, appeal has hearing postponed and no hearings scheduled" @@ -100,7 +100,7 @@ t.boolean "privacy_act_complete", default: false, null: false, comment: "When true, appeal has a privacy act request completed" t.boolean "privacy_act_pending", default: false, null: false, comment: "When true, appeal has a privacy act request still open" t.boolean "scheduled_in_error", default: false, null: false, comment: "When true, hearing was scheduled in error and none scheduled" - t.datetime "updated_at" + t.datetime "updated_at", comment: "Date and time the record was last updated" t.bigint "updated_by_id", comment: "User id of the last user that updated the record" t.boolean "vso_ihp_complete", default: false, null: false, comment: "When true, appeal has a VSO IHP request completed" t.boolean "vso_ihp_pending", default: false, null: false, comment: "When true, appeal has a VSO IHP request pending" @@ -1275,7 +1275,7 @@ t.string "recipient_email", comment: "Participant's Email Address" t.string "recipient_phone_number", comment: "Participants Phone Number" t.text "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_external_id" t.string "sms_notification_status", comment: "Status of SMS/Text Notification" 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" @@ -1577,7 +1577,6 @@ t.boolean "national_cemetery_administration", default: false t.boolean "no_special_issues", default: false, comment: "Affirmative no special issues, added belatedly" t.boolean "nonrating_issue", default: false - t.boolean "pact_act", default: false, comment: "The Sergeant First Class (SFC) Heath Robinson Honoring our Promise to Address Comprehensive Toxics (PACT) Act" t.boolean "pension_united_states", default: false t.boolean "private_attorney_or_agent", default: false t.boolean "radiation", default: false From 46d4111eaff6b69204ac2e76dccb5254c77453e5 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 16 May 2023 15:56:34 -0400 Subject: [PATCH 082/308] Reformatted per rubocop suggestions --- app/models/vbms_communication_package.rb | 1 + app/models/vbms_distribution.rb | 8 ++++---- app/models/vbms_distribution_destination.rb | 22 ++++++++++----------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 6603cb8d84e..0f2cb93b716 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class VbmsCommunicationPackage < CaseflowRecord belongs_to :vbms_uploaded_document, optional: false has_many :vbms_distributions diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 3e3bc5e32ab..6527af2a821 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -5,13 +5,13 @@ class VbmsDistribution < CaseflowRecord has_one :vbms_distribution_destination with_options presence: true do - validates :recipient_type, inclusion: { in: %w(organization person system ro-colocated) } + validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } validates :first_name, :last_name, if: -> { recipient_type == "person" } - validates :name, if: :is_not_a_person? + validates :name, if: :not_a_person? validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } end - def is_not_a_person? - %w(organization system ro-colocated).include?(recipient_type) + def not_a_person? + %w[organization system ro-colocated].include?(recipient_type) end end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 96cc94321ae..0590e1c038a 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -4,34 +4,34 @@ class VbmsDistributionDestination < CaseflowRecord belongs_to :vbms_distribution, optional: false with_options presence: true do - validates :destination_type, inclusion: { in: %w(domesticAddress internationalAddress militaryAddress derived email sms) } - validates :address_line_1, :city, :country_code, if: :is_physical_mail? + validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived email sms] } + validates :address_line_1, :city, :country_code, if: :physical_mail? validates :address_line_2, if: :treat_line_2_as_addressee validates :address_line_3, if: :treat_line_3_as_addressee - validates :state, :postal_code, if: :is_us_address? + validates :state, :postal_code, if: :us_address? validates :country_name, if: -> { destination_type == "internationalAddress" } validates :email_address, if: -> { destination_type == "email" } validates :phone_number, if: -> { destination_type == "sms" } end - validate :is_valid_country_code?, if: :is_physical_mail? - validate :is_valid_us_state_code?, if: :is_us_address? + validate :valid_country_code?, if: :physical_mail? + validate :valid_us_state_code?, if: :us_address? - def is_physical_mail? - %w(domesticAddress internationalAddress militaryAddress).include?(destination_type) + def physical_mail? + %w[domesticAddress internationalAddress militaryAddress].include?(destination_type) end - def is_us_address? - %w(domesticAddress militaryAddress).include?(destination_type) + def us_address? + %w[domesticAddress militaryAddress].include?(destination_type) end - def is_valid_country_code? + def valid_country_code? unless iso_country_codes.include?(country_code) errors.add(:country_code, "is not a valid ISO 3166-2 code") end end - def is_valid_us_state_code? + def valid_us_state_code? unless iso_us_state_codes.include?(state) errors.add(:state, "is not a valid ISO 3166-2 code") end From ee4a60fcfafa76d460fdc675abfceadadb89a7a5 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 16 May 2023 17:36:31 -0400 Subject: [PATCH 083/308] APPEALS-21118 updated response --- app/jobs/mail_request_job.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 8b7c1f91d98..7aa41fe8002 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -6,9 +6,17 @@ class MailRequestJob < CaseflowJob application_attr :intake def perform(vbms_comm_package) - package = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, + package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, vbms_comm_package.comm_package_name, vbms_comm_package.document_referenced) - distribution = ExternalApi::PacmanService.send_distribution_request(package_id, recipient, destinations) + + distribution_response = create_distribution(vbms_comm_package.id) + end + + def create_distribution(package_id) + dist = VbmsDistribution.find_by(vbms_communication_package_id: package_id) + dist_dest = VbmsDistributionDestination.find_by(dist.id) + distribution = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) + distribution end end From ed7d9c7d0bdd444049d5cbafbcba9fb6a213d5a4 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 16 May 2023 18:07:47 -0400 Subject: [PATCH 084/308] APPEALS-21118 added error handling --- app/jobs/mail_request_job.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 7aa41fe8002..05646f2e6f9 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -9,8 +9,12 @@ def perform(vbms_comm_package) package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, vbms_comm_package.comm_package_name, vbms_comm_package.document_referenced) - - distribution_response = create_distribution(vbms_comm_package.id) + if package_response.code == 201 + vbms_comm_package.update!(status: "success") + distribution_response = create_distribution(vbms_comm_package.id) + else + vbms_comm_package.update!(status: "error") + end end def create_distribution(package_id) @@ -19,4 +23,10 @@ def create_distribution(package_id) distribution = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) distribution end + + def log_error(error) + uuid = SecureRandom.uuid + Rails.logger.error(error.to_s + "Error ID: " + uuid) + Raven.capture_exception(error, extra: { error_uuid: uuid }) + end end From 2c3c6a588ca96fbd51408ef64da486497b94d25d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 16 May 2023 18:35:19 -0400 Subject: [PATCH 085/308] APPEALS-21118 extra logging and added rspec file --- app/jobs/mail_request_job.rb | 34 ++++++++++++++++++++++++------ spec/jobs/mail_request_job_spec.rb | 5 +++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 spec/jobs/mail_request_job_spec.rb diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 05646f2e6f9..b24c34aec06 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -7,13 +7,15 @@ class MailRequestJob < CaseflowJob def perform(vbms_comm_package) package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, - vbms_comm_package.comm_package_name, - vbms_comm_package.document_referenced) + vbms_comm_package.comm_package_name, + vbms_comm_package.document_referenced) + log_info(package_response) if package_response.code == 201 vbms_comm_package.update!(status: "success") - distribution_response = create_distribution(vbms_comm_package.id) + create_distribution(vbms_comm_package.id) else vbms_comm_package.update!(status: "error") + log_error(error_msg(package_response.code)) end end @@ -21,12 +23,32 @@ def create_distribution(package_id) dist = VbmsDistribution.find_by(vbms_communication_package_id: package_id) dist_dest = VbmsDistributionDestination.find_by(dist.id) distribution = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) + log_info(distribution) + if distribution.code != 201 + log_error(error_msg(distribution.code)) + end distribution end - def log_error(error) + def log_error(error_msg) + uuid = SecureRandom.uuid + Rails.logger.error(error_msg + "Error ID: " + uuid) + Raven.capture_exception(error_msg, extra: { error_uuid: uuid }) + end + + def error_msg(code) + if code == 400 + "400 PacmanBadRequestError The server cannot create the new communication package due to a client error " + elsif code == 403 + "403 PacmanForbiddenError The server cannot create the new communication package due to insufficient privileges." + elsif code == 404 + "404 PacmanNotFoundError The communication package could not be found but may be available again in the future. + Subsequent requests by the client are permissible. " + end + end + + def log_info(info_message) uuid = SecureRandom.uuid - Rails.logger.error(error.to_s + "Error ID: " + uuid) - Raven.capture_exception(error, extra: { error_uuid: uuid }) + Rails.logger.info(info_message + "ID: " + uuid) end end diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb new file mode 100644 index 00000000000..84331c9ecbd --- /dev/null +++ b/spec/jobs/mail_request_job_spec.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +describe MailRequestJob do + +end From 8a37ad1ff263589514768da9d854a89d9d546d8a Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 17 May 2023 11:02:16 -0400 Subject: [PATCH 086/308] Removed email and sms validations from VbmsDistributionDestination and unit test --- app/models/vbms_distribution_destination.rb | 7 ++-- .../vbms_distribution_destination_spec.rb | 34 ------------------- 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 0590e1c038a..063229cbe76 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -4,14 +4,13 @@ class VbmsDistributionDestination < CaseflowRecord belongs_to :vbms_distribution, optional: false with_options presence: true do - validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived email sms] } + # Question of whether "derived" is necessary destination_type to check for, or if only relevant to VBMS + validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } validates :address_line_1, :city, :country_code, if: :physical_mail? validates :address_line_2, if: :treat_line_2_as_addressee validates :address_line_3, if: :treat_line_3_as_addressee validates :state, :postal_code, if: :us_address? validates :country_name, if: -> { destination_type == "internationalAddress" } - validates :email_address, if: -> { destination_type == "email" } - validates :phone_number, if: -> { destination_type == "sms" } end validate :valid_country_code?, if: :physical_mail? @@ -37,7 +36,7 @@ def valid_us_state_code? end end - # Are these country and state codes available in a hard coded constant – or should I create? + # Are these country and state codes available in a hard coded constant – or can I create? def iso_country_codes @iso_country_codes ||= ISO3166::Country.codes diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 59b84c58a07..2a5fc05d37a 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -133,38 +133,4 @@ expect(destination).to_not be_valid end end - - context "destination type is email" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: "email", - email_address: "email@email.com", - vbms_distribution: distribution - ) - end - - include_examples "destination has valid attributes" - - it "is invalid without an email address" do - destination.email_address = nil - expect(destination).to_not be_valid - end - end - - context "destination type is sms" do - let(:destination) do - VbmsDistributionDestination.new( - destination_type: "sms", - phone_number: "555-5555", - vbms_distribution: distribution - ) - end - - include_examples "destination has valid attributes" - - it "is invalid without a phone number" do - destination.phone_number = nil - expect(destination).to_not be_valid - end - end end From 6c98972b92eb43407530de7901723b6b2b84349c Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 17 May 2023 12:43:25 -0400 Subject: [PATCH 087/308] APPEALS-21118 added fakes for vbms package, dist, and dist dest --- spec/factories/vbms_communication_package.rb | 15 +++++++++++ spec/factories/vbms_distribution.rb | 19 +++++++++++++ .../vbms_distribution_destination.rb | 27 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 spec/factories/vbms_communication_package.rb create mode 100644 spec/factories/vbms_distribution.rb create mode 100644 spec/factories/vbms_distribution_destination.rb diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb new file mode 100644 index 00000000000..b0a50e9b7cf --- /dev/null +++ b/spec/factories/vbms_communication_package.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_communication_package do + comm_package_name {} + created_at + created_by_id + document_referenced + file_number + status + updated_at + updated_by_id + vbms_uploaded_document_id + end +end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb new file mode 100644 index 00000000000..dd0752ae7ea --- /dev/null +++ b/spec/factories/vbms_distribution.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_distribution do + t.string "claimant_station_of_jurisdiction", comment: "Can't be null if [recipient_type] is ro-colocated." + t.datetime "created_at", null: false + t.bigint "created_by_id" + t.string "first_name", comment: "recipient's first name. If Type is [person] then it cant be null." + t.string "last_name", comment: "recipient's last name. If Type is [person] then it cant be null." + t.string "middle_name", comment: "recipient's middle name." + t.string "name", comment: "should only be used for non-person entity names. Not null if [recipient_type] is organization, ro-colocated, or System." + t.string "participant_id", comment: "recipient's participant id." + t.string "poa_code", comment: "Can't be null if [recipient_type] is ro-colocated. The recipients POA code" + t.string "recipient_type", null: false, comment: "Must be one of [person, organization, ro-colocated, System]." + t.datetime "updated_at", null: false + t.bigint "updated_by_id" + t.bigint "vbms_communication_package_id" + end +end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb new file mode 100644 index 00000000000..e0427def15a --- /dev/null +++ b/spec/factories/vbms_distribution_destination.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_distribution_destination do + t.string "address_line_1", null: false, comment: "PII. If destination_type is domestic, international, or military then Must not be null." + t.string "address_line_2", comment: "PII. If treatLine2AsAddressee is [true] then must not be null" + t.string "address_line_3", comment: "PII. If treatLine3AsAddressee is [true] then must not be null" + t.string "address_line_4", comment: "PII." + t.string "address_line_5", comment: "PII." + t.string "address_line_6", comment: "PII." + t.string "city", comment: "PII. If type is [domestic, international, military] then Must not be null" + t.string "country_code", comment: "Must be exactly two-letter ISO 3166 code." + t.string "country_name" + t.datetime "created_at", null: false + t.bigint "created_by_id" + t.string "destination_type", null: false, comment: "Must be 'domesticAddress', 'internationalAddress', 'militaryAddress', 'derived', 'email', or 'sms'. Cannot be 'physicalAddress'." + t.string "email_address" + t.string "phone_number", comment: "PII." + t.string "postal_code" + t.string "state", comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" + t.boolean "treat_line_2_as_addressee" + t.boolean "treat_line_3_as_addressee" + t.datetime "updated_at", null: false + t.bigint "updated_by_id" + t.bigint "vbms_distribution_id" + end +end From 0f1bc469a3518af3766e63619bf6b87b37b2c23d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 10:58:41 -0400 Subject: [PATCH 088/308] APPEALS-21118 updated factories and rspec --- app/jobs/mail_request_job.rb | 1 - spec/factories/vbms_communication_package.rb | 18 ++++---- spec/factories/vbms_distribution.rb | 26 ++++++------ .../vbms_distribution_destination.rb | 42 +++++++++---------- spec/jobs/mail_request_job_spec.rb | 11 ++++- 5 files changed, 53 insertions(+), 45 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index b24c34aec06..4d8b01e238e 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -# This job syncs an EndProductEstablishment (end product manager) with up to date BGS and VBMS data class MailRequestJob < CaseflowJob queue_with_priority :low_priority application_attr :intake diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index b0a50e9b7cf..c245fdd8bd3 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -2,14 +2,14 @@ FactoryBot.define do factory :vbms_communication_package do - comm_package_name {} - created_at - created_by_id - document_referenced - file_number - status - updated_at - updated_by_id - vbms_uploaded_document_id + comm_package_name { nil } + created_at { Time.zone.now } + created_by_id { nil } + document_referenced { nil } + file_number { nil } + status { nil } + updated_at { Time.zone.now } + updated_by_id { nil } + vbms_uploaded_document_id { nil } end end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index dd0752ae7ea..2a0c9299d69 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -2,18 +2,18 @@ FactoryBot.define do factory :vbms_distribution do - t.string "claimant_station_of_jurisdiction", comment: "Can't be null if [recipient_type] is ro-colocated." - t.datetime "created_at", null: false - t.bigint "created_by_id" - t.string "first_name", comment: "recipient's first name. If Type is [person] then it cant be null." - t.string "last_name", comment: "recipient's last name. If Type is [person] then it cant be null." - t.string "middle_name", comment: "recipient's middle name." - t.string "name", comment: "should only be used for non-person entity names. Not null if [recipient_type] is organization, ro-colocated, or System." - t.string "participant_id", comment: "recipient's participant id." - t.string "poa_code", comment: "Can't be null if [recipient_type] is ro-colocated. The recipients POA code" - t.string "recipient_type", null: false, comment: "Must be one of [person, organization, ro-colocated, System]." - t.datetime "updated_at", null: false - t.bigint "updated_by_id" - t.bigint "vbms_communication_package_id" + claimant_station_of_jurisdiction + created_at + created_by_id + first_name + last_name + middle_name + name + participant_id + poa_code + recipient_type + updated_at + updated_by_id + vbms_communication_package_id end end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index e0427def15a..34eeded3a0e 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -2,26 +2,26 @@ FactoryBot.define do factory :vbms_distribution_destination do - t.string "address_line_1", null: false, comment: "PII. If destination_type is domestic, international, or military then Must not be null." - t.string "address_line_2", comment: "PII. If treatLine2AsAddressee is [true] then must not be null" - t.string "address_line_3", comment: "PII. If treatLine3AsAddressee is [true] then must not be null" - t.string "address_line_4", comment: "PII." - t.string "address_line_5", comment: "PII." - t.string "address_line_6", comment: "PII." - t.string "city", comment: "PII. If type is [domestic, international, military] then Must not be null" - t.string "country_code", comment: "Must be exactly two-letter ISO 3166 code." - t.string "country_name" - t.datetime "created_at", null: false - t.bigint "created_by_id" - t.string "destination_type", null: false, comment: "Must be 'domesticAddress', 'internationalAddress', 'militaryAddress', 'derived', 'email', or 'sms'. Cannot be 'physicalAddress'." - t.string "email_address" - t.string "phone_number", comment: "PII." - t.string "postal_code" - t.string "state", comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" - t.boolean "treat_line_2_as_addressee" - t.boolean "treat_line_3_as_addressee" - t.datetime "updated_at", null: false - t.bigint "updated_by_id" - t.bigint "vbms_distribution_id" + address_line_1 + address_line_2 + address_line_3 + address_line_4 + address_line_5 + address_line_6 + city + country_code + country_name + created_at + created_by_id + destination_type + email_address + phone_number + postal_code + state + treat_line_2_as_addressee + treat_line_3_as_addressee + updated_at + updated_by_id + vbms_distribution_id end end diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 84331c9ecbd..0e501df675e 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,5 +1,14 @@ # frozen_string_literal: true describe MailRequestJob do - + let!(package) { VbmsCommunicationPackage.create!(comm_package_name: "Jonah", created_at: DateTime.now, updated_at: DateTime.now) } + context "successful " do + subject { MailRequestJob.perform(package) } + it "changes package status to success" do + subject + expect(package.status).to eq("success") + end + it "creates distribution" do + end + end end From 3061016e6ba6490e3db252ff6b25f7f1f6ae63bb Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 11:00:40 -0400 Subject: [PATCH 089/308] APPEALS-21120 updated comments --- app/services/external_api/pacman_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index d50f422188d..d81116ce98a 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -17,7 +17,7 @@ class << self # Purpose: Creates and sends communication package # POST: /package-manager-service/communication-package # - # takes in file_number(string), name(string), document_reference(json of strings) + # takes in file_number(string), name(string), document_reference(array of strings) # # Response: JSON of created package from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_package_request' method @@ -29,7 +29,7 @@ def send_communication_package_request(file_number, name, document_references) # Purpose: Creates and sends distribution # POST: /package-manager-service/distribution # - # takes in package_id(string), recipient(json of strings), destinations(json of strings) + # takes in package_id(string), recipient(json of strings), destinations(array of strings) # # Response: JSON of created distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_request' method From e833ed95996518ad71bde317daf04124302a6d21 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 18 May 2023 12:12:04 -0400 Subject: [PATCH 090/308] APPEALS-21123 included activeModel valitations. provided Logic for validation within mailrequest.rb --- app/workflows/mail_request.rb | 198 +++++++++++++++++++++++++--------- 1 file changed, 150 insertions(+), 48 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 94fe5f40524..34c7bd944d1 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -1,36 +1,85 @@ -#frozen_string_literal: true +# frozen_string_literal: true class MailRequest include ActiveModel::Model + include ActiveModel::Validations - # ask about what should be validated... - # Could put them in a frozen array.....only having to reference that in future calls + attr_accessor :recipient_type, :name, :first_name, :middle_name, :last_name, + :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, + :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, + :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, + :treat_line_3_as_addressee, :country_name, :email_address, :phone_number + + with_options presence: true do + validates :recipient_type, if: :recipient_type_valid? + + validates :first_name, :last_name, if: :person? + validates :poa_code, :claimant_station_of_jurisdiction, if: :ro_colocated? + validates :destination_type, if: :destination_type_valid? + validates :address_line_1, :city, :country_code, if: :physical_mail? + validates :address_line_2, if: :line_2_addressee? + validates :address_line_3, if: :line_3_addressee? + validates :state, :postal_code, if: :us_address? + validates :country_name, if: :country_name_required? + validates :email_address, if: :email_required? + validates :phone_number, if: :phone_number_required? + end + validate :name, unless: :person? + # code that checks if a vbms_distribution with held params are valid? EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4, - :address_line_5, :address_line_6, - :city, - :country_code, - :postal_code, - :state, - :treat_line_2_as_addressee, - :treat_line_3_as_addressee, - :country_name, :email_address, - :phone_number, :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction - ] + :recipient_type, + :name, + :first_name, + :middle_name, + :last_name, + :participant_id, + :poa_code, + :claimant_station_of_jurisdiction, + :destination_type, + :address_line_1, + :address_line_2, + :address_line_3, + :address_line_4, + :address_line_5, + :address_line_6, + :city, + :country_code, + :postal_code, + :state, + :treat_line_2_as_addressee, + :treat_line_3_as_addressee, + :country_name, + :email_address, + :phone_number + ].freeze def initialize(params) - @params = params.slice(EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS) + @params = params.permit(EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS) + @recipient_type = @params[:recipient_type] + @name = @params[:name] + @first_name = @params[:first_name] + @middle_name = @params[:middle_name] + @last_name = @params[:last_name] + @participant_id = @params[:participant_id] + @poa_code = @params[:poa_code] + @claimant_station_of_jurisdiction = @params[:claimant_station_of_jurisdiction] + @destination_type = @params[:destination_type] + @address_line_1 = @params[:address_line_1] + @address_line_2 = @params[:address_line_2] + @address_line_3 = @params[:address_line_3] + @address_line_4 = @params[:address_line_4] + @address_line_5 = @params[:address_line_5] + @address_line_6 = @params[:address_line_6] + @city = @params[:city] + @country_code = @params[:country_code] + @postal_code = @params[:postal_code] + @state = @params[:state] + @treat_line_2_as_addressee = @params[:treat_line_2_as_addressee] + @treat_line_3_as_addressee = @params[:treat_line_3_as_addressee] + @country_name = @params[:country_name] + @email_address = @params[:email_address] + @phone_number = @params[:phone_number] end def create_a_vbms_distribution @@ -41,36 +90,89 @@ def create_a_vbms_distribution_destination VbmsDistributionDestination.create(destination_params_parse) end + private + + def recipient_type_valid? + valid_var = %w[organization person system ro-colocated].include?( + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2)) + valid_var + end + + def person? + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "person" + end + + def ro_colocated? + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "ro-colocated" + end + + def destination_type_valid? + %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( + @params[:destination_type].slice(1, @params[:destination_type].length - 2) + ) + end + + def physical_mail? + %w[domesticAddress internationalAddress militaryAddress].include?( + @params[:destination_type].slice(1, @params[:destination_type].length - 2)) + end + + def line_2_addressee? + @params[:treat_line_2_as_addressee] == true + end + + def line_3_addressee? + @params[:treat_line_3_as_addressee] == true + end + + def country_name_required? + @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "internationalAddress" + end + + def us_address? + %w[domesticAddress militaryAddress].include?( + @params[:destination_type].slice(1, @params[:recipient_type].length - 2)) + end + + def email_required? + @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "email" + end + + def phone_number_required? + @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "sms" + end + def destination_params_parse { - address_line_1: @params.address_line_1, - address_line_2: @params.address_line_2, - address_line_3: @params.address_line_3, - address_line_4: @params.address_line_4, - address_line_5: @params.address_line_5, - address_line_6: @params.address_line_6, - city: @params.city, - country_code: @params.country, - postal_code: @params.postal_code, - state: @params.state, - treat_line_2_as_addressee: @params.treat_line_2_as_addressee, - treat_line_3_as_addressee: @params.treat_line_3_as_addressee, - country_name: @params.country_name, - email_address: @params.email_address, - phone_number: @params.phone_number + destination_type: @destination_type, + address_line_1: @address_line_1, + address_line_2: @address_line_2, + address_line_3: @address_line_3, + address_line_4: @address_line_4, + address_line_5: @address_line_5, + address_line_6: @address_line_6, + city: @city, + country_code: @country, + postal_code: @postal_code, + state: @state, + treat_line_2_as_addressee: @treat_line_2_as_addressee, + treat_line_3_as_addressee: @treat_line_3_as_addressee, + country_name: @country_name, + email_address: @email_address, + phone_number: @phone_number } end def recipient_params_parse { - recipient_type: @params, - name: @params.name, - first_name: @params.first_name, - middle_name: @params.middle_name, - last_name: @params.last_name, - participant_id: @params.participant_id, - poa_code: @params.poa_code, - claimant_station_of_jurisdiction: @params.claimant_station_of_jurisdiction + recipient_type: @recipient_type, + name: @name, + first_name: @first_name, + middle_name: @middle_name, + last_name: @last_name, + participant_id: @participant_id, + poa_code: @poa_code, + claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction } end end From d9fb95e9ce5d75d9fcb3b165249514254b938cf0 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 18 May 2023 12:16:55 -0400 Subject: [PATCH 091/308] added conditional logic for param checking and object creation along with error logging. --- .../api/v1/upload_vbms_document_controller.rb | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 1b2be7c20c0..50c6655c3c6 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,10 +12,13 @@ def bgs end def create - if address_params.present? && recipient_params.present? - MailRequest.new(params) - elsif !address_params.present? || !recipient_params.present? - # log_some_error + if recipient_and_destination_params + new_mailing = MailRequest.new(params) + if new_mailing.valid? + new_mailing.create_a_vbms_distribution && new_mailing.create_a_vbms_distribution_destination + elsif new_mailing.invalid? + fail Caseflow::Error::MissingRecipientInfo, "IDT Standard Error ID: " + SecureRandom.uuid + " Not enough recipient info thats needed to mail the document." + end end appeal = nil @@ -45,8 +48,17 @@ def create end end - def destination_params + def recipient_and_destination_params params.permit( + :recipient_type, + :name, + :first_name, + :middle_name, + :last_name, + :participant_id, + :poa_code, + :claimant_station_of_jurisdiction, + :destination_type, :address_line_1, :address_line_2, :address_line_3, @@ -65,16 +77,4 @@ def destination_params ) end - def recipient_params - params.permit( - :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction - ) - end end From e1863cbece60af251aaea29550bae5fa10bc943e Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Thu, 18 May 2023 14:06:00 -0400 Subject: [PATCH 092/308] APPEALS-21119 Fill out empty SQL files --- ...ommunication_packages_audit_table_function.sql | 15 +++++++++++++++ ...ribution_destinations_audit_table_function.sql | 15 +++++++++++++++ ...to_vbms_distributions_audit_table_function.sql | 15 +++++++++++++++ ...ms_uploaded_documents_audit_table_function.sql | 15 +++++++++++++++ ..._vbms_communication_packages_audit_trigger.sql | 4 ++++ ...ms_distribution_destinations_audit_trigger.sql | 4 ++++ .../create_vbms_distributions_audit_trigger.sql | 4 ++++ ...eate_vbms_uploaded_documents_audit_trigger.sql | 4 ++++ 8 files changed, 76 insertions(+) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index e69de29bb2d..c47a1a498fb 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -0,0 +1,15 @@ +create or replace function caseflow_audit.add_row_to_vbms_communication_packages_audit() returns trigger +as +$add_row$ +begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; +end; +$add_row$ +language plpgsql; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index e69de29bb2d..fd5922c5872 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -0,0 +1,15 @@ +create or replace function caseflow_audit.add_row_to_vbms_distribution_destinations_audit() returns trigger +as +$add_row$ +begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; +end; +$add_row$ +language plpgsql; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index e69de29bb2d..5c5baaf75f2 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -0,0 +1,15 @@ +create or replace function caseflow_audit.add_row_to_vbms_distributions_audit() returns trigger +as +$add_row$ +begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; +end; +$add_row$ +language plpgsql; diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql index e69de29bb2d..5c5baaf75f2 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql @@ -0,0 +1,15 @@ +create or replace function caseflow_audit.add_row_to_vbms_distributions_audit() returns trigger +as +$add_row$ +begin + if (TG_OP = 'DELETE') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + elsif (TG_OP = 'UPDATE') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + elsif (TG_OP = 'INSERT') then + insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + end if; + return null; +end; +$add_row$ +language plpgsql; diff --git a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql index e69de29bb2d..6628fc6661b 100644 --- a/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql +++ b/db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.sql @@ -0,0 +1,4 @@ +create trigger vbms_communication_packages_audit_trigger +after insert or update or delete on public.vbms_communication_packages +for each row +execute procedure caseflow_audit.add_row_to_vbms_communication_packages_audit(); diff --git a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql index e69de29bb2d..506a3703b07 100644 --- a/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql +++ b/db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.sql @@ -0,0 +1,4 @@ +create trigger vbms_distribution_destinations_audit_trigger +after insert or update or delete on public.vbms_distribution_destinations +for each row +execute procedure caseflow_audit.add_row_to_vbms_distribution_destinations_audit(); diff --git a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql index e69de29bb2d..03c9f8eecd6 100644 --- a/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql +++ b/db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.sql @@ -0,0 +1,4 @@ +create trigger vbms_distributions_audit_trigger +after insert or update or delete on public.vbms_distributions +for each row +execute procedure caseflow_audit.add_row_to_vbms_distributions_audit(); diff --git a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql index e69de29bb2d..5ae25d271e5 100644 --- a/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql +++ b/db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.sql @@ -0,0 +1,4 @@ +create trigger vbms_uploaded_documents_audit_trigger +after insert or update or delete on public.vbms_uploaded_documents +for each row +execute procedure caseflow_audit.add_row_to_vbms_uploaded_documents_audit(); From 759da9ae6620990131f2648933fa71ea17e6a815 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 14:25:28 -0400 Subject: [PATCH 093/308] APPEALS-21120 pr feedback changes --- app/services/external_api/pacman_service.rb | 6 +++--- lib/fakes/pacman_service.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index d81116ce98a..2052d4f93a1 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -64,10 +64,10 @@ def package_request(file_number, name, document_reference) body: { fileNumber: file_number, name: name, - documentReferences: { + documentReferences: [{ id: document_reference[:id], copies: document_reference[:copies] - } + }] }, headers: HEADERS, endpoint: SEND_PACKAGE_ENDPOINT, method: :post @@ -123,7 +123,7 @@ def distribution_request(package_id, recipient, destination) # Params: general requirements for HTTP request # # Return: service_response: JSON from Pacman or error - def send_pacman_request(query: {}, headers: {}, endpoint:, method: :get, body: nil) + def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) url = URI.escape(BASE_URL + endpoint) request = HTTPI::Request.new(url) request.query = query diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 45c282b24a6..2fa4306b26a 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -93,7 +93,7 @@ def fake_distribution_response(distribution_id) 200, {}, OpenStruct.new( - "id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "id": distribution_id, "recipient": { "type": "system", "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", From bafb54b6ce6cf679ba0970c2a34ac16f089fe30b Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Thu, 18 May 2023 15:37:26 -0400 Subject: [PATCH 094/308] APPEALS-21119 Updated migration to remove email and phone number, reordered makefile and teardown script --- Makefile.example | 12 ++++++------ .../20230425144000_create_pacman_integration.rb | 4 +--- db/schema.rb | 4 +--- db/scripts/audit/pacman_integration_teardown.sql | 12 ++++++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Makefile.example b/Makefile.example index 93ee443be86..07c11681e69 100644 --- a/Makefile.example +++ b/Makefile.example @@ -141,16 +141,16 @@ db: ## Connect to your dev postgres (caseflow) db audit: ## Create caseflow_audit schema, tables, and triggers in postgres bundle exec rails r db/scripts/audit/create_caseflow_audit_schema.rb bundle exec rails r db/scripts/audit/tables/create_appeal_states_audit.rb - bundle exec rails r db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb - bundle exec rails r db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb bundle exec rails r db/scripts/audit/tables/create_vbms_communication_packages_audit.rb - bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb - bundle exec rails r db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb bundle exec rails r db/scripts/audit/tables/create_vbms_distributions_audit.rb - bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb - bundle exec rails r db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb bundle exec rails r db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb + bundle exec rails r db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb bundle exec rails r db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb audit-remove: ## Remove caseflow_audit schema, tables and triggers in postgres diff --git a/db/migrate/20230425144000_create_pacman_integration.rb b/db/migrate/20230425144000_create_pacman_integration.rb index a1ca1a8b514..8eda26cf944 100644 --- a/db/migrate/20230425144000_create_pacman_integration.rb +++ b/db/migrate/20230425144000_create_pacman_integration.rb @@ -38,14 +38,12 @@ def change t.string :address_line_5, comment: "PII." t.string :address_line_6, comment: "PII." t.boolean :treat_line_2_as_addressee - t.boolean :treat_line_3_as_addressee + t.boolean :treat_line_3_as_addressee, comment: "If true, treatLine2AsAddressee must also be true" t.string :city, comment: "PII. If type is [domestic, international, military] then Must not be null" t.string :state, comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" t.string :postal_code t.string :country_name t.string :country_code,comment: "Must be exactly two-letter ISO 3166 code." - t.string :email_address - t.string :phone_number, comment: "PII." t.timestamps t.references :vbms_distribution, index: true, foreign_key: { to_table: :vbms_distributions } diff --git a/db/schema.rb b/db/schema.rb index 9b5b3b841f6..a22fd7acb3e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1816,12 +1816,10 @@ t.datetime "created_at", null: false t.bigint "created_by_id" t.string "destination_type", null: false, comment: "Must be 'domesticAddress', 'internationalAddress', 'militaryAddress', 'derived', 'email', or 'sms'. Cannot be 'physicalAddress'." - t.string "email_address" - t.string "phone_number", comment: "PII." t.string "postal_code" t.string "state", comment: "PII. Must be exactly two-letter ISO 3166-2 code. If destination_type is domestic or military then Must not be null" t.boolean "treat_line_2_as_addressee" - t.boolean "treat_line_3_as_addressee" + t.boolean "treat_line_3_as_addressee", comment: "If true, treatLine2AsAddressee must also be true" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.bigint "vbms_distribution_id" diff --git a/db/scripts/audit/pacman_integration_teardown.sql b/db/scripts/audit/pacman_integration_teardown.sql index 11cdac54b82..386008b3bb0 100644 --- a/db/scripts/audit/pacman_integration_teardown.sql +++ b/db/scripts/audit/pacman_integration_teardown.sql @@ -1,8 +1,12 @@ -drop table caseflow_audit.vbms_communication_packages_audit; drop trigger vbms_communication_packages_audit_trigger; -drop table caseflow_audit.vbms_distributions_audit; drop trigger vbms_distributions_audit_trigger; -drop table caseflow_audit.vbms_distribution_destinations_audit; drop trigger vbms_distribution_destinations_audit_trigger; -drop table caseflow_audit.vbms_uploaded_documents_audit; drop trigger vbms_uploaded_documents_audit_trigger; +drop function caseflow_audit.add_row_to_vbms_communication_packages_audit +drop function caseflow_audit.add_row_to_vbms_distributions_audit +drop function caseflow_audit.add_row_to_vbms_distribution_destinations_audit +drop function caseflow_audit.add_row_to_vbms_uploaded_documents_audit +drop table caseflow_audit.vbms_communication_packages_audit; +drop table caseflow_audit.vbms_distributions_audit; +drop table caseflow_audit.vbms_distribution_destinations_audit; +drop table caseflow_audit.vbms_uploaded_documents_audit; From d0c020fbab5d9b7f4c9b7784ff037870bc9441bc Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 18 May 2023 16:14:21 -0400 Subject: [PATCH 095/308] Added validations for copies and removed document_referenced --- app/models/vbms_communication_package.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 0f2cb93b716..08b00e4e07b 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -4,10 +4,7 @@ class VbmsCommunicationPackage < CaseflowRecord belongs_to :vbms_uploaded_document, optional: false has_many :vbms_distributions - validates :file_number, :comm_package_name, :document_referenced, presence: true + validates :file_number, :comm_package_name, presence: true validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } - - validates :document_referenced, length: { minimum: 1 } - # - document_referenced has current data type of array of bigint values - # - need to change before being able to validate nested values of "id" and "copies" + # validates :copies, length: { in: 1..500 } end From 54d127e138bf0b344ea47a57279628b1e090a3a8 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 18 May 2023 16:15:06 -0400 Subject: [PATCH 096/308] Updated association relationship between distribution and destination --- app/models/vbms_distribution.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 6527af2a821..4902b568eac 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -2,7 +2,7 @@ class VbmsDistribution < CaseflowRecord belongs_to :vbms_communication_package, optional: false - has_one :vbms_distribution_destination + has_many :vbms_distribution_destinations with_options presence: true do validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } From 4faef6a031fa8975571f087f8081c11f36736852 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 18 May 2023 16:15:41 -0400 Subject: [PATCH 097/308] Added validation for address line 2 and address line 3 --- app/models/vbms_distribution_destination.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index 063229cbe76..f2440fe0e34 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -4,7 +4,6 @@ class VbmsDistributionDestination < CaseflowRecord belongs_to :vbms_distribution, optional: false with_options presence: true do - # Question of whether "derived" is necessary destination_type to check for, or if only relevant to VBMS validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } validates :address_line_1, :city, :country_code, if: :physical_mail? validates :address_line_2, if: :treat_line_2_as_addressee @@ -13,6 +12,8 @@ class VbmsDistributionDestination < CaseflowRecord validates :country_name, if: -> { destination_type == "internationalAddress" } end + validates :treat_line_2_as_addressee, inclusion: { in: [true] }, if: -> { treat_line_3_as_addressee == true } + validate :valid_country_code?, if: :physical_mail? validate :valid_us_state_code?, if: :us_address? @@ -36,8 +37,6 @@ def valid_us_state_code? end end - # Are these country and state codes available in a hard coded constant – or can I create? - def iso_country_codes @iso_country_codes ||= ISO3166::Country.codes end From 22029cd619e232c852cad14f90300dcfeadd7dfd Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 18 May 2023 16:27:19 -0400 Subject: [PATCH 098/308] Uncommented out validations for copies --- app/models/vbms_communication_package.rb | 4 +-- .../models/vbms_communication_package_spec.rb | 32 ++++++++++++++++--- .../vbms_distribution_destination_spec.rb | 6 ++++ spec/models/vbms_distribution_spec.rb | 10 +++++- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 08b00e4e07b..5a139dd6600 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -4,7 +4,7 @@ class VbmsCommunicationPackage < CaseflowRecord belongs_to :vbms_uploaded_document, optional: false has_many :vbms_distributions - validates :file_number, :comm_package_name, presence: true + validates :file_number, :comm_package_name, :copies, presence: true validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } - # validates :copies, length: { in: 1..500 } + validates :copies, length: { in: 1..500 } end diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index a88a24bbd1a..99eebfca9fd 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -5,7 +5,7 @@ VbmsCommunicationPackage.new( file_number: "329780002", comm_package_name: "test package name", - document_referenced: [1], + # copies: 1, vbms_uploaded_document: VbmsUploadedDocument.new ) end @@ -17,35 +17,57 @@ it "is not valid without a filenumber" do package.file_number = nil expect(package).to_not be_valid + expect(package.errors[:file_number]).to eq(["can't be blank"]) end it "is not valid without a communication package name" do package.comm_package_name = nil expect(package).to_not be_valid + expect(package.errors[:comm_package_name]).to eq( + [ + "can't be blank", + "is too short (minimum is 1 character)", + "is invalid" + ] + ) end it "is not valid if communication package name exceeds 255 characters" do package.comm_package_name = "x" * 256 expect(package).to_not be_valid + expect(package.errors[:comm_package_name]).to eq(["is too long (maximum is 255 characters)", "is invalid"]) end it "is not valid without a user friendly communication package name" do package.comm_package_name = "(test package name with parentheses)" expect(package).to_not be_valid + expect(package.errors[:comm_package_name]).to eq(["is invalid"]) + end + + it "is not valid without a copies attribute" do + package.copies = nil + expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) end - it "is not valid without a document referenced" do - package.document_referenced = nil + it "is not valid with less than one copy" do + package.copies = 0 expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) end - it "is not valid with less than one document referenced" do - package.document_referenced = [] + it "is not valid with more than 500 copies" do + package.copies = 500 + expect(package).to be_valid + + package.copies = 501 expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) end it "is not valid without an associated VbmsUploadedDocument" do package.vbms_uploaded_document = nil expect(package).to_not be_valid + expect(package.errors[:vbms_uploaded_document]).to eq(["must exist"]) end end diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 2a5fc05d37a..5d03dc5cd98 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -56,6 +56,12 @@ expect(destination).to_not be_valid end + it "is not valid if treat_line_3_as_addressee is true and treat_line_2_as_addressee is false" do + destination.treat_line_3_as_addressee = true + destination.treat_line_2_as_addressee = false + expect(destination).to_not be_valid + end + it "is not valid without a city" do destination.city = nil expect(destination).to_not be_valid diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index 3afcdb6718b..da76b6cba2a 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -23,27 +23,32 @@ it "is not valid without an associated VbmsCommunicationPackage" do distribution.vbms_communication_package = nil expect(distribution).to_not be_valid + expect(distribution.errors[:vbms_communication_package]).to eq(["must exist"]) end it "is not valid without a recipient type" do distribution.recipient_type = nil expect(distribution).to_not be_valid + expect(distribution.errors[:recipient_type]).to eq(["can't be blank", "is not included in the list"]) end it "is not valid with incorrect recipient type" do distribution.recipient_type = "Person" expect(distribution).to_not be_valid + expect(distribution.errors[:recipient_type]).to eq(["is not included in the list"]) end context "recipient type is person" do it "is not valid without a first name" do distribution.first_name = nil expect(distribution).to_not be_valid + expect(distribution.errors[:first_name]).to eq(["can't be blank"]) end it "is not valid without a last name" do - distribution.first_name = nil + distribution.last_name = nil expect(distribution).to_not be_valid + expect(distribution.errors[:last_name]).to eq(["can't be blank"]) end end @@ -51,6 +56,7 @@ it "is not valid without a name" do distribution.name = nil expect(distribution).to_not be_valid + expect(distribution.errors[:name]).to eq(["can't be blank"]) end end @@ -97,11 +103,13 @@ it "is not valid without a poa code" do distribution.poa_code = nil expect(distribution).to_not be_valid + expect(distribution.errors[:poa_code]).to eq(["can't be blank"]) end it "is not valid without a claimant station of jurisdiction" do distribution.claimant_station_of_jurisdiction = nil expect(distribution).to_not be_valid + expect(distribution.errors[:claimant_station_of_jurisdiction]).to eq(["can't be blank"]) end end end From 6a442873af7cee700603da77ede3948b740bd009 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 18 May 2023 17:04:12 -0400 Subject: [PATCH 099/308] Updated unit tests to validate specific error messages --- app/models/vbms_distribution_destination.rb | 4 +++- spec/models/vbms_distribution_destination_spec.rb | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index f2440fe0e34..f6fc5c785ad 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -12,7 +12,9 @@ class VbmsDistributionDestination < CaseflowRecord validates :country_name, if: -> { destination_type == "internationalAddress" } end - validates :treat_line_2_as_addressee, inclusion: { in: [true] }, if: -> { treat_line_3_as_addressee == true } + validates :treat_line_2_as_addressee, + inclusion: { in: [true], message: "cannot be false if line 3 is treated as addressee" }, + if: -> { treat_line_3_as_addressee == true } validate :valid_country_code?, if: :physical_mail? validate :valid_us_state_code?, if: :us_address? diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index 5d03dc5cd98..f89aed1940a 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -26,55 +26,65 @@ it "is not valid without a destination type" do destination.destination_type = nil expect(destination).to_not be_valid + expect(destination.errors[:destination_type]).to eq(["can't be blank", "is not included in the list"]) end it "is not valid with incorrect destination type" do destination.destination_type = "DomesticAddress" expect(destination).to_not be_valid + expect(destination.errors[:destination_type]).to eq(["is not included in the list"]) end it "is not valid without an associated VbmsDistribution" do destination.vbms_distribution = nil expect(destination).to_not be_valid + expect(destination.errors[:vbms_distribution]).to eq(["must exist"]) end shared_examples "destination is a physical mailing address" do it "is not valid without an address line 1" do destination.address_line_1 = nil expect(destination).to_not be_valid + expect(destination.errors[:address_line_1]).to eq(["can't be blank"]) end it "is not valid without an address line 2 if treat_line_2_as_addressee is true" do destination.treat_line_2_as_addressee = true destination.address_line_2 = nil expect(destination).to_not be_valid + expect(destination.errors[:address_line_2]).to eq(["can't be blank"]) end it "is not valid without an address line 3 if treat_line_3_as_addressee is true" do destination.treat_line_3_as_addressee = true destination.address_line_3 = nil expect(destination).to_not be_valid + expect(destination.errors[:address_line_3]).to eq(["can't be blank"]) end it "is not valid if treat_line_3_as_addressee is true and treat_line_2_as_addressee is false" do destination.treat_line_3_as_addressee = true destination.treat_line_2_as_addressee = false expect(destination).to_not be_valid + expect(destination.errors[:treat_line_2_as_addressee]).to eq(["cannot be false if line 3 is treated as addressee"]) end it "is not valid without a city" do destination.city = nil expect(destination).to_not be_valid + expect(destination.errors[:city]).to eq(["can't be blank"]) end it "is not valid without a country code" do destination.country_code = nil expect(destination).to_not be_valid + expect(destination.errors[:country_code]).to eq(["can't be blank", "is not a valid ISO 3166-2 code"]) end it "is not valid without a two-letter ISO 3166-2 country code" do destination.country_code = "XX" expect(destination).to_not be_valid + expect(destination.errors[:country_code]).to eq(["is not a valid ISO 3166-2 code"]) end end @@ -82,16 +92,19 @@ it "is not valid without a state" do destination.state = nil expect(destination).to_not be_valid + expect(destination.errors[:state]).to eq(["can't be blank", "is not a valid ISO 3166-2 code"]) end it "is not valid without a two-letter ISO 3166-2 state code" do destination.state = "XX" expect(destination).to_not be_valid + expect(destination.errors[:state]).to eq(["is not a valid ISO 3166-2 code"]) end it "is not valid without a postal code" do destination.postal_code = nil expect(destination).to_not be_valid + expect(destination.errors[:postal_code]).to eq(["can't be blank"]) end end @@ -137,6 +150,7 @@ it "is not valid without a country name" do destination.country_name = nil expect(destination).to_not be_valid + expect(destination.errors[:country_name]).to eq(["can't be blank"]) end end end From 8431c4fb41ce4238179bf7eb28375d0c85112508 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 21:44:13 -0400 Subject: [PATCH 100/308] APPEALS-21120 broke down request into smaller methods, compacted distribution_request --- app/services/external_api/pacman_service.rb | 73 +++++++++++++-------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 2052d4f93a1..e27e2a627a7 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -84,40 +84,57 @@ def distribution_request(package_id, recipient, destination) request = { body: { communicationPackageId: package_id, - recipient: { - type: recipient[:type], - name: recipient[:name], - firstName: recipient[:first_name], - middleName: recipient[:middle_name], - lastName: recipient[:last_name], - participant_id: recipient[:participant_id], - poaCode: recipient[:poa_code], - claimantStationOfJurisdiction: recipient[:claimant_station_of_jurisdiction] - }, - destinations: { - type: destination[:type], - addressLine1: destination[:addressLine1], - addressLine2: destination[:addressLine2], - addressLine3: destination[:addressLine3], - addressLine4: destination[:addressLine4], - addressLine5: destination[:addressLine5], - addressLine6: destination[:addressLine6], - treatLine2AsAddressee: destination[:treatLine2AsAddressee], - treatLine3AsAddressee: destination[:treatLine3AsAddressee], - city: destination[:city], - state: destination[:state], - postalCode: destination[:postalCode], - countryName: destination[:countryName], - emailAddress: destination[:emailAddress], - phoneNumber: destination[:phoneNumber] - } + recipient: recipient_data(recipient), + destinations: destinations_data(destination) }, headers: HEADERS, endpoint: SEND_PACKAGE_ENDPOINT, method: :post - } + }.compact request end + # Purpose: Builds recipient json for distribution request + # + # takes in recipient(json of strings) + # + # Response: json of recipient data for distribution request hash + def recipient_data(recipient) + { + type: recipient[:type], + name: recipient[:name], + firstName: recipient[:first_name], + middleName: recipient[:middle_name], + lastName: recipient[:last_name], + participant_id: recipient[:participant_id], + poaCode: recipient[:poa_code], + claimantStationOfJurisdiction: recipient[:claimant_station_of_jurisdiction] + } + end + + # Purpose: Builds destinations array for distribution request + # + # takes in destination(array of strings) + # + # Response: array of destination data for distribution request hashh + def destinations_data(destination) + [{ + type: destination[:type], + addressLine1: destination[:addressLine1], + addressLine2: destination[:addressLine2], + addressLine3: destination[:addressLine3], + addressLine4: destination[:addressLine4], + addressLine5: destination[:addressLine5], + addressLine6: destination[:addressLine6], + treatLine2AsAddressee: destination[:treatLine2AsAddressee], + treatLine3AsAddressee: destination[:treatLine3AsAddressee], + city: destination[:city], + state: destination[:state], + postalCode: destination[:postalCode], + countryName: destination[:countryName], + countryCode: destination[:countryCode] + }] + end + # Purpose: Build and send the request to the server # # Params: general requirements for HTTP request From 1c3d1dd6afae363ba8a420f04e49bc0e3dbfc611 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 21:47:55 -0400 Subject: [PATCH 101/308] APPEALS-21120 removed query from request --- app/services/external_api/pacman_service.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index e27e2a627a7..4e6d6a669d4 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -143,7 +143,6 @@ def destinations_data(destination) def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) url = URI.escape(BASE_URL + endpoint) request = HTTPI::Request.new(url) - request.query = query request.open_timeout = 30 request.read_timeout = 30 request.body = body.to_json unless body.nil? From e792e68960af1558e519ab5f5ee0d1a0d2a59e45 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 18 May 2023 21:55:00 -0400 Subject: [PATCH 102/308] APPEALS-21120 added error logging to response body parsing --- app/services/external_api/pacman_service/response.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb index 139fb50ec87..8c5412e448b 100644 --- a/app/services/external_api/pacman_service/response.rb +++ b/app/services/external_api/pacman_service/response.rb @@ -25,6 +25,7 @@ def body @body ||= begin JSON.parse(resp.body) rescue JSON::ParserError + log(JSON::ParserError) {} end end @@ -52,6 +53,12 @@ def check_for_error end end + def log_error(error) + uuid = SecureRandom.uuid + Rails.logger.error(error.name + " " + error.message + "Error ID: " + uuid) + Raven.capture_exception(error.name + " " + error.message, extra: { error_uuid: uuid }) + end + # Gets the error message from the response def error_message return "No error message from Pacman" if body.empty? From 30c8f2ad245e90736ed3f2314a81bc12f03b7cdf Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Fri, 19 May 2023 14:58:15 -0400 Subject: [PATCH 103/308] APPEALS-21120 fixed destinations to be array and updated comments --- app/services/external_api/pacman_service.rb | 10 ++-- lib/fakes/pacman_service.rb | 4 +- .../external_api/pacman_service_spec.rb | 51 ++++++++++++------- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 4e6d6a669d4..17821dd2825 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -34,8 +34,10 @@ def send_communication_package_request(file_number, name, document_references) # Response: JSON of created distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_request' method def send_distribution_request(package_id, recipient, destinations) - request = distribution_request(package_id, recipient, destinations) - send_pacman_request(request) + destinations.each do |destination| + request = distribution_request(package_id, recipient, destination) + send_pacman_request(request) + end end # Purpose: Gets distribution from distribution id @@ -56,7 +58,7 @@ def get_distribution_request(distribution_id) # Purpose: Builds package request # - # takes in file_number(string), name(string), document_reference(json of strings) + # takes in file_number(string), name(string), document_reference(array of strings) # # Response: package request hash def package_request(file_number, name, document_reference) @@ -77,7 +79,7 @@ def package_request(file_number, name, document_reference) # Purpose: Builds distribution request # - # takes in package_id(string), recipient(json of strings), destinations(json of strings) + # takes in package_id(string), recipient(json of strings), destinations(array of strings) # # Response: Distribution request hash def distribution_request(package_id, recipient, destination) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 2fa4306b26a..b7bc6fa1ca9 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -101,7 +101,7 @@ def fake_distribution_response(distribution_id) }, "description": "Staging Mailing Distribution", "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations": { + "destinations": [{ "type": "physicalAddress", "id": "28440040-51a5-4d2a-81a2-28730827be14", "status": "", @@ -119,7 +119,7 @@ def fake_distribution_response(distribution_id) "postalCode": "12345", "countryName": "UNITED STATES", "countryCode": "us" - }, + }], "status": "", "sentToCbcmDate": "" ) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index c731f305d90..8b79f933456 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -50,23 +50,31 @@ { "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", "recipient" => { - "type" => "system", - "name" => "VBMS-C" + "type" => nil, + "name" => nil, + "firstName" => nil, + "middleName" => nil, + "lastName" => nil, + "participant_id" => nil, + "poaCode" => nil, + "claimantStationOfJurisdiction" => nil }, - "destinations" => { - "type" => "domesticAddress", - "addressLine1" => "123 Test St.", - "addressLine2" => "", - "addressLine3" => "", - "addressLine4" => "", - "addressLine5" => "", - "addressLine6" => "", - "city" => "Anytown", - "postalCode" => "12345", - "state" => "DC", - "countryName" => "United States of America", - "countryCode" => "01" - } + "destinations" => [{ + "type" => nil, + "addressLine1" => nil, + "addressLine2" => nil, + "addressLine3" => nil, + "addressLine4" => nil, + "addressLine5" => nil, + "addressLine6" => nil, + "treatLine2AsAddressee" => nil, + "treatLine3AsAddressee" => nil, + "city" => nil, + "state" => nil, + "postalCode" => nil, + "countryName" => nil, + "countryCode" => nil + }] }.as_json end @@ -80,7 +88,7 @@ }, "description" => "Staging Distribution", "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations" => { + "destinations" => [{ "type" => "physicalAddress", "id" => "5378bfbd-eff5-470c-bbc4-c7fd3c863a50", "status" => "null", @@ -98,7 +106,7 @@ "postalCode" => "12345", "countryName" => "UNITED STATES", "countryCode" => "us" - }, + }], "status" => "null", "sentToCbcmDate" => "null" }.as_json @@ -163,7 +171,12 @@ distribution_post_request["destinations"]) end it "successfully sends distribution" do - allow(HTTPI).to receive(:post).and_return(post_distribution_success_response) + allow(HTTPI) + .to receive(:post) do |req| + # Making sure the request being handed to HTTPI.post + # has everything we'd expect, and that there's no funny business going on. + expect(JSON.parse(req.body)).to eq distribution_post_request + end.and_return(post_distribution_success_response) expect(subject.body.as_json).to eq(post_distribution_success_response.body) end end From 3f029c76f5d339adb3adcd3f7e8047efbc6cd80d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Fri, 19 May 2023 15:21:18 -0400 Subject: [PATCH 104/308] APPEALS-21120 fixed document_references and destinations to be arrays, updated spec tests to reflect changes --- app/services/external_api/pacman_service.rb | 4 ++-- .../external_api/pacman_service_spec.rb | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 17821dd2825..05b2aeb4ff8 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -22,7 +22,7 @@ class << self # Response: JSON of created package from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_package_request' method def send_communication_package_request(file_number, name, document_references) - request = package_request(file_number, name, document_references) + request = package_request(file_number, name, document_references.first) send_pacman_request(request) end @@ -34,7 +34,7 @@ def send_communication_package_request(file_number, name, document_references) # Response: JSON of created distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_request' method def send_distribution_request(package_id, recipient, destinations) - destinations.each do |destination| + destinations.map do |destination| request = distribution_request(package_id, recipient, destination) send_pacman_request(request) end diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 8b79f933456..76250708375 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -22,7 +22,7 @@ }, "description" => "Staging Mailing Distribution", "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations" => { + "destinations" => [{ "type" => "physicalAddress", "id" => "28440040-51a5-4d2a-81a2-28730827be14", "status" => "", @@ -40,7 +40,7 @@ "postalCode" => "12345", "countryName" => "UNITED STATES", "countryCode" => "us" - }, + }], "status" => "", "sentToCbcmDate" => "" }.as_json @@ -116,10 +116,10 @@ { "fileNumber" => "123456789", "name" => "ABC abc 1234 !*+,-.:;=?", - "documentReferences" => { + "documentReferences" => [{ "id" => "3aec91cc-a88d-4b9c-9183-84bed583bbcc", "copies" => 1 - } + }] }.as_json end @@ -127,10 +127,10 @@ { "id" => "24eb6a66-3833-4de6-bea4-4b614e55d5ac", "fileNumber" => "123456789", - "documentReferences" => { + "documentReferences" => [{ "id" => "23233175-6a87-4cd4-b327-f20cf5ef1222", "copies" => 1 - }, + }], "status" => "NEW", "createDate" => "" }.as_json @@ -172,12 +172,10 @@ end it "successfully sends distribution" do allow(HTTPI) - .to receive(:post) do |req| - # Making sure the request being handed to HTTPI.post - # has everything we'd expect, and that there's no funny business going on. + .to receive(:post) do |req| expect(JSON.parse(req.body)).to eq distribution_post_request end.and_return(post_distribution_success_response) - expect(subject.body.as_json).to eq(post_distribution_success_response.body) + expect(subject.first.body.as_json).to eq(post_distribution_success_response.body) end end From 2e59b8f1d8b53d64cbc02d5a2d09cbab9261c13f Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 22 May 2023 09:54:10 -0400 Subject: [PATCH 105/308] Uncommended out copies attribute in unit test --- .../models/vbms_communication_package_spec.rb | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 99eebfca9fd..bab33333a11 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -44,26 +44,26 @@ expect(package.errors[:comm_package_name]).to eq(["is invalid"]) end - it "is not valid without a copies attribute" do - package.copies = nil - expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) - end + # it "is not valid without a copies attribute" do + # package.copies = nil + # expect(package).to_not be_valid + # expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) + # end - it "is not valid with less than one copy" do - package.copies = 0 - expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) - end + # it "is not valid with less than one copy" do + # package.copies = 0 + # expect(package).to_not be_valid + # expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) + # end - it "is not valid with more than 500 copies" do - package.copies = 500 - expect(package).to be_valid + # it "is not valid with more than 500 copies" do + # package.copies = 500 + # expect(package).to be_valid - package.copies = 501 - expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) - end + # package.copies = 501 + # expect(package).to_not be_valid + # expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) + # end it "is not valid without an associated VbmsUploadedDocument" do package.vbms_uploaded_document = nil From a26601f1280aba44827816bbfdc35bd4be1adbf3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 22 May 2023 10:02:28 -0400 Subject: [PATCH 106/308] Uncommented out copies attribute in unit test --- .../models/vbms_communication_package_spec.rb | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index bab33333a11..d30f7c30159 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -5,7 +5,7 @@ VbmsCommunicationPackage.new( file_number: "329780002", comm_package_name: "test package name", - # copies: 1, + copies: 1, vbms_uploaded_document: VbmsUploadedDocument.new ) end @@ -44,26 +44,26 @@ expect(package.errors[:comm_package_name]).to eq(["is invalid"]) end - # it "is not valid without a copies attribute" do - # package.copies = nil - # expect(package).to_not be_valid - # expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) - # end + it "is not valid without a copies attribute" do + package.copies = nil + expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) + end - # it "is not valid with less than one copy" do - # package.copies = 0 - # expect(package).to_not be_valid - # expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) - # end + it "is not valid with less than one copy" do + package.copies = 0 + expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) + end - # it "is not valid with more than 500 copies" do - # package.copies = 500 - # expect(package).to be_valid + it "is not valid with more than 500 copies" do + package.copies = 500 + expect(package).to be_valid - # package.copies = 501 - # expect(package).to_not be_valid - # expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) - # end + package.copies = 501 + expect(package).to_not be_valid + expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) + end it "is not valid without an associated VbmsUploadedDocument" do package.vbms_uploaded_document = nil From 97d26fc5a369d6fc2131534e1cae75f5d12d088b Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 22 May 2023 10:46:51 -0400 Subject: [PATCH 107/308] cleaned up controller code. leaving majority of logic to the new mail_request.rb workflow. --- .../api/v1/upload_vbms_document_controller.rb | 80 +++++-------------- 1 file changed, 21 insertions(+), 59 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 50c6655c3c6..93a505f0c52 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,69 +12,31 @@ def bgs end def create - if recipient_and_destination_params - new_mailing = MailRequest.new(params) - if new_mailing.valid? - new_mailing.create_a_vbms_distribution && new_mailing.create_a_vbms_distribution_destination - elsif new_mailing.invalid? - fail Caseflow::Error::MissingRecipientInfo, "IDT Standard Error ID: " + SecureRandom.uuid + " Not enough recipient info thats needed to mail the document." - end - end + MailRequest.new(params).call + appeal = nil + # Find veteran from appeal id and check with db + if params["appeal_id"].present? + appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) + if appeal.nil? + fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." + else + params["veteran_file_number"] = appeal.veteran_file_number + end - appeal = nil - # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." else - params["veteran_file_number"] = appeal.veteran_file_number - end + file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) + if file_number.nil? + fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." + end - else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." + params["veteran_file_number"] = file_number end + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call - params["veteran_file_number"] = file_number - end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call - - if result.success? - render json: { message: "Document successfully queued for upload." } - else - render json: result.errors[0], status: :bad_request - end - end - - def recipient_and_destination_params - params.permit( - :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction, - :destination_type, - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4, - :address_line_5, - :address_line_6, - :city, - :country_code, - :postal_code, - :state, - :treat_line_2_as_addressee, - :treat_line_3_as_addressee, - :country_name, - :email_address, - :phone_number - ) + if result.success? + render json: { message: "Document successfully queued for upload." } + else + render json: result.errors[0], status: :bad_request + end end - end From d74f28d4729a774ab5c25e40302cbff41ce72d47 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 22 May 2023 10:51:03 -0400 Subject: [PATCH 108/308] logic implemented that creates a vbms_distribution and vbms_distribution_destination. currenlty raw JSON is being saved(no parsing of the values). --- app/workflows/mail_request.rb | 69 ++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 34c7bd944d1..dfc2e76ee21 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -82,6 +82,15 @@ def initialize(params) @phone_number = @params[:phone_number] end + def call + if valid? + create_a_vbms_distribution + create_a_vbms_distribution_destination + else + raise Caseflow::Error::MissingRecipientInfo + end + end + def create_a_vbms_distribution VbmsDistribution.create(recipient_params_parse) end @@ -93,53 +102,77 @@ def create_a_vbms_distribution_destination private def recipient_type_valid? - valid_var = %w[organization person system ro-colocated].include?( - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2)) - valid_var + unless @params[:recipient_type].blank? + valid_var = %w[organization person system ro-colocated].include?( + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2)) + valid_var + end end def person? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "person" + unless @params[:recipient_type].blank? + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "person" + end end def ro_colocated? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "ro-colocated" + unless @params[:recipient_type].blank? + @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "ro-colocated" + end end def destination_type_valid? - %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) + unless @params[:destination_type].blank? + %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( + @params[:destination_type].slice(1, @params[:destination_type].length - 2) + ) + end end def physical_mail? - %w[domesticAddress internationalAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2)) + unless @params[:destination_type].blank? + %w[domesticAddress internationalAddress militaryAddress].include?( + @params[:destination_type].slice(1, @params[:destination_type].length - 2) + ) + end end def line_2_addressee? - @params[:treat_line_2_as_addressee] == true + unless @params[:treat_line_2_as_addressee].blank? + @params[:treat_line_2_as_addressee] == true + end end def line_3_addressee? - @params[:treat_line_3_as_addressee] == true + unless @params[:treat_line_3_as_addressee].blank? + @params[:treat_line_3_as_addressee] == true + end end def country_name_required? - @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "internationalAddress" + unless @params[:destination_type].blank? + @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "internationalAddress" + end end def us_address? - %w[domesticAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:recipient_type].length - 2)) + unless @params[:destination_type].blank? + %w[domesticAddress militaryAddress].include?( + @params[:destination_type].slice(1, @params[:destination_type].length - 2) + ) + end end def email_required? - @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "email" + unless @params[:destination_type].blank? + @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "email" + end end def phone_number_required? - @params[:destination_type].slice(1, @params[:recipient_type].length - 2) == "sms" + unless @params[:destination_type].blank? + @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "sms" + end end def destination_params_parse @@ -175,4 +208,6 @@ def recipient_params_parse claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction } end + + end From 07e158575483cfb2a5da97bced299967e025b7da Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 09:11:21 -0400 Subject: [PATCH 109/308] Passed MailRequest object and VBMS document to MailRequestJob --- .../api/v1/upload_vbms_document_controller.rb | 52 +++++++++++-------- app/jobs/upload_document_to_vbms_job.rb | 11 +++- app/workflows/mail_request.rb | 1 + .../prepare_document_upload_to_vbms.rb | 7 ++- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 93a505f0c52..7b8c37d4a65 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,31 +12,41 @@ def bgs end def create - MailRequest.new(params).call - appeal = nil - # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." - else - params["veteran_file_number"] = appeal.veteran_file_number - end + mail_request = recipient_and_address_info + appeal = nil + # Find veteran from appeal id and check with db + if params["appeal_id"].present? + appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) + if appeal.nil? + fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." - end - - params["veteran_file_number"] = file_number + params["veteran_file_number"] = appeal.veteran_file_number end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call - if result.success? - render json: { message: "Document successfully queued for upload." } - else - render json: result.errors[0], status: :bad_request + else + file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) + if file_number.nil? + fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." end + + params["veteran_file_number"] = file_number + end + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call + + if result.success? + render json: { message: "Document successfully queued for upload." } + else + render json: result.errors[0], status: :bad_request + end + end + + private + + def recipient_and_address_info + return nil if params["recipient_type"].blank? + + # MailRequest#call will need to return the MailRequest instance + MailRequest.new(params).call end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index fa66a304c83..6b91172b334 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -10,7 +10,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # application - string with a default value of "idt" but can be overwritten # # Return: nil - def perform(document_id:, initiator_css_id:, application: "idt") + def perform(document_id:, initiator_css_id:, application: "idt", mail_request: nil) RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @@ -18,6 +18,8 @@ def perform(document_id:, initiator_css_id:, application: "idt") @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call + + queue_mail_request_job(mail_request) end private @@ -39,4 +41,11 @@ def add_context_to_sentry veteran_file_number: document.veteran_file_number ) end + + def queue_mail_request_job(mail_request) + return unless document.processed_at && mail_request + + # perform or perform_later? + MailRequestJob.perform(mail_request, document) + end end diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index dfc2e76ee21..1ca6a7c6380 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -83,6 +83,7 @@ def initialize(params) end def call + byebug if valid? create_a_vbms_distribution create_a_vbms_distribution_destination diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 68f7737e277..fb0f747a78f 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,11 +9,13 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - def initialize(params, user, appeal = nil) + # mail_request - MailRequest object with address and recipient info (optional) + def initialize(params, user, appeal = nil, mail_request = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal + @mail_request = mail_request end # Purpose: Queues a job to upload a document to vbms @@ -30,7 +32,8 @@ def call UploadDocumentToVbmsJob.perform_later( document_id: document.id, initiator_css_id: user.css_id, - application: @params[:application] + application: @params[:application], + mail_request: mail_request ) end end From f317e155644a0e2bb06a5ea4041a37db167aade6 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 24 May 2023 10:00:55 -0400 Subject: [PATCH 110/308] removed email/phone number param checks and validation logic. --- app/workflows/mail_request.rb | 86 ++++++++++++++--------------------- 1 file changed, 35 insertions(+), 51 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index dfc2e76ee21..53e915b63cb 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -8,11 +8,10 @@ class MailRequest :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, - :treat_line_3_as_addressee, :country_name, :email_address, :phone_number + :treat_line_3_as_addressee, :country_name with_options presence: true do validates :recipient_type, if: :recipient_type_valid? - validates :first_name, :last_name, if: :person? validates :poa_code, :claimant_station_of_jurisdiction, if: :ro_colocated? validates :destination_type, if: :destination_type_valid? @@ -21,11 +20,9 @@ class MailRequest validates :address_line_3, if: :line_3_addressee? validates :state, :postal_code, if: :us_address? validates :country_name, if: :country_name_required? - validates :email_address, if: :email_required? - validates :phone_number, if: :phone_number_required? end validate :name, unless: :person? - # code that checks if a vbms_distribution with held params are valid? + EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ :recipient_type, @@ -50,8 +47,7 @@ class MailRequest :treat_line_2_as_addressee, :treat_line_3_as_addressee, :country_name, - :email_address, - :phone_number + :vbms_communication_package ].freeze def initialize(params) @@ -78,14 +74,18 @@ def initialize(params) @treat_line_2_as_addressee = @params[:treat_line_2_as_addressee] @treat_line_3_as_addressee = @params[:treat_line_3_as_addressee] @country_name = @params[:country_name] - @email_address = @params[:email_address] - @phone_number = @params[:phone_number] + @vbms_communication_package = @params[:vbms_communication_package] + @vbms_distribution_id = nil + @comm_package_id = nil end def call if valid? - create_a_vbms_distribution - create_a_vbms_distribution_destination + distribution = create_a_vbms_distribution + @vbms_distribution_id = distribution.id + byebug + destination = create_a_vbms_distribution_destination + byebug else raise Caseflow::Error::MissingRecipientInfo end @@ -102,76 +102,60 @@ def create_a_vbms_distribution_destination private def recipient_type_valid? - unless @params[:recipient_type].blank? - valid_var = %w[organization person system ro-colocated].include?( - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2)) + unless @recipient_type.blank? + valid_var = %w[organization person system ro-colocated].include?(@recipient_type) valid_var end end def person? - unless @params[:recipient_type].blank? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "person" + unless @recipient_type.blank? + @recipient_type == "person" end end def ro_colocated? - unless @params[:recipient_type].blank? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "ro-colocated" + unless @recipient_type.blank? + @recipient_type == "ro-colocated" end end def destination_type_valid? - unless @params[:destination_type].blank? + unless @destination_type.blank? %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) + @destination_type ) end end def physical_mail? - unless @params[:destination_type].blank? - %w[domesticAddress internationalAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) + unless @destination_type.blank? + %w[domesticAddress internationalAddress militaryAddress].include?(@destination_type) + end end def line_2_addressee? - unless @params[:treat_line_2_as_addressee].blank? - @params[:treat_line_2_as_addressee] == true + unless @treat_line_2_as_addressee.blank? + @treat_line_2_as_addressee == true end end def line_3_addressee? - unless @params[:treat_line_3_as_addressee].blank? - @params[:treat_line_3_as_addressee] == true + unless @treat_line_3_as_addressee.blank? + @treat_line_3_as_addressee == true end end def country_name_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "internationalAddress" + unless @destination_type.blank? + @destination_type == "internationalAddress" end end def us_address? - unless @params[:destination_type].blank? - %w[domesticAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) - end - end - - def email_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "email" - end - end - - def phone_number_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "sms" + unless @destination_type.blank? + %w[domesticAddress militaryAddress].include?(@destination_type) end end @@ -185,14 +169,14 @@ def destination_params_parse address_line_5: @address_line_5, address_line_6: @address_line_6, city: @city, - country_code: @country, + country_code: @country_code, postal_code: @postal_code, state: @state, treat_line_2_as_addressee: @treat_line_2_as_addressee, treat_line_3_as_addressee: @treat_line_3_as_addressee, country_name: @country_name, - email_address: @email_address, - phone_number: @phone_number + vbms_distribution_id: @vbms_distribution_id + } end @@ -206,8 +190,8 @@ def recipient_params_parse participant_id: @participant_id, poa_code: @poa_code, claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction + # vbms_communication_package_id: 3 + } end - - end From 5f2a628a68bb52d5ee539088bcec0cb54b8fb134 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 24 May 2023 10:02:14 -0400 Subject: [PATCH 111/308] created factory to help with specs for mail_request workflow. --- spec/factories/mail_request.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 spec/factories/mail_request.rb diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb new file mode 100644 index 00000000000..0f5a786330e --- /dev/null +++ b/spec/factories/mail_request.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :valid_mail_request do + + end + + factory :invalid_mail_request do + + end +end + From e1f93ac0fe6ed7c11d8d1391804d430853450a70 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 24 May 2023 10:04:21 -0400 Subject: [PATCH 112/308] removed the optional attribute on the belongs_to relationship expressed in the beginning of the file. --- app/models/vbms_distribution.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 4902b568eac..2c769a943d8 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - belongs_to :vbms_communication_package, optional: false + belongs_to :vbms_communication_package has_many :vbms_distribution_destinations with_options presence: true do From 1fe7a990d629f9fe53d95a07ba844b7f712dc490 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 10:06:54 -0400 Subject: [PATCH 113/308] Passed MailObject to MailObjectJob after successful VBMS document upload: --- .../idt/api/v1/upload_vbms_document_controller.rb | 1 + app/jobs/upload_document_to_vbms_job.rb | 7 ++++--- app/workflows/prepare_document_upload_to_vbms.rb | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 7b8c37d4a65..118f91765d9 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -44,6 +44,7 @@ def create private def recipient_and_address_info + # Should IDT send a param e.g. "includes_communication_package"? return nil if params["recipient_type"].blank? # MailRequest#call will need to return the MailRequest instance diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 6b91172b334..b2f8e36e38a 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,6 +8,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten + # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) # # Return: nil def perform(document_id:, initiator_css_id:, application: "idt", mail_request: nil) @@ -18,8 +19,7 @@ def perform(document_id:, initiator_css_id:, application: "idt", mail_request: n @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - - queue_mail_request_job(mail_request) + queue_mail_request_job(mail_request) unless mail_request.nil? end private @@ -43,9 +43,10 @@ def add_context_to_sentry end def queue_mail_request_job(mail_request) - return unless document.processed_at && mail_request + return unless document.processed_at # perform or perform_later? + # check parameter order against MailRequestJob#perform (APPEALS-21118) MailRequestJob.perform(mail_request, document) end end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index fb0f747a78f..8c2227bc1c0 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,7 +9,7 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # mail_request - MailRequest object with address and recipient info (optional) + # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) def initialize(params, user, appeal = nil, mail_request = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] From 00ca0e781531a8f63618818439654e3532bf5f49 Mon Sep 17 00:00:00 2001 From: Minhazur Rahaman Date: Wed, 24 May 2023 10:09:56 -0400 Subject: [PATCH 114/308] APPEALS-23174 added environment variables for pacman to test environment --- config/environments/test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/environments/test.rb b/config/environments/test.rb index 739eeb2b3fb..3daa8b28e05 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -112,4 +112,8 @@ ENV["CLAIM_EVIDENCE_EFOLDER_BASE_URL"] ||= "https://vefs-claimevidence-ui-uat.stage8.bip.va.gov" ENV['TEST_VACOLS_HOST'] ||= "localhost" + + # PacMan environment variables + ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov" + ENV["PACMAN_API_KEY"] ||= "secret-key" end From 95d09e3c7a75e7be70cdaeb1ec218648cb0d800b Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 10:13:33 -0400 Subject: [PATCH 115/308] Undid changes yet to be merged from APPEALS-21123 --- app/controllers/idt/api/v1/base_controller.rb | 14 +- app/workflows/mail_request.rb | 214 ------------------ lib/caseflow/error.rb | 1 - 3 files changed, 2 insertions(+), 227 deletions(-) delete mode 100644 app/workflows/mail_request.rb diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index df7ed124723..8b2f72cf16f 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -16,8 +16,7 @@ class Idt::Api::V1::BaseController < ActionController::Base if error.class.method_defined?(:serialize_response) render(error.serialize_response) else - render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, - status: :internal_server_error + render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, status: :internal_server_error end end # :nocov: @@ -33,16 +32,7 @@ class Idt::Api::V1::BaseController < ActionController::Base log_error(error) uuid = SecureRandom.uuid Rails.logger.error("IDT Standard Error ID: " + uuid) - render(json: { message: "IDT Standard Error ID: " + uuid + " Please enter a file number in the 'FILENUMBER' header" }, - status: :unprocessable_entity) - end - - rescue_from Caseflow::Error::MissingRecipientInfo do |error| - log_error(error) - uuid = SecureRandom.uuid - Rails.logger.error("IDT Standard Error ID: " + uuid) - render(json: { message: "IDT Standard Error ID: " + uuid + " Not enough address/recipient information " }, - status: :bad_request) + render(json: { message: "IDT Standard Error ID: " + uuid + " Please enter a file number in the 'FILENUMBER' header" }, status: :unprocessable_entity) end rescue_from Caseflow::Error::VeteranNotFound do |error| diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb deleted file mode 100644 index 1ca6a7c6380..00000000000 --- a/app/workflows/mail_request.rb +++ /dev/null @@ -1,214 +0,0 @@ -# frozen_string_literal: true - -class MailRequest - include ActiveModel::Model - include ActiveModel::Validations - - attr_accessor :recipient_type, :name, :first_name, :middle_name, :last_name, - :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, - :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, - :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, - :treat_line_3_as_addressee, :country_name, :email_address, :phone_number - - with_options presence: true do - validates :recipient_type, if: :recipient_type_valid? - - validates :first_name, :last_name, if: :person? - validates :poa_code, :claimant_station_of_jurisdiction, if: :ro_colocated? - validates :destination_type, if: :destination_type_valid? - validates :address_line_1, :city, :country_code, if: :physical_mail? - validates :address_line_2, if: :line_2_addressee? - validates :address_line_3, if: :line_3_addressee? - validates :state, :postal_code, if: :us_address? - validates :country_name, if: :country_name_required? - validates :email_address, if: :email_required? - validates :phone_number, if: :phone_number_required? - end - validate :name, unless: :person? - # code that checks if a vbms_distribution with held params are valid? - - EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ - :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction, - :destination_type, - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4, - :address_line_5, - :address_line_6, - :city, - :country_code, - :postal_code, - :state, - :treat_line_2_as_addressee, - :treat_line_3_as_addressee, - :country_name, - :email_address, - :phone_number - ].freeze - - def initialize(params) - @params = params.permit(EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS) - @recipient_type = @params[:recipient_type] - @name = @params[:name] - @first_name = @params[:first_name] - @middle_name = @params[:middle_name] - @last_name = @params[:last_name] - @participant_id = @params[:participant_id] - @poa_code = @params[:poa_code] - @claimant_station_of_jurisdiction = @params[:claimant_station_of_jurisdiction] - @destination_type = @params[:destination_type] - @address_line_1 = @params[:address_line_1] - @address_line_2 = @params[:address_line_2] - @address_line_3 = @params[:address_line_3] - @address_line_4 = @params[:address_line_4] - @address_line_5 = @params[:address_line_5] - @address_line_6 = @params[:address_line_6] - @city = @params[:city] - @country_code = @params[:country_code] - @postal_code = @params[:postal_code] - @state = @params[:state] - @treat_line_2_as_addressee = @params[:treat_line_2_as_addressee] - @treat_line_3_as_addressee = @params[:treat_line_3_as_addressee] - @country_name = @params[:country_name] - @email_address = @params[:email_address] - @phone_number = @params[:phone_number] - end - - def call - byebug - if valid? - create_a_vbms_distribution - create_a_vbms_distribution_destination - else - raise Caseflow::Error::MissingRecipientInfo - end - end - - def create_a_vbms_distribution - VbmsDistribution.create(recipient_params_parse) - end - - def create_a_vbms_distribution_destination - VbmsDistributionDestination.create(destination_params_parse) - end - - private - - def recipient_type_valid? - unless @params[:recipient_type].blank? - valid_var = %w[organization person system ro-colocated].include?( - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2)) - valid_var - end - end - - def person? - unless @params[:recipient_type].blank? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "person" - end - end - - def ro_colocated? - unless @params[:recipient_type].blank? - @params[:recipient_type].slice(1, @params[:recipient_type].length - 2) == "ro-colocated" - end - end - - def destination_type_valid? - unless @params[:destination_type].blank? - %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) - end - end - - def physical_mail? - unless @params[:destination_type].blank? - %w[domesticAddress internationalAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) - end - end - - def line_2_addressee? - unless @params[:treat_line_2_as_addressee].blank? - @params[:treat_line_2_as_addressee] == true - end - end - - def line_3_addressee? - unless @params[:treat_line_3_as_addressee].blank? - @params[:treat_line_3_as_addressee] == true - end - end - - def country_name_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "internationalAddress" - end - end - - def us_address? - unless @params[:destination_type].blank? - %w[domesticAddress militaryAddress].include?( - @params[:destination_type].slice(1, @params[:destination_type].length - 2) - ) - end - end - - def email_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "email" - end - end - - def phone_number_required? - unless @params[:destination_type].blank? - @params[:destination_type].slice(1, @params[:destination_type].length - 2) == "sms" - end - end - - def destination_params_parse - { - destination_type: @destination_type, - address_line_1: @address_line_1, - address_line_2: @address_line_2, - address_line_3: @address_line_3, - address_line_4: @address_line_4, - address_line_5: @address_line_5, - address_line_6: @address_line_6, - city: @city, - country_code: @country, - postal_code: @postal_code, - state: @state, - treat_line_2_as_addressee: @treat_line_2_as_addressee, - treat_line_3_as_addressee: @treat_line_3_as_addressee, - country_name: @country_name, - email_address: @email_address, - phone_number: @phone_number - } - end - - def recipient_params_parse - { - recipient_type: @recipient_type, - name: @name, - first_name: @first_name, - middle_name: @middle_name, - last_name: @last_name, - participant_id: @participant_id, - poa_code: @poa_code, - claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction - } - end - - -end diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index f37911d4214..e7601fc7ca3 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -340,7 +340,6 @@ class MustImplementInSubclass < StandardError; end class AttributeNotLoaded < StandardError; end class VeteranNotFound < StandardError; end class AppealNotFound < StandardError; end - class MissingRecipientInfo < StandardError; end class EstablishClaimFailedInVBMS < StandardError attr_reader :error_code From 3428b97ecb882cf595a2a1035d14bc04147ebbd5 Mon Sep 17 00:00:00 2001 From: Minhazur Rahaman Date: Wed, 24 May 2023 10:51:06 -0400 Subject: [PATCH 116/308] APPEALS-23174 added in token headers to service --- app/services/external_api/pacman_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 05b2aeb4ff8..4b6691de208 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -10,7 +10,8 @@ class ExternalApi::PacmanService SEND_PACKAGE_ENDPOINT = "/package-manager-service/communication-package" GET_DISTRIBUTION_ENDPOINT = "/package-manager-service/distribution/" HEADERS = { - "Content-Type": "application/json", Accept: "application/json" + "Content-Type": "application/json", Accept: "application/json", + "TOKEN": ENV["PACMAN_API_KEY"] }.freeze class << self From 78a8825a804d8b35a0a76d74d18feef5bd0fc342 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 11:21:06 -0400 Subject: [PATCH 117/308] Used uploaded_to_vbms_at property instead of processed_at --- app/jobs/upload_document_to_vbms_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index b2f8e36e38a..5c9597b4a25 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -43,10 +43,10 @@ def add_context_to_sentry end def queue_mail_request_job(mail_request) - return unless document.processed_at + return unless document.uploaded_to_vbms_at # perform or perform_later? - # check parameter order against MailRequestJob#perform (APPEALS-21118) + # check parameter order to match MailRequestJob#perform (APPEALS-21118) MailRequestJob.perform(mail_request, document) end end From 12a4622311b7e1292459eefec0bd7fe7f4dccaea Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 15:23:05 -0400 Subject: [PATCH 118/308] Added tentative unit tests to UploadDocumentToVbmsJob --- spec/jobs/upload_document_to_vbms_job_spec.rb | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 2cb2a50cc67..8cb516076b0 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -4,9 +4,11 @@ describe ".perform" do let(:document) { create(:vbms_uploaded_document) } let(:service) { instance_double(UploadDocumentToVbms) } + let(:mail_request) { { name: "Jeff" } } + # let(:mail_request_job) { instance_double(MailRequestJob) } let(:user) { create(:user) } - subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id) } + subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id, mail_request: mail_request) } it "calls #call on UploadDocumentToVbms instance" do expect(UploadDocumentToVbms).to receive(:new).with(document: document).and_return(service) @@ -15,5 +17,22 @@ expect(service).to receive(:call) subject end + + it "does not queue a MailRequestJob without a MailRequest object present" do + mail_request = nil + expect(MailRequestJob).to_not receive(:perform) + subject + end + + it "queues a MailRequestJob if the document has been uploaded to vbms" do + document.uploaded_to_vbms_at = Time.zone.now + expect(MailRequestJob).to receive(:perform).with(document: document, mail_request: mail_request) + subject + end + + it "does not queue a MailRequestJob if the document has not been uploaded to vbms" do + expect(MailRequestJob).to_not receive(:perform) + subject + end end end From 469ab4a8b6760669eb281fb246e27e2b6b8bb53f Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 15:24:11 -0400 Subject: [PATCH 119/308] Incorporated new recipient_info param --- .../idt/api/v1/upload_vbms_document_controller.rb | 7 +++---- app/jobs/upload_document_to_vbms_job.rb | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 118f91765d9..b06f4c1c356 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,7 +12,7 @@ def bgs end def create - mail_request = recipient_and_address_info + mail_request = recipient_info_and_address appeal = nil # Find veteran from appeal id and check with db @@ -43,9 +43,8 @@ def create private - def recipient_and_address_info - # Should IDT send a param e.g. "includes_communication_package"? - return nil if params["recipient_type"].blank? + def recipient_info_and_address + return nil if params["recipient_info"].blank? # MailRequest#call will need to return the MailRequest instance MailRequest.new(params).call diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 5c9597b4a25..e1eed0d42d7 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -11,7 +11,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, application: "idt", mail_request: nil) + def perform(document_id:, initiator_css_id:, mail_request:, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user From 9e5ab6eb6d581698247735382c9ba39b540deb2e Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 24 May 2023 16:36:22 -0400 Subject: [PATCH 120/308] Refactored to reflect change to array of multiple recipients --- .../idt/api/v1/upload_vbms_document_controller.rb | 13 +++++++------ app/jobs/upload_document_to_vbms_job.rb | 8 ++++---- app/workflows/prepare_document_upload_to_vbms.rb | 6 +++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index b06f4c1c356..17efa618072 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,7 +12,7 @@ def bgs end def create - mail_request = recipient_info_and_address + mail_requests = process_recipients appeal = nil # Find veteran from appeal id and check with db @@ -32,7 +32,7 @@ def create params["veteran_file_number"] = file_number end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests).call if result.success? render json: { message: "Document successfully queued for upload." } @@ -43,10 +43,11 @@ def create private - def recipient_info_and_address - return nil if params["recipient_info"].blank? + # MailRequest#call will need to return the MailRequest instance + def process_recipients + return [] if params["recipient_info"].empty? - # MailRequest#call will need to return the MailRequest instance - MailRequest.new(params).call + recipients = params["recipient_info"] + recipients.map { |recipient_params| MailRequest.new(recipient_params).call } end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index e1eed0d42d7..4fca5fcb930 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -11,7 +11,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_request:, application: "idt") + def perform(document_id:, initiator_css_id:, mail_requests:, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @@ -19,7 +19,7 @@ def perform(document_id:, initiator_css_id:, mail_request:, application: "idt") @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_request) unless mail_request.nil? + queue_mail_request_job(mail_requests) unless mail_requests.empty? end private @@ -42,11 +42,11 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_request) + def queue_mail_request_job(mail_requests) return unless document.uploaded_to_vbms_at # perform or perform_later? # check parameter order to match MailRequestJob#perform (APPEALS-21118) - MailRequestJob.perform(mail_request, document) + MailRequestJob.perform(mail_requests, document) end end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 8c2227bc1c0..18cdb7ac43a 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,12 +10,12 @@ class PrepareDocumentUploadToVbms # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_request = nil) + def initialize(params, user, appeal = nil, mail_requests = []) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal - @mail_request = mail_request + @mail_requests = mail_requests end # Purpose: Queues a job to upload a document to vbms @@ -33,7 +33,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_request: mail_request + mail_requests: mail_requests ) end end From 522748538d21bdde0f2bc51ebdf710dfa7726eb5 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 25 May 2023 13:18:55 -0400 Subject: [PATCH 121/308] Simplified workflow in anticipation of changes to AC --- .../idt/api/v1/upload_vbms_document_controller.rb | 12 +++++------- app/jobs/upload_document_to_vbms_job.rb | 8 ++++---- app/workflows/prepare_document_upload_to_vbms.rb | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 17efa618072..c518644c0bd 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,7 +12,7 @@ def bgs end def create - mail_requests = process_recipients + mail_request = recipient_info appeal = nil # Find veteran from appeal id and check with db @@ -32,7 +32,7 @@ def create params["veteran_file_number"] = file_number end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call if result.success? render json: { message: "Document successfully queued for upload." } @@ -43,11 +43,9 @@ def create private - # MailRequest#call will need to return the MailRequest instance - def process_recipients - return [] if params["recipient_info"].empty? + def recipient_info + return nil if params["recipient_info"].blank? - recipients = params["recipient_info"] - recipients.map { |recipient_params| MailRequest.new(recipient_params).call } + MailRequest.new(address_params).call end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 4fca5fcb930..076415b70a9 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -11,7 +11,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_requests:, application: "idt") + def perform(document_id:, initiator_css_id:, mail_request: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @@ -19,7 +19,7 @@ def perform(document_id:, initiator_css_id:, mail_requests:, application: "idt") @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_requests) unless mail_requests.empty? + queue_mail_request_job(mail_request) unless mail_request.nil? end private @@ -42,11 +42,11 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_requests) + def queue_mail_request_job(mail_request) return unless document.uploaded_to_vbms_at # perform or perform_later? # check parameter order to match MailRequestJob#perform (APPEALS-21118) - MailRequestJob.perform(mail_requests, document) + MailRequestJob.perform(mail_request, document) end end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 18cdb7ac43a..d229a9a22f5 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -15,7 +15,7 @@ def initialize(params, user, appeal = nil, mail_requests = []) @document_type = @params[:document_type] @user = user @appeal = appeal - @mail_requests = mail_requests + @mail_request = mail_request end # Purpose: Queues a job to upload a document to vbms @@ -33,7 +33,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_requests: mail_requests + mail_request: @mail_request ) end end From 1ac85c3e717bd2f50eb0d1df2c001075eb7fef5a Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 25 May 2023 14:34:31 -0400 Subject: [PATCH 122/308] inserted conditional logic. providing expected behavior as stated by the AC. --- .../api/v1/upload_vbms_document_controller.rb | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 93a505f0c52..091b0d72c50 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,31 +12,33 @@ def bgs end def create - MailRequest.new(params).call - appeal = nil - # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." - else - params["veteran_file_number"] = appeal.veteran_file_number - end - + if params["recipient_info"].present? + new_mailing = MailRequest.new(params).call + end + appeal = nil + # Find veteran from appeal id and check with db + if params["appeal_id"].present? + appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) + if appeal.nil? + fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." - end - - params["veteran_file_number"] = file_number + params["veteran_file_number"] = appeal.veteran_file_number end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call - if result.success? - render json: { message: "Document successfully queued for upload." } - else - render json: result.errors[0], status: :bad_request + else + file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) + if file_number.nil? + fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." end + + params["veteran_file_number"] = file_number + end + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call + + if result.success? + render json: { message: "Document successfully queued for upload." } + else + render json: result.errors[0], status: :bad_request + end end end From 4c43035581d7009ca26e51a6a06a02c98af1b240 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 25 May 2023 14:36:06 -0400 Subject: [PATCH 123/308] chaged constant array to anticipate nested params. --- app/workflows/mail_request.rb | 84 +++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 53e915b63cb..b4302315551 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -25,6 +25,7 @@ class MailRequest EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ + recipient_info:[ :recipient_type, :name, :first_name, @@ -46,35 +47,62 @@ class MailRequest :state, :treat_line_2_as_addressee, :treat_line_3_as_addressee, - :country_name, - :vbms_communication_package - ].freeze + :country_name + ]].freeze def initialize(params) - @params = params.permit(EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS) - @recipient_type = @params[:recipient_type] - @name = @params[:name] - @first_name = @params[:first_name] - @middle_name = @params[:middle_name] - @last_name = @params[:last_name] - @participant_id = @params[:participant_id] - @poa_code = @params[:poa_code] - @claimant_station_of_jurisdiction = @params[:claimant_station_of_jurisdiction] - @destination_type = @params[:destination_type] - @address_line_1 = @params[:address_line_1] - @address_line_2 = @params[:address_line_2] - @address_line_3 = @params[:address_line_3] - @address_line_4 = @params[:address_line_4] - @address_line_5 = @params[:address_line_5] - @address_line_6 = @params[:address_line_6] - @city = @params[:city] - @country_code = @params[:country_code] - @postal_code = @params[:postal_code] - @state = @params[:state] - @treat_line_2_as_addressee = @params[:treat_line_2_as_addressee] - @treat_line_3_as_addressee = @params[:treat_line_3_as_addressee] - @country_name = @params[:country_name] - @vbms_communication_package = @params[:vbms_communication_package] + @params = params.permit( + :veteran_identifier, + :document_subject, + :document_name, + :file, + :document_type, + recipient_info:[ + :recipient_type, + :name, + :first_name, + :middle_name, + :last_name, + :participant_id, + :poa_code, + :claimant_station_of_jurisdiction, + :destination_type, + :address_line_1, + :address_line_2, + :address_line_3, + :address_line_4, + :address_line_5, + :address_line_6, + :city, + :country_code, + :postal_code, + :state, + :treat_line_2_as_addressee, + :treat_line_3_as_addressee, + :country_name]).to_h + # @recipient_info_hash = @params[:recipient_info] + @recipient_type = @params[:recipient_info][0][:recipient_type] + @name = @params[:recipient_info][0][:name] + @first_name = @params[:recipient_info][0][:first_name] + @middle_name = @params[:recipient_info][0][:middle_name] + @last_name = @params[:recipient_info][0][:last_name] + @participant_id = @params[:recipient_info][0][:participant_id] + @poa_code = @params[:recipient_info][0][:poa_code] + @claimant_station_of_jurisdiction = @params[:recipient_info][0][:claimant_station_of_jurisdiction] + @destination_type = @params[:recipient_info][0][:destination_type] + @address_line_1 = @params[:recipient_info][0][:address_line_1] + @address_line_2 = @params[:recipient_info][0][:address_line_2] + @address_line_3 = @params[:recipient_info][0][:address_line_3] + @address_line_4 = @params[:recipient_info][0][:address_line_4] + @address_line_5 = @params[:recipient_info][0][:address_line_5] + @address_line_6 = @params[:recipient_info][0][:address_line_6] + @city = @params[:recipient_info][0][:city] + @country_code = @params[:recipient_info][0][:country_code] + @postal_code = @params[:recipient_info][0][:postal_code] + @state = @params[:recipient_info][0][:state] + @treat_line_2_as_addressee = @params[:recipient_info][0][:treat_line_2_as_addressee] + @treat_line_3_as_addressee = @params[:recipient_info][0][:treat_line_3_as_addressee] + @country_name = @params[:recipient_info][0][:country_name] @vbms_distribution_id = nil @comm_package_id = nil end @@ -82,10 +110,10 @@ def initialize(params) def call if valid? distribution = create_a_vbms_distribution + byebug @vbms_distribution_id = distribution.id byebug destination = create_a_vbms_distribution_destination - byebug else raise Caseflow::Error::MissingRecipientInfo end From cfc9b81a425d380db349081d282985032897b7ce Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 25 May 2023 14:43:37 -0400 Subject: [PATCH 124/308] added test in controller to check for creation of mail req object --- .../upload_vbms_document_controller_spec.rb | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 0c1b55944e9..ce1dcb8cadd 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -7,12 +7,34 @@ let(:veteran) { appeal.veteran } let(:file_number) { appeal.veteran.file_number } let(:valid_document_type) { "BVA Decision" } + let(:mail_request_object){create(:valid_mail_request)} let(:params) do { appeal_id: appeal.external_id, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", document_type: valid_document_type } end + let(:mail_request_params) do + { + recipient_info: [ + { + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + } + ] + } + end + let(:params_identifier) do { veteran_identifier: veteran.file_number, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", @@ -130,6 +152,11 @@ end shared_examples "success_with_valid_parameters" do + it "creates a new Mail Request object when optional params exist" do + expect_any_instance_of(MailRequest).to receive(:call) + post :create, params: mail_request_params + end + it "returns a successful message and creates a new VbmsUploadedDocument" do expect { post :create, params: params }.to change(VbmsUploadedDocument, :count).by(1) From 900b3ea9eefd0a9375d0f16c6e626536d3faa809 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 25 May 2023 14:47:53 -0400 Subject: [PATCH 125/308] factories for valid mail request object and invalid mail request object created. --- spec/factories/mail_request.rb | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index 0f5a786330e..9dff04014ff 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -2,11 +2,30 @@ FactoryBot.define do factory :valid_mail_request do - + recipient_type { "person" } + first_name { "Bob" } + last_name { "Smithcole" } + participant_id { 640_460_002 } + destination_type { "domesticAddress" } + address_line_1 { "1234 Main Street" } + city { "Orlando" } + country_code { "US"} + postal_code { "12345" } + state { "FL" } + treat_line_2_as_addressee { false } + treat_line_3_as_addressee { false } end factory :invalid_mail_request do - + recipient_type { "person" } + first_name { "Bob" } + participant_id { 640_460_002 } + address_line_1 { "1234 Main Street" } + city { "Orlando" } + country_code { "US"} + postal_code { 12_345 } + state { "FL" } + treat_line_2_as_addressee { false } + treat_line_3_as_addressee { false } end end - From 13f23934c9ac08109d9791950cf081559a2164e0 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 26 May 2023 09:35:27 -0400 Subject: [PATCH 126/308] Refactored mail_request default value --- app/jobs/upload_document_to_vbms_job.rb | 2 +- .../prepare_document_upload_to_vbms.rb | 2 +- spec/jobs/upload_document_to_vbms_job_spec.rb | 21 +------------------ 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 076415b70a9..eaade5a66b3 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -45,7 +45,7 @@ def add_context_to_sentry def queue_mail_request_job(mail_request) return unless document.uploaded_to_vbms_at - # perform or perform_later? + # perform_now or perform_later? # check parameter order to match MailRequestJob#perform (APPEALS-21118) MailRequestJob.perform(mail_request, document) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index d229a9a22f5..b3f52fa72d9 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,7 +10,7 @@ class PrepareDocumentUploadToVbms # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_requests = []) + def initialize(params, user, appeal = nil, mail_request = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 8cb516076b0..2cb2a50cc67 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -4,11 +4,9 @@ describe ".perform" do let(:document) { create(:vbms_uploaded_document) } let(:service) { instance_double(UploadDocumentToVbms) } - let(:mail_request) { { name: "Jeff" } } - # let(:mail_request_job) { instance_double(MailRequestJob) } let(:user) { create(:user) } - subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id, mail_request: mail_request) } + subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id) } it "calls #call on UploadDocumentToVbms instance" do expect(UploadDocumentToVbms).to receive(:new).with(document: document).and_return(service) @@ -17,22 +15,5 @@ expect(service).to receive(:call) subject end - - it "does not queue a MailRequestJob without a MailRequest object present" do - mail_request = nil - expect(MailRequestJob).to_not receive(:perform) - subject - end - - it "queues a MailRequestJob if the document has been uploaded to vbms" do - document.uploaded_to_vbms_at = Time.zone.now - expect(MailRequestJob).to receive(:perform).with(document: document, mail_request: mail_request) - subject - end - - it "does not queue a MailRequestJob if the document has not been uploaded to vbms" do - expect(MailRequestJob).to_not receive(:perform) - subject - end end end From 3b32a31c8e8cfdbd067a5d7f1740c263480ac039 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 26 May 2023 10:34:57 -0400 Subject: [PATCH 127/308] Added logging --- .../idt/api/v1/upload_vbms_document_controller.rb | 2 +- app/jobs/upload_document_to_vbms_job.rb | 11 ++++++++--- app/workflows/upload_document_to_vbms.rb | 6 ++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index c518644c0bd..df4c7bf9fdd 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -46,6 +46,6 @@ def create def recipient_info return nil if params["recipient_info"].blank? - MailRequest.new(address_params).call + MailRequest.new(params).call end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index eaade5a66b3..90c6206cdb2 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -45,8 +45,13 @@ def add_context_to_sentry def queue_mail_request_job(mail_request) return unless document.uploaded_to_vbms_at - # perform_now or perform_later? - # check parameter order to match MailRequestJob#perform (APPEALS-21118) - MailRequestJob.perform(mail_request, document) + MailRequestJob.perform_later(document, mail_request) + status = "MailRequestJob queued for submission to Package Manager" + log_info(document: document, mail_request: mail_request, status: status) + end + + def log_info(info_message) + uuid = SecureRandom.uuid + Rails.logger.info(info_message + "ID: " + uuid) end end diff --git a/app/workflows/upload_document_to_vbms.rb b/app/workflows/upload_document_to_vbms.rb index 8560a9ba76c..dbf0312a768 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -13,6 +13,7 @@ def call submit_for_processing! upload_to_vbms! set_processed_at_to_current_time + log_info(document: document, status: "Document uploaded to VBMS") rescue StandardError => error save_rescued_error!(error.to_s) raise error @@ -83,6 +84,11 @@ 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. # From 788bbc6c2809a070afe598786333fa28c9ba30d0 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 26 May 2023 15:36:54 -0400 Subject: [PATCH 128/308] Refactored UploadVbmsDocumentController#create to be more DRY --- .../api/v1/upload_vbms_document_controller.rb | 56 +++++++++++++------ app/jobs/upload_document_to_vbms_job.rb | 8 +-- .../prepare_document_upload_to_vbms.rb | 6 +- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index df4c7bf9fdd..ee585d83b81 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,27 +12,16 @@ def bgs end def create - mail_request = recipient_info + mail_requests = recipient_info appeal = nil # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." - else - params["veteran_file_number"] = appeal.veteran_file_number - end - + if appeal_id.present? + appeal = find_by_appeal_id else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." - end - - params["veteran_file_number"] = file_number + find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests).call if result.success? render json: { message: "Document successfully queued for upload." } @@ -44,8 +33,39 @@ def create private def recipient_info - return nil if params["recipient_info"].blank? + return [] if params["recipient_info"].blank? + + addresses = params["recipient_info"] + addresses.map { |address_params| MailRequest.new(address_params).call } + end + + def appeal_id + params["appeal_id"] + end + + def veteran_identifier + params["veteran_identifier"] + end + + def find_by_appeal_id + appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) + throw_not_found_error("appeal") if appeal.nil? + update_veteran_file_number(appeal.veteran_file_number) + appeal + end + + def find_file_number_by_veteran_identifier + file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || bgs.fetch_file_number_by_ssn(veteran_identifier) + throw_not_found_error("veteran") if file_number.nil? + update_veteran_file_number(file_number) + end + + def update_veteran_file_number(file_number) + params["veteran_file_number"] = file_number + end - MailRequest.new(params).call + def throw_not_found_error(name) + uuid = SecureRandom.uuid + fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + uuid + " The #{name} was unable to be found." end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 90c6206cdb2..cd3f8383a31 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -11,7 +11,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_request: nil, application: "idt") + def perform(document_id:, initiator_css_id:, mail_requests: [], application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @@ -19,7 +19,7 @@ def perform(document_id:, initiator_css_id:, mail_request: nil, application: "id @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_request) unless mail_request.nil? + queue_mail_request_job(mail_requests) unless mail_requests.empty? end private @@ -42,10 +42,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_request) + def queue_mail_request_job(mail_requests) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_request) + MailRequestJob.perform_later(document, mail_requests) status = "MailRequestJob queued for submission to Package Manager" log_info(document: document, mail_request: mail_request, status: status) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index b3f52fa72d9..a782c41c7ad 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,12 +10,12 @@ class PrepareDocumentUploadToVbms # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_request = nil) + def initialize(params, user, appeal = nil, mail_requests = []) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal - @mail_request = mail_request + @mail_requests = mail_requests end # Purpose: Queues a job to upload a document to vbms @@ -33,7 +33,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_request: @mail_request + mail_requests: @mail_requests ) end end From d2b0a10b2b0515692e4641a31c59ef6b6e9b3b34 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 26 May 2023 17:13:58 -0400 Subject: [PATCH 129/308] Refactored private methods --- .../api/v1/upload_vbms_document_controller.rb | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index ee585d83b81..547a2e2328e 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -7,12 +7,8 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController skip_before_action :verify_authenticity_token, only: [:create] before_action :verify_access - def bgs - @bgs ||= BGSService.new - end - def create - mail_requests = recipient_info + mail_requests = create_mail_requests appeal = nil # Find veteran from appeal id and check with db @@ -33,10 +29,7 @@ def create private def recipient_info - return [] if params["recipient_info"].blank? - - addresses = params["recipient_info"] - addresses.map { |address_params| MailRequest.new(address_params).call } + params["recipient_info"] end def appeal_id @@ -47,6 +40,17 @@ def veteran_identifier params["veteran_identifier"] end + def bgs + @bgs ||= BGSService.new + end + + def create_mail_requests + return [] if recipient_info.blank? + + addresses = recipient_info + addresses.map { |address_params| MailRequest.new(address_params).call } + end + def find_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) throw_not_found_error("appeal") if appeal.nil? From db551d294e0a83c2518d286d6ea62e13eba6942b Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 26 May 2023 17:16:08 -0400 Subject: [PATCH 130/308] Changed variable names --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 547a2e2328e..fa50738ecaa 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -47,8 +47,7 @@ def bgs def create_mail_requests return [] if recipient_info.blank? - addresses = recipient_info - addresses.map { |address_params| MailRequest.new(address_params).call } + recipient_info.map { |address_params| MailRequest.new(address_params).call } end def find_by_appeal_id From f3b1e07d0a948ad0f99fefe14a26ef45a60c4d47 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 30 May 2023 09:32:00 -0400 Subject: [PATCH 131/308] Changed method names to be more descriptive --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index fa50738ecaa..4dd83e17545 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -13,7 +13,7 @@ def create appeal = nil # Find veteran from appeal id and check with db if appeal_id.present? - appeal = find_by_appeal_id + appeal = find_veteran_by_appeal_id else find_file_number_by_veteran_identifier end @@ -50,7 +50,7 @@ def create_mail_requests recipient_info.map { |address_params| MailRequest.new(address_params).call } end - def find_by_appeal_id + def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) throw_not_found_error("appeal") if appeal.nil? update_veteran_file_number(appeal.veteran_file_number) From 16e87f07fb5a63bca23053b14a6ae2569d661123 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 30 May 2023 15:19:12 -0400 Subject: [PATCH 132/308] Changed mail_request back to object instead of array of objects to meet new AC --- .../idt/api/v1/upload_vbms_document_controller.rb | 10 +++++----- app/jobs/upload_document_to_vbms_job.rb | 15 ++++++++------- app/workflows/prepare_document_upload_to_vbms.rb | 8 ++++---- app/workflows/upload_document_to_vbms.rb | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 4dd83e17545..441f83c4997 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -8,7 +8,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController before_action :verify_access def create - mail_requests = create_mail_requests + mail_request = create_mail_request appeal = nil # Find veteran from appeal id and check with db @@ -17,7 +17,7 @@ def create else find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call if result.success? render json: { message: "Document successfully queued for upload." } @@ -44,10 +44,10 @@ def bgs @bgs ||= BGSService.new end - def create_mail_requests - return [] if recipient_info.blank? + def create_mail_request + return nil if recipient_info.blank? - recipient_info.map { |address_params| MailRequest.new(address_params).call } + MailRequest.new(recipient_info).call end def find_veteran_by_appeal_id diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index cd3f8383a31..fc17d4b1c97 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,10 +8,10 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten - # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) + # mail_request - MailRequest object with address info to be sent to Package Manager (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_requests: [], application: "idt") + def perform(document_id:, initiator_css_id:, mail_request: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @@ -19,7 +19,8 @@ def perform(document_id:, initiator_css_id:, mail_requests: [], application: "id @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_requests) unless mail_requests.empty? + byebug + queue_mail_request_job(mail_request) unless mail_request.nil? end private @@ -42,12 +43,12 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_requests) + def queue_mail_request_job(mail_request) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_requests) - status = "MailRequestJob queued for submission to Package Manager" - log_info(document: document, mail_request: mail_request, status: status) + MailRequestJob.perform_later(document, mail_request) + info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" + log_info(info_message) end def log_info(info_message) diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index a782c41c7ad..4070cd69650 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,13 +9,13 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # mail_request - MailRequest object with recipient/address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_requests = []) + # mail_request - MailRequest object with address info to be sent to Package Manager (optional) + def initialize(params, user, appeal = nil, mail_request = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal - @mail_requests = mail_requests + @mail_request = mail_request end # Purpose: Queues a job to upload a document to vbms @@ -33,7 +33,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_requests: @mail_requests + mail_request: @mail_request ) end end diff --git a/app/workflows/upload_document_to_vbms.rb b/app/workflows/upload_document_to_vbms.rb index dbf0312a768..8e360624de4 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -13,7 +13,7 @@ def call submit_for_processing! upload_to_vbms! set_processed_at_to_current_time - log_info(document: document, status: "Document uploaded to VBMS") + log_info("Document #{document.id} uploaded to VBMS") rescue StandardError => error save_rescued_error!(error.to_s) raise error From cc6fddc28d87e2d2a6861ba04e68158cf2c24167 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 30 May 2023 16:55:22 -0400 Subject: [PATCH 133/308] Completed unit test --- app/jobs/upload_document_to_vbms_job.rb | 1 - .../prepare_document_upload_to_vbms.rb | 2 +- spec/jobs/upload_document_to_vbms_job_spec.rb | 34 ++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index fc17d4b1c97..59c4fdee6a2 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -19,7 +19,6 @@ def perform(document_id:, initiator_css_id:, mail_request: nil, application: "id @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - byebug queue_mail_request_job(mail_request) unless mail_request.nil? end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 4070cd69650..992f5781212 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,7 +10,7 @@ class PrepareDocumentUploadToVbms # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) # mail_request - MailRequest object with address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_request = nil) + def initialize(params, user, appeal = nil, mail_request = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 2cb2a50cc67..4bf9198f391 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -5,8 +5,17 @@ let(:document) { create(:vbms_uploaded_document) } let(:service) { instance_double(UploadDocumentToVbms) } let(:user) { create(:user) } + # let(:mail_request) { instance_double(MailRequest) } + let(:mail_request) { { name: "Jeff" } } + let(:mail_request_job) { class_double("MailRequestJob", :perform_later).as_stubbed_const } - subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id) } + let(:params) do + { document_id: document.id, + initiator_css_id: user.css_id, + mail_request: mail_request } + end + + subject { UploadDocumentToVbmsJob.perform_now(params) } it "calls #call on UploadDocumentToVbms instance" do expect(UploadDocumentToVbms).to receive(:new).with(document: document).and_return(service) @@ -15,5 +24,28 @@ expect(service).to receive(:call) subject end + + context "document is associated with a mail request" do + it "calls #perform_later on MailRequestJob" do + expect(mail_request_job).to receive(:perform_later).with(document, mail_request) + subject + end + end + + context "document is not associated with a mail request" do + let(:mail_request) { nil } + it "does not call #perform_later on MailRequestJob" do + expect(mail_request_job).to_not receive(:perform_later) + subject + end + end + + context "document is not successfully uploaded to vbms" do + it "does not call #perform_later on MailRequestJob" do + allow(VBMSService).to receive(:upload_document_to_vbms_veteran).and_raise(StandardError) + expect(mail_request_job).to_not receive(:perform_later) + expect { subject }.to raise_error(StandardError) + end + end end end From fab778af8ace44721d6028e568f6e14742a33c71 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 31 May 2023 09:21:54 -0400 Subject: [PATCH 134/308] APPEALS-21123 provided functionality for multiple recipient_info parameters. --- .../api/v1/upload_vbms_document_controller.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 091b0d72c50..68d2f807b79 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -13,7 +13,11 @@ def bgs def create if params["recipient_info"].present? - new_mailing = MailRequest.new(params).call + params["recipient_info"].map do |recipient| + mail_req = MailRequest.new(recipient).call + # Need to do soemthing with this value at this point in time + # >> mail_req.vbms_distribution_id if I want to return the ids from this file. + end end appeal = nil # Find veteran from appeal id and check with db @@ -36,9 +40,17 @@ def create result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call if result.success? - render json: { message: "Document successfully queued for upload." } + upload_result_successful else render json: result.errors[0], status: :bad_request end end + + private + def upload_result_successful + render json: { + message: "Document successfully queued for upload.", + distribution_ids: "1, 2, 4" + } + end end From de7b29f915b315d4e7fd4a8bf5bc4639cb0b0f5c Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 31 May 2023 09:24:37 -0400 Subject: [PATCH 135/308] APPEALS-21123 removed frozen array. made adjustments to init method. place create methods under the private keyword. --- app/workflows/mail_request.rb | 117 ++++++++-------------------------- 1 file changed, 28 insertions(+), 89 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index b4302315551..6692fc5ce5a 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -23,86 +23,29 @@ class MailRequest end validate :name, unless: :person? - - EXPECTED_PARAMS_FOR_RECIPIENTS_AND_DESTINATIONS = [ - recipient_info:[ - :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction, - :destination_type, - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4, - :address_line_5, - :address_line_6, - :city, - :country_code, - :postal_code, - :state, - :treat_line_2_as_addressee, - :treat_line_3_as_addressee, - :country_name - ]].freeze - - def initialize(params) - @params = params.permit( - :veteran_identifier, - :document_subject, - :document_name, - :file, - :document_type, - recipient_info:[ - :recipient_type, - :name, - :first_name, - :middle_name, - :last_name, - :participant_id, - :poa_code, - :claimant_station_of_jurisdiction, - :destination_type, - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4, - :address_line_5, - :address_line_6, - :city, - :country_code, - :postal_code, - :state, - :treat_line_2_as_addressee, - :treat_line_3_as_addressee, - :country_name]).to_h - # @recipient_info_hash = @params[:recipient_info] - @recipient_type = @params[:recipient_info][0][:recipient_type] - @name = @params[:recipient_info][0][:name] - @first_name = @params[:recipient_info][0][:first_name] - @middle_name = @params[:recipient_info][0][:middle_name] - @last_name = @params[:recipient_info][0][:last_name] - @participant_id = @params[:recipient_info][0][:participant_id] - @poa_code = @params[:recipient_info][0][:poa_code] - @claimant_station_of_jurisdiction = @params[:recipient_info][0][:claimant_station_of_jurisdiction] - @destination_type = @params[:recipient_info][0][:destination_type] - @address_line_1 = @params[:recipient_info][0][:address_line_1] - @address_line_2 = @params[:recipient_info][0][:address_line_2] - @address_line_3 = @params[:recipient_info][0][:address_line_3] - @address_line_4 = @params[:recipient_info][0][:address_line_4] - @address_line_5 = @params[:recipient_info][0][:address_line_5] - @address_line_6 = @params[:recipient_info][0][:address_line_6] - @city = @params[:recipient_info][0][:city] - @country_code = @params[:recipient_info][0][:country_code] - @postal_code = @params[:recipient_info][0][:postal_code] - @state = @params[:recipient_info][0][:state] - @treat_line_2_as_addressee = @params[:recipient_info][0][:treat_line_2_as_addressee] - @treat_line_3_as_addressee = @params[:recipient_info][0][:treat_line_3_as_addressee] - @country_name = @params[:recipient_info][0][:country_name] + def initialize(recipient_and_destination_hash) + @recipient_type = recipient_and_destination_hash[:recipient_type] + @name = recipient_and_destination_hash[:name] + @first_name = recipient_and_destination_hash[:first_name] + @middle_name = recipient_and_destination_hash[:middle_name] + @last_name = recipient_and_destination_hash[:last_name] + @participant_id = recipient_and_destination_hash[:participant_id] + @poa_code = recipient_and_destination_hash[:poa_code] + @claimant_station_of_jurisdiction = recipient_and_destination_hash[:claimant_station_of_jurisdiction] + @destination_type = recipient_and_destination_hash[:destination_type] + @address_line_1 = recipient_and_destination_hash[:address_line_1] + @address_line_2 = recipient_and_destination_hash[:address_line_2] + @address_line_3 = recipient_and_destination_hash[:address_line_3] + @address_line_4 = recipient_and_destination_hash[:address_line_4] + @address_line_5 = recipient_and_destination_hash[:address_line_5] + @address_line_6 = recipient_and_destination_hash[:address_line_6] + @city = recipient_and_destination_hash[:city] + @country_code = recipient_and_destination_hash[:country_code] + @postal_code = recipient_and_destination_hash[:postal_code] + @state = recipient_and_destination_hash[:state] + @treat_line_2_as_addressee = recipient_and_destination_hash[:treat_line_2_as_addressee] + @treat_line_3_as_addressee = recipient_and_destination_hash[:treat_line_3_as_addressee] + @country_name = recipient_and_destination_hash[:country_name] @vbms_distribution_id = nil @comm_package_id = nil end @@ -110,25 +53,23 @@ def initialize(params) def call if valid? distribution = create_a_vbms_distribution - byebug @vbms_distribution_id = distribution.id - byebug - destination = create_a_vbms_distribution_destination + create_a_vbms_distribution_destination else raise Caseflow::Error::MissingRecipientInfo end end + private + def create_a_vbms_distribution - VbmsDistribution.create(recipient_params_parse) + VbmsDistribution.create!(recipient_params_parse) end def create_a_vbms_distribution_destination - VbmsDistributionDestination.create(destination_params_parse) + VbmsDistributionDestination.create!(destination_params_parse) end - private - def recipient_type_valid? unless @recipient_type.blank? valid_var = %w[organization person system ro-colocated].include?(@recipient_type) @@ -218,8 +159,6 @@ def recipient_params_parse participant_id: @participant_id, poa_code: @poa_code, claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction - # vbms_communication_package_id: 3 - } end end From 4c6ce022c297d60a0903fa4011d4bec28ef62b1f Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 31 May 2023 09:25:42 -0400 Subject: [PATCH 136/308] APPEALS-21123 spec clean-up. --- .../idt/api/v1/upload_vbms_document_controller_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index ce1dcb8cadd..9cce398be85 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -7,7 +7,6 @@ let(:veteran) { appeal.veteran } let(:file_number) { appeal.veteran.file_number } let(:valid_document_type) { "BVA Decision" } - let(:mail_request_object){create(:valid_mail_request)} let(:params) do { appeal_id: appeal.external_id, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", From 13d73520c92285b78f03e7ecb8b18bc191d668f8 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 31 May 2023 10:05:50 -0400 Subject: [PATCH 137/308] Updated unit tests with instance and class doubles --- spec/jobs/upload_document_to_vbms_job_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 4bf9198f391..2dc3e3a994f 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -5,9 +5,8 @@ let(:document) { create(:vbms_uploaded_document) } let(:service) { instance_double(UploadDocumentToVbms) } let(:user) { create(:user) } - # let(:mail_request) { instance_double(MailRequest) } - let(:mail_request) { { name: "Jeff" } } - let(:mail_request_job) { class_double("MailRequestJob", :perform_later).as_stubbed_const } + let(:mail_request) { instance_double(MailRequest) } + let(:mail_request_job) { class_double(MailRequestJob) } let(:params) do { document_id: document.id, From 041dac47c13a52ad677f8956c060386025de8ebb Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 31 May 2023 10:52:29 -0400 Subject: [PATCH 138/308] APPEALS-21118 updated perform method parameters --- app/jobs/mail_request_job.rb | 76 ++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 4d8b01e238e..c4735846fa2 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -3,30 +3,82 @@ class MailRequestJob < CaseflowJob queue_with_priority :low_priority application_attr :intake - - def perform(vbms_comm_package) - package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_comm_package.file_number, - vbms_comm_package.comm_package_name, +# copies based on number of recipients +# But then how to get document reference id? +# is that even needed still? if not, pacman service needs to be changed + def perform(vbms_uploaded_document, mail_request) + package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, + mail_request.name, vbms_comm_package.document_referenced) log_info(package_response) + vbms_comm_package = create_package(vbms_uploaded_document, mail_request) +# FIXME what do we want when the response is an error? +# should a VbmsCommunicationPackage object still be created? if package_response.code == 201 vbms_comm_package.update!(status: "success") - create_distribution(vbms_comm_package.id) + create_distribution_request(vbms_comm_package.id, mail_request) else vbms_comm_package.update!(status: "error") log_error(error_msg(package_response.code)) end end +# FIXME how to get created_by_id + def create_package(vbms_uploaded_document, mail_request) + VbmsCommunicationPackage.new( + comm_package_name: mail_request.name, + created_at: Time.zone.now, + created_by_id: "", + copies: nil, + file_number: vbms_uploaded_document.veteran_file_number, + status: nil, + updated_at: Time.zone.now, + updated_by_id: " ", + vbms_uploaded_document_id: vbms_uploaded_document.id + ) + end + + def create_distribution(package_id, mail_request) + VbmsDistribution.new( + claimant_station_of_jurisdiction: mail_request.claimant_station_of_jurisdiction, + created_at: Time.zone.now, + created_by_id: "", + first_name: mail_request.first_name, + last_name: mail_request.last_name, + middle_name: mail_request.middle_name, + name: mail_request.name, + participant_id: mail_request.participant_id, + poa_code: mail_request.poa_code, + recipient_type: mail_request.recipient_type, + updated_at: Time.zone.now, + updated_by_id: "", + vbms_communication_package_id: package_id + ) + + end + + def create_distribution_destinations(dist_id, mail_request) + + end + + def get_recipient_array(mail_request) + + end - def create_distribution(package_id) - dist = VbmsDistribution.find_by(vbms_communication_package_id: package_id) - dist_dest = VbmsDistributionDestination.find_by(dist.id) - distribution = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) - log_info(distribution) - if distribution.code != 201 + def get_destination_array(mail_request) + + end +# multiple recipients and destinations? +# how will those be packaged in mail_request? + def create_distribution_request(package_id, mail_request) + distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) + log_info(distribution_response) + if distribution_response.code == 201 + distribution = create_distribution(package_id, mail_request) + create_distribution_destinations + else log_error(error_msg(distribution.code)) end - distribution + distribution.uuid end def log_error(error_msg) From af0414efeb3c97a6e27d36a1b2d29140b48b1aae Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 31 May 2023 14:05:17 -0400 Subject: [PATCH 139/308] APPEALS-21123 controller fixed to return distribution_ids along with message as JSON --- .../idt/api/v1/upload_vbms_document_controller.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 68d2f807b79..8bce958d724 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -6,18 +6,18 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController protect_from_forgery with: :exception skip_before_action :verify_authenticity_token, only: [:create] before_action :verify_access - + id_array = [] def bgs @bgs ||= BGSService.new end def create if params["recipient_info"].present? - params["recipient_info"].map do |recipient| + id_array = params["recipient_info"].map do |recipient| mail_req = MailRequest.new(recipient).call - # Need to do soemthing with this value at this point in time - # >> mail_req.vbms_distribution_id if I want to return the ids from this file. + mail_req.vbms_distribution_id end + end appeal = nil # Find veteran from appeal id and check with db @@ -40,17 +40,18 @@ def create result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call if result.success? - upload_result_successful + upload_result_successful(id_array) else render json: result.errors[0], status: :bad_request end end private - def upload_result_successful + + def upload_result_successful(array) render json: { message: "Document successfully queued for upload.", - distribution_ids: "1, 2, 4" + distribution_ids: array } end end From 08fc47230d4d7c7692405d3e67bd3ae0cc0d67e3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 31 May 2023 16:07:06 -0400 Subject: [PATCH 140/308] Fixed spacing in rails log message --- app/jobs/upload_document_to_vbms_job.rb | 3 +-- app/workflows/upload_document_to_vbms.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 59c4fdee6a2..e4d4573b626 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -14,7 +14,6 @@ class UploadDocumentToVbmsJob < CaseflowJob def perform(document_id:, initiator_css_id:, mail_request: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user - @document = VbmsUploadedDocument.find_by(id: document_id) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry @@ -52,6 +51,6 @@ def queue_mail_request_job(mail_request) def log_info(info_message) uuid = SecureRandom.uuid - Rails.logger.info(info_message + "ID: " + uuid) + Rails.logger.info(info_message + " ID: " + uuid) end end diff --git a/app/workflows/upload_document_to_vbms.rb b/app/workflows/upload_document_to_vbms.rb index 8e360624de4..6c8bb913523 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -86,7 +86,7 @@ def file_number def log_info(info_message) uuid = SecureRandom.uuid - Rails.logger.info(info_message + "ID: " + uuid) + Rails.logger.info(info_message + " ID: " + uuid) end # Purpose: Get the s3_sub_bucket based on the document type From 665fb0be87c997d2936a690dbfa587c1313541ce Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 1 Jun 2023 13:57:41 -0400 Subject: [PATCH 141/308] APPEALS-21123 made edit to missing_recipient_info error in file. --- app/controllers/idt/api/v1/base_controller.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index df7ed124723..cd9d367ca8c 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -40,9 +40,7 @@ class Idt::Api::V1::BaseController < ActionController::Base rescue_from Caseflow::Error::MissingRecipientInfo do |error| log_error(error) uuid = SecureRandom.uuid - Rails.logger.error("IDT Standard Error ID: " + uuid) - render(json: { message: "IDT Standard Error ID: " + uuid + " Not enough address/recipient information " }, - status: :bad_request) + Rails.logger.error("IDT Standard Error ID: " + uuid + " Not enough address/recipient information for a successful mail request. ") end rescue_from Caseflow::Error::VeteranNotFound do |error| From 768da808d9c0653be1b239e01716ee089d81c0ae Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 1 Jun 2023 14:01:43 -0400 Subject: [PATCH 142/308] added begin/ensure blocks. providing functionality that will allow code to continue even if an exception rises. --- .../api/v1/upload_vbms_document_controller.rb | 70 +++++++++++-------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 8bce958d724..be26f44b625 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -6,52 +6,60 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController protect_from_forgery with: :exception skip_before_action :verify_authenticity_token, only: [:create] before_action :verify_access - id_array = [] + def bgs @bgs ||= BGSService.new end def create - if params["recipient_info"].present? - id_array = params["recipient_info"].map do |recipient| - mail_req = MailRequest.new(recipient).call - mail_req.vbms_distribution_id + id_array = [] + begin + if params["recipient_info"].present? + id_array = params["recipient_info"].map do |recipient| + mail_req = MailRequest.new(recipient).call + mail_req.vbms_distribution_id + end end + ensure + appeal = nil + # Find veteran from appeal id and check with db + if params["appeal_id"].present? + appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) + if appeal.nil? + fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." + else + params["veteran_file_number"] = appeal.veteran_file_number + end - end - appeal = nil - # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." else - params["veteran_file_number"] = appeal.veteran_file_number - end + file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) + if file_number.nil? + fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." + end - else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." + params["veteran_file_number"] = file_number + end + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call + if result.success? + upload_result_successful(id_array) + else + render json: result.errors[0], status: :bad_request end - - params["veteran_file_number"] = file_number - end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call - - if result.success? - upload_result_successful(id_array) - else - render json: result.errors[0], status: :bad_request end end private def upload_result_successful(array) - render json: { - message: "Document successfully queued for upload.", - distribution_ids: array - } + if array.empty? + render json: { + message: "Document successfully queued for upload." + } + else + render json: { + message: "Document successfully queued for upload.", + distribution_ids: array + } + end end end From beedc9007e11d2b574c4bacf8f49c339d5ff3f01 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 2 Jun 2023 13:18:24 -0400 Subject: [PATCH 143/308] updated logic in file adding and additional attribute to the accessor block. --- app/workflows/mail_request.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 6692fc5ce5a..d5a6f8960d4 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -8,7 +8,7 @@ class MailRequest :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, - :treat_line_3_as_addressee, :country_name + :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id with_options presence: true do validates :recipient_type, if: :recipient_type_valid? @@ -53,9 +53,10 @@ def initialize(recipient_and_destination_hash) def call if valid? distribution = create_a_vbms_distribution + byebug @vbms_distribution_id = distribution.id create_a_vbms_distribution_destination - else + elsif invalid? raise Caseflow::Error::MissingRecipientInfo end end From 8428f6cbeabc8b36b49ffbe40807407fd48f040b Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 2 Jun 2023 13:19:16 -0400 Subject: [PATCH 144/308] APPEALS-21123 added code to handle incomplete params. --- .../api/v1/upload_vbms_document_controller.rb | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index be26f44b625..b444bc65895 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,14 +12,24 @@ def bgs end def create - id_array = [] + success_json = { + message: "Document successfully queued for upload." + } begin if params["recipient_info"].present? - id_array = params["recipient_info"].map do |recipient| - mail_req = MailRequest.new(recipient).call + success_json[:distribution_ids] = params["recipient_info"].map do |recipient| + mail_req = MailRequest.new(recipient) + if mail_req.invalid? + success_json[:error_messages] = mail_req.errors.messages + # byebug + end + mail_req.call mail_req.vbms_distribution_id end end + rescue Caseflow::Error::MissingRecipientInfo => error + success_json[:errors] = "Incomplete mailing informaiton provided. No mail request was created." + raise error ensure appeal = nil # Find veteran from appeal id and check with db @@ -41,25 +51,10 @@ def create end result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call if result.success? - upload_result_successful(id_array) + render json: success_json else render json: result.errors[0], status: :bad_request end end end - - private - - def upload_result_successful(array) - if array.empty? - render json: { - message: "Document successfully queued for upload." - } - else - render json: { - message: "Document successfully queued for upload.", - distribution_ids: array - } - end - end end From d33720f6478f0ac53c8a8dbda8d6c16b0e4f3d36 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 2 Jun 2023 13:40:40 -0400 Subject: [PATCH 145/308] APPEALS-21123 added accessors. adjusted call method. --- app/workflows/mail_request.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index d5a6f8960d4..e2494937462 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -53,7 +53,6 @@ def initialize(recipient_and_destination_hash) def call if valid? distribution = create_a_vbms_distribution - byebug @vbms_distribution_id = distribution.id create_a_vbms_distribution_destination elsif invalid? From 582850ad5890ec07c5dfe376d1444e28bd47a629 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 2 Jun 2023 13:41:03 -0400 Subject: [PATCH 146/308] APPEALS-21123 added code to handle incomplete params. --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index b444bc65895..9796361c9eb 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -16,12 +16,13 @@ def create message: "Document successfully queued for upload." } begin + #check if the parameters to create a mailrequest are present. if params["recipient_info"].present? + #creating the key for distribution_ids to provide to IDT client within the success_json hash. success_json[:distribution_ids] = params["recipient_info"].map do |recipient| mail_req = MailRequest.new(recipient) if mail_req.invalid? success_json[:error_messages] = mail_req.errors.messages - # byebug end mail_req.call mail_req.vbms_distribution_id From 7f69ac45241c3c616076491c78036b4709b19377 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Fri, 2 Jun 2023 14:17:42 -0400 Subject: [PATCH 147/308] APPEALS-21118 updated create_distribution with recipient and destination hashes --- app/jobs/mail_request_job.rb | 81 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index c4735846fa2..77ba57a0a7a 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -3,9 +3,7 @@ class MailRequestJob < CaseflowJob queue_with_priority :low_priority application_attr :intake -# copies based on number of recipients -# But then how to get document reference id? -# is that even needed still? if not, pacman service needs to be changed + def perform(vbms_uploaded_document, mail_request) package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, mail_request.name, @@ -37,49 +35,52 @@ def create_package(vbms_uploaded_document, mail_request) ) end - def create_distribution(package_id, mail_request) - VbmsDistribution.new( - claimant_station_of_jurisdiction: mail_request.claimant_station_of_jurisdiction, - created_at: Time.zone.now, - created_by_id: "", - first_name: mail_request.first_name, - last_name: mail_request.last_name, - middle_name: mail_request.middle_name, - name: mail_request.name, - participant_id: mail_request.participant_id, - poa_code: mail_request.poa_code, - recipient_type: mail_request.recipient_type, - updated_at: Time.zone.now, - updated_by_id: "", - vbms_communication_package_id: package_id - ) - - end - - def create_distribution_destinations(dist_id, mail_request) - + def create_distribution_request(package_id, mail_request) + distributions = VbmsDistribution.find(participant_id: mail_request.participant_id) + distributions.each do |dist| + distribution_destination = VbmsDistributionDestination.find(vbms_distribution_id: dist.id) + distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, + get_recipient_hash(distribution), + get_destinations_hash(distribution_destination)) + log_info(distribution_response) + if distribution_response.code == 201 + dist.update!(vbms_communication_package_id: package_id) + else + log_error(error_msg(distribution.code)) + end + end end - def get_recipient_array(mail_request) - + def get_recipient_hash(distribution) + { + type: distribution.recipient_type, + name: distribution.name, + firstName: distribution.first_name, + middleName: distribution.middle_name, + lastName: distribution.last_name, + participant_id: distribution.participant_id, + poaCode: distribution.poa_code, + claimantStationOfJurisdiction: distribution.claimant_station_of_jurisdiction + } end - def get_destination_array(mail_request) + def get_destinations_hash(destination) + [{ + "type" => destination.destination_type, + "addressLine1" => destination.address_line_1, + "addressLine2" => destination.address_line_2, + "addressLine3" => destination.address_line_3, + "addressLine4" => destination.address_line_4, + "addressLine5" => destination.address_line_5, + "addressLine6" => destination.address_line_6, + "city" => destination.city, + "state" => destination.state, + "postalCode" => destination.postal_code, + "countryName" => destination.country_name, + "countryCode" => destination.country_code + }] end -# multiple recipients and destinations? -# how will those be packaged in mail_request? - def create_distribution_request(package_id, mail_request) - distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, dist[:recipient], Array(dist_dest)) - log_info(distribution_response) - if distribution_response.code == 201 - distribution = create_distribution(package_id, mail_request) - create_distribution_destinations - else - log_error(error_msg(distribution.code)) - end - distribution.uuid - end def log_error(error_msg) uuid = SecureRandom.uuid From 6654b1aca13f30238301fa4f2860c55cc8e3e955 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Fri, 2 Jun 2023 14:53:01 -0400 Subject: [PATCH 148/308] APPEALS-21118 added comments to methods --- app/jobs/mail_request_job.rb | 44 +++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 77ba57a0a7a..062a4417230 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -4,6 +4,11 @@ class MailRequestJob < CaseflowJob queue_with_priority :low_priority application_attr :intake + # Purpose: performs job + # + # takes in VbmsUploadedDocument object and MailRequest object + # + # Response: n/a def perform(vbms_uploaded_document, mail_request) package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, mail_request.name, @@ -20,6 +25,14 @@ def perform(vbms_uploaded_document, mail_request) log_error(error_msg(package_response.code)) end end + + private + + # Purpose: Creates new VbmsCommunicationPackage + # + # takes in VbmsUploadedDocument object and MailRequest object + # + # Response: new VbmsCommunicationPackage object # FIXME how to get created_by_id def create_package(vbms_uploaded_document, mail_request) VbmsCommunicationPackage.new( @@ -35,6 +48,11 @@ def create_package(vbms_uploaded_document, mail_request) ) end + # Purpose: sends distribution POST request to Pacman API + # + # takes in VbmsCommunicationPackage id (string) and MailRequest object + # + # Response: n/a def create_distribution_request(package_id, mail_request) distributions = VbmsDistribution.find(participant_id: mail_request.participant_id) distributions.each do |dist| @@ -51,6 +69,11 @@ def create_distribution_request(package_id, mail_request) end end + # Purpose: creates recipient hash from VbmsDistribution attributes + # + # takes in VbmsDistribution object + # + # Response: hash that is needed in Pacman API distribution POST requests def get_recipient_hash(distribution) { type: distribution.recipient_type, @@ -64,6 +87,11 @@ def get_recipient_hash(distribution) } end + # Purpose: creates destination hash from VbmsDistributionDestination attributes + # + # takes in VbmsDistributionDestination object + # + # Response: array that holds a hash def get_destinations_hash(destination) [{ "type" => destination.destination_type, @@ -79,15 +107,24 @@ def get_destinations_hash(destination) "countryName" => destination.country_name, "countryCode" => destination.country_code }] - end + # Purpose: logging error in Rails and in Raven + # + # takes in error message (string) + # + # Response: n/a def log_error(error_msg) uuid = SecureRandom.uuid Rails.logger.error(error_msg + "Error ID: " + uuid) Raven.capture_exception(error_msg, extra: { error_uuid: uuid }) end + # Purpose: gets an error message based on the error code + # + # takes in error code (int) + # + # Response: error message string def error_msg(code) if code == 400 "400 PacmanBadRequestError The server cannot create the new communication package due to a client error " @@ -99,6 +136,11 @@ def error_msg(code) end end + # Purpose: logs information in Rails logger + # + # takes in info message (string) + # + # Response: n/a def log_info(info_message) uuid = SecureRandom.uuid Rails.logger.info(info_message + "ID: " + uuid) From fdb97fbb29f82b58fb43fa870a338583296bcb2a Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 5 Jun 2023 11:19:03 -0400 Subject: [PATCH 149/308] added comments to new code for possible future dev support. --- .../api/v1/upload_vbms_document_controller.rb | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 9796361c9eb..93a7a0a8aa6 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,24 +12,33 @@ def bgs end def create + # creating a JSON object that will be used to communicate with the IDT user as to the status of the upload if it was + # successful and if the proper params were supplied, it will also hold the IDs for the created distributions. + # allowing the client to be able to search for the status. + # However, if there are any errors in regards to creation of the MailRequest, the errors will be returned + # to the Client and the originally intended upload will still follow through. success_json = { message: "Document successfully queued for upload." } begin - #check if the parameters to create a mailrequest are present. + # optional check if the parameters to create a mailrequest are present. if params["recipient_info"].present? - #creating the key for distribution_ids to provide to IDT client within the success_json hash. + # creating the key for distribution_ids to provide to IDT client within the success_json hash. success_json[:distribution_ids] = params["recipient_info"].map do |recipient| mail_req = MailRequest.new(recipient) + # Given that the mail request is invalid, errors will be taken track of and presented to the + # user within the success_JSON object. if mail_req.invalid? - success_json[:error_messages] = mail_req.errors.messages + success_json[:error_messages] = mail_req.errors.messages end mail_req.call mail_req.vbms_distribution_id end end rescue Caseflow::Error::MissingRecipientInfo => error - success_json[:errors] = "Incomplete mailing informaiton provided. No mail request was created." + # Raises Caseflow::Error::MissingRecipientInfo if provided params within the recipient_info + # array do not create a valid MailRequest. + success_json[:error] = "Incomplete mailing informaiton provided. No mail request was created." raise error ensure appeal = nil From 64defc960f204b9583cfe72126f5bd399392e396 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 5 Jun 2023 15:49:42 -0400 Subject: [PATCH 150/308] Refactored controller --- .../idt/api/v1/upload_vbms_document_controller.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 441f83c4997..0e562ed9ead 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -8,7 +8,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController before_action :verify_access def create - mail_request = create_mail_request + create_mail_request_distributions appeal = nil # Find veteran from appeal id and check with db @@ -44,10 +44,16 @@ def bgs @bgs ||= BGSService.new end - def create_mail_request + def mail_request return nil if recipient_info.blank? - MailRequest.new(recipient_info).call + @mail_request ||= MailRequest.new(params) + end + + def create_mail_request_distributions + return if recipient_info.blank? + + mail_requst.call end def find_veteran_by_appeal_id From 1399a14597b795cf6efc6f5f79ead66b86f48708 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 6 Jun 2023 10:32:31 -0400 Subject: [PATCH 151/308] Abstracted validations into a shared concern to make available to MailRequest object --- app/models/vbms_distribution.rb | 13 +--- app/models/vbms_distribution_destination.rb | 46 +------------ app/validators/mail_request_validator.rb | 74 +++++++++++++++++++++ 3 files changed, 78 insertions(+), 55 deletions(-) create mode 100644 app/validators/mail_request_validator.rb diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 4902b568eac..538171b52aa 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,17 +1,8 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord + include MailRequestValidator::Distribution + belongs_to :vbms_communication_package, optional: false has_many :vbms_distribution_destinations - - with_options presence: true do - validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } - validates :first_name, :last_name, if: -> { recipient_type == "person" } - validates :name, if: :not_a_person? - validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } - end - - def not_a_person? - %w[organization system ro-colocated].include?(recipient_type) - end end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index f6fc5c785ad..80bbd6b1730 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,49 +1,7 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - belongs_to :vbms_distribution, optional: false - - with_options presence: true do - validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } - validates :address_line_1, :city, :country_code, if: :physical_mail? - validates :address_line_2, if: :treat_line_2_as_addressee - validates :address_line_3, if: :treat_line_3_as_addressee - validates :state, :postal_code, if: :us_address? - validates :country_name, if: -> { destination_type == "internationalAddress" } - end - - validates :treat_line_2_as_addressee, - inclusion: { in: [true], message: "cannot be false if line 3 is treated as addressee" }, - if: -> { treat_line_3_as_addressee == true } - - validate :valid_country_code?, if: :physical_mail? - validate :valid_us_state_code?, if: :us_address? - - def physical_mail? - %w[domesticAddress internationalAddress militaryAddress].include?(destination_type) - end + include MailRequestValidator::DistributionDestination - def us_address? - %w[domesticAddress militaryAddress].include?(destination_type) - end - - def valid_country_code? - unless iso_country_codes.include?(country_code) - errors.add(:country_code, "is not a valid ISO 3166-2 code") - end - end - - def valid_us_state_code? - unless iso_us_state_codes.include?(state) - errors.add(:state, "is not a valid ISO 3166-2 code") - end - end - - def iso_country_codes - @iso_country_codes ||= ISO3166::Country.codes - end - - def iso_us_state_codes - @iso_us_state_codes ||= ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys - end + belongs_to :vbms_distribution, optional: false end diff --git a/app/validators/mail_request_validator.rb b/app/validators/mail_request_validator.rb new file mode 100644 index 00000000000..66cc146d4b9 --- /dev/null +++ b/app/validators/mail_request_validator.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module MailRequestValidator + module Distribution + extend ActiveSupport::Concern + + included do + with_options presence: true do + validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } + validates :first_name, :last_name, if: -> { recipient_type == "person" } + validates :name, if: :not_a_person? + validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } + end + end + + private + + def not_a_person? + %w[organization system ro-colocated].include?(recipient_type) + end + end + + module DistributionDestination + extend ActiveSupport::Concern + + included do + with_options presence: true do + validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } + validates :address_line_1, :city, :country_code, if: :physical_mail? + validates :address_line_2, if: :treat_line_2_as_addressee + validates :address_line_3, if: :treat_line_3_as_addressee + validates :state, :postal_code, if: :us_address? + validates :country_name, if: -> { destination_type == "internationalAddress" } + end + + validates :treat_line_2_as_addressee, + inclusion: { in: [true], message: "cannot be false if line 3 is treated as addressee" }, + if: -> { treat_line_3_as_addressee == true } + + validate :valid_country_code?, if: :physical_mail? + validate :valid_us_state_code?, if: :us_address? + end + + private + + def physical_mail? + %w[domesticAddress internationalAddress militaryAddress].include?(destination_type) + end + + def us_address? + %w[domesticAddress militaryAddress].include?(destination_type) + end + + def valid_country_code? + unless iso_country_codes.include?(country_code) + errors.add(:country_code, "is not a valid ISO 3166-2 code") + end + end + + def valid_us_state_code? + unless iso_us_state_codes.include?(state) + errors.add(:state, "is not a valid ISO 3166-2 code") + end + end + + def iso_country_codes + @iso_country_codes ||= ISO3166::Country.codes + end + + def iso_us_state_codes + @iso_us_state_codes ||= ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys + end + end +end From 96a1c13a611edaf90d62a9bae7cd375df3a75f52 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 6 Jun 2023 16:02:36 -0400 Subject: [PATCH 152/308] APPEALS-21123 controller testing completed. Changes made to mail_request factory. MailRequest spec is created. --- .../upload_vbms_document_controller_spec.rb | 51 +++++++++++++++++- spec/factories/mail_request.rb | 4 +- spec/workflows/mail_request_spec.rb | 53 +++++++++++++++++++ 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 spec/workflows/mail_request_spec.rb diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 9cce398be85..863212ff297 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -14,7 +14,9 @@ end let(:mail_request_params) do - { + { veteran_identifier: veteran.file_number, + file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + document_type: valid_document_type, recipient_info: [ { recipient_type: "person", @@ -34,6 +36,26 @@ } end + let(:invalid_mail_request_params) do + { veteran_identifier: veteran.file_number, + file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + document_type: valid_document_type, + recipient_info: [ + { + recipient_type: "person", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + } + ]} + end + let(:params_identifier) do { veteran_identifier: veteran.file_number, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", @@ -136,6 +158,23 @@ end end + context "when the recipient_info parameters are incomplete" do + it "queues the upload(given valid veteran info), returns a descriptive error to the IDT user" do + post :create, params: invalid_mail_request_params + success_message = JSON.parse(response.body)["message"] + validation_error_msgs = JSON.parse(response.body)["error_messages"] + error = JSON.parse(response.body)["error"] + + expect(success_message).to eq "Document successfully queued for upload." + expect(validation_error_msgs).to eq( + {"first_name" => ["can't be blank"], + "last_name" => ["can't be blank"]} + ) + expect(error).to eq("Incomplete mailing informaiton provided. No mail request was created.") + expect(response.status).to eq(200) + end + end + context "all parameters are valid" do let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 1) } let(:document_params) do @@ -156,6 +195,16 @@ post :create, params: mail_request_params end + it "returns a list of vbms_distribution ids alongside a success message" do + post :create, params: mail_request_params + success_message = JSON.parse(response.body)["message"] + success_id = JSON.parse(response.body)["distribution_ids"] + # expect(VbmsDistribution).to change(:count).by(1) + expect(success_message).to eq "Document successfully queued for upload." + expect(success_id).not_to eq([]) + expect(response.status).to eq(200) + end + it "returns a successful message and creates a new VbmsUploadedDocument" do expect { post :create, params: params }.to change(VbmsUploadedDocument, :count).by(1) diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index 9dff04014ff..e89512d06ec 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true FactoryBot.define do - factory :valid_mail_request do + factory :mail_request do recipient_type { "person" } first_name { "Bob" } last_name { "Smithcole" } - participant_id { 640_460_002 } + participant_id { "640460002" } destination_type { "domesticAddress" } address_line_1 { "1234 Main Street" } city { "Orlando" } diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb new file mode 100644 index 00000000000..e59edbf5e88 --- /dev/null +++ b/spec/workflows/mail_request_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +describe MailRequest do + let(:valid_request) { MailRequest.new(mail_request_params) } + let(:invalid_request) { MailRequest.new(invalid_mail_request_params) } + let(:mail_request_params) do + ActionController::Parameters.new({ + recipient_info: [ + { + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + } + ] + }) + end + let(:invalid_mail_request_params) do + ActionController::Parameters.new({ + recipient_info: [ + { + recipient_type: "", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + } + ] + }) + end + + describe "#call" do + context "when valid parameters are available" do + it "it checks if self is valid" do + + end + end + end +end From b97d50a532e3c670898d8b06d68851621a55e8dc Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 7 Jun 2023 09:51:44 -0400 Subject: [PATCH 153/308] Added comments --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 4 +++- app/validators/mail_request_validator.rb | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 0e562ed9ead..1f00865b953 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -8,6 +8,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController before_action :verify_access def create + # Create distributions for Package Manager mail service if recipient info present create_mail_request_distributions appeal = nil @@ -64,7 +65,8 @@ def find_veteran_by_appeal_id end def find_file_number_by_veteran_identifier - file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || bgs.fetch_file_number_by_ssn(veteran_identifier) + file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || + bgs.fetch_file_number_by_ssn(veteran_identifier) throw_not_found_error("veteran") if file_number.nil? update_veteran_file_number(file_number) end diff --git a/app/validators/mail_request_validator.rb b/app/validators/mail_request_validator.rb index 66cc146d4b9..987fb5e4c4e 100644 --- a/app/validators/mail_request_validator.rb +++ b/app/validators/mail_request_validator.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true module MailRequestValidator + # Validations for VbmsDistribution model and MailRequest object module Distribution extend ActiveSupport::Concern @@ -20,6 +21,7 @@ def not_a_person? end end + # Validations for VbmsDistributionDestination model and MailRequest object module DistributionDestination extend ActiveSupport::Concern From 668d18cb64b38145241fdc277428f8906dfb9996 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Wed, 7 Jun 2023 12:05:43 -0400 Subject: [PATCH 154/308] spec updates, comment change in controller. --- .../api/v1/upload_vbms_document_controller.rb | 4 +- spec/factories/mail_request.rb | 6 +- spec/workflows/mail_request_spec.rb | 87 ++++++++++--------- 3 files changed, 52 insertions(+), 45 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 93a7a0a8aa6..abbfff47c8c 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -12,7 +12,7 @@ def bgs end def create - # creating a JSON object that will be used to communicate with the IDT user as to the status of the upload if it was + # creating a JSON object that will be used to communicate with the IDT user as to the status of the upload. If it was # successful and if the proper params were supplied, it will also hold the IDs for the created distributions. # allowing the client to be able to search for the status. # However, if there are any errors in regards to creation of the MailRequest, the errors will be returned @@ -38,7 +38,7 @@ def create rescue Caseflow::Error::MissingRecipientInfo => error # Raises Caseflow::Error::MissingRecipientInfo if provided params within the recipient_info # array do not create a valid MailRequest. - success_json[:error] = "Incomplete mailing informaiton provided. No mail request was created." + success_json[:error] = "Incomplete mailing information provided. No mail request was created." raise error ensure appeal = nil diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index e89512d06ec..d5a09c679fd 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -5,7 +5,7 @@ recipient_type { "person" } first_name { "Bob" } last_name { "Smithcole" } - participant_id { "640460002" } + participant_id { "487470002" } destination_type { "domesticAddress" } address_line_1 { "1234 Main Street" } city { "Orlando" } @@ -19,11 +19,11 @@ factory :invalid_mail_request do recipient_type { "person" } first_name { "Bob" } - participant_id { 640_460_002 } + participant_id { "487470002" } address_line_1 { "1234 Main Street" } city { "Orlando" } country_code { "US"} - postal_code { 12_345 } + postal_code { "12345" } state { "FL" } treat_line_2_as_addressee { false } treat_line_3_as_addressee { false } diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb index e59edbf5e88..dae93f08a40 100644 --- a/spec/workflows/mail_request_spec.rb +++ b/spec/workflows/mail_request_spec.rb @@ -1,53 +1,60 @@ # frozen_string_literal: true -describe MailRequest do - let(:valid_request) { MailRequest.new(mail_request_params) } - let(:invalid_request) { MailRequest.new(invalid_mail_request_params) } +describe MailRequest, :postgres do let(:mail_request_params) do - ActionController::Parameters.new({ - recipient_info: [ - { - recipient_type: "person", - first_name: "Bob", - last_name: "Smithmetz", - participant_id: "487470002", - destination_type: "domesticAddress", - address_line_1: "1234 Main Street", - treat_line_2_as_addressee: false, - treat_line_3_as_addressee: false, - city: "Orlando", - state: "FL", - postal_code: "12345", - country_code: "US" - } - ] - }) + ActionController::Parameters.new( + { + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + }) end let(:invalid_mail_request_params) do - ActionController::Parameters.new({ - recipient_info: [ - { - recipient_type: "", - last_name: "Smithmetz", - participant_id: "487470002", - destination_type: "domesticAddress", - address_line_1: "1234 Main Street", - treat_line_2_as_addressee: false, - treat_line_3_as_addressee: false, - city: "Orlando", - state: "FL", - postal_code: "12345", - country_code: "US" - } - ] - }) + ActionController::Parameters.new( + { + recipient_type: "", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + }) end + let(:valid_request) { MailRequest.new(mail_request_params) } + let(:invalid_request) { MailRequest.new(invalid_mail_request_params) } describe "#call" do - context "when valid parameters are available" do - it "it checks if self is valid" do + context "when valid parameters are passed into the mail requests initialize method." do + subject { described_class.new(mail_request_params).call } + it "creates a vbms_distribution" do + expect{ subject }.to change(VbmsDistribution, :count).by(1) + end + it "creates a vbms_distribution_destination" do + expect{ subject }.to change(VbmsDistributionDestination, :count).by(1) end end + + context "when invalid parameters are passed into the mail requests initialize method." do + subject { described_class.new(invalid_mail_request_params).call } + it "raises an error" do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid) + end + end + end end From 90c3dfe170f15dd4d8dfee53d7d7be2b3ef6bd04 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 8 Jun 2023 10:59:09 -0400 Subject: [PATCH 155/308] method refactor --- app/workflows/mail_request.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index e2494937462..1f13d35f73d 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -72,8 +72,7 @@ def create_a_vbms_distribution_destination def recipient_type_valid? unless @recipient_type.blank? - valid_var = %w[organization person system ro-colocated].include?(@recipient_type) - valid_var + %w[organization person system ro-colocated].include?(@recipient_type) end end From 9c4c6119409a820840593cdcba76cbd80fa59924 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 8 Jun 2023 12:28:44 -0400 Subject: [PATCH 156/308] Updated controller to validate copies and pass to MailRequestJob --- .../api/v1/upload_vbms_document_controller.rb | 31 +++++++++++++------ app/jobs/upload_document_to_vbms_job.rb | 9 +++--- .../prepare_document_upload_to_vbms.rb | 8 +++-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 1f00865b953..d6122dadbc1 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -9,7 +9,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController def create # Create distributions for Package Manager mail service if recipient info present - create_mail_request_distributions + create_mail_requests appeal = nil # Find veteran from appeal id and check with db @@ -18,7 +18,7 @@ def create else find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_request).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call if result.success? render json: { message: "Document successfully queued for upload." } @@ -30,31 +30,44 @@ def create private def recipient_info - params["recipient_info"] + params[:recipient_info] + end + + def copies + return 1 if params[:copies].blank? + + params[:copies] end def appeal_id - params["appeal_id"] + params[:appeal_id] end def veteran_identifier - params["veteran_identifier"] + params[:veteran_identifier] end def bgs @bgs ||= BGSService.new end - def mail_request + def mail_requests return nil if recipient_info.blank? - @mail_request ||= MailRequest.new(params) + # @mail_requests ||= Logic from Jonathan's branch goes here end - def create_mail_request_distributions + def create_mail_requests return if recipient_info.blank? - mail_requst.call + throw_error_if_copies_out_of_range + # Logic from Jonathan's branch goes here + end + + def throw_error_if_copies_out_of_range + unless (1..500).cover?(copies) + fail StandardError, "Copies must be between 1 and 500 (inclusive)" + end end def find_veteran_by_appeal_id diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index e4d4573b626..cbd2d225b71 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -9,16 +9,17 @@ class UploadDocumentToVbmsJob < CaseflowJob # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten # mail_request - MailRequest object with address info to be sent to Package Manager (optional) + # copies - Number of copies of document to be included in mail distribution (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_request: nil, application: "idt") + def perform(document_id:, initiator_css_id:, mail_request: nil, copies: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: document_id) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_request) unless mail_request.nil? + queue_mail_request_job(mail_request, copies) unless mail_request.nil? end private @@ -41,10 +42,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_request) + def queue_mail_request_job(mail_request, copies) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_request) + MailRequestJob.perform_later(document, mail_request, copies) info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" log_info(info_message) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 992f5781212..f3ff9291738 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,12 +10,15 @@ class PrepareDocumentUploadToVbms # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) # mail_request - MailRequest object with address info to be sent to Package Manager (optional) - def initialize(params, user, appeal = nil, mail_request = nil) + # copies - Number of copies of document to be included in mail distribution (optional) + + def initialize(params, user, appeal = nil, mail_request = nil, copies = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal @mail_request = mail_request + @copies = copies end # Purpose: Queues a job to upload a document to vbms @@ -33,7 +36,8 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_request: @mail_request + mail_request: @mail_request, + copies: @copies ) end end From af6ceb92db22f18975b8d64ece2ff172dc2ba679 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 8 Jun 2023 12:31:21 -0400 Subject: [PATCH 157/308] validation methods updated --- app/workflows/mail_request.rb | 49 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 1f13d35f73d..b89dc2be45b 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -71,60 +71,49 @@ def create_a_vbms_distribution_destination end def recipient_type_valid? - unless @recipient_type.blank? - %w[organization person system ro-colocated].include?(@recipient_type) - end + return true if %w[organization person system ro-colocated].include?(@recipient_type) + false end def person? - unless @recipient_type.blank? - @recipient_type == "person" - end + return true if @recipient_type == "person" unless @recipient_type.blank? + false end def ro_colocated? - unless @recipient_type.blank? - @recipient_type == "ro-colocated" - end + return true if @recipient_type == "ro-colocated" unless @recipient_type.blank? + false end def destination_type_valid? - unless @destination_type.blank? - %w[domesticAddress internationalAddress militaryAddress derived email sms].include?( - @destination_type - ) - end + return true if %w[domesticAddress internationalAddress militaryAddress derived email sms].include?(@destination_type) unless @destination_type.blank? + false end def physical_mail? - unless @destination_type.blank? - %w[domesticAddress internationalAddress militaryAddress].include?(@destination_type) - - end + return true if %w[domesticAddress internationalAddress militaryAddress].include?(@destination_type) unless @destination_type.blank? + false end def line_2_addressee? - unless @treat_line_2_as_addressee.blank? - @treat_line_2_as_addressee == true - end + return true if @treat_line_2_as_addressee == true + false end def line_3_addressee? - unless @treat_line_3_as_addressee.blank? - @treat_line_3_as_addressee == true - end + return true if @treat_line_3_as_addressee == true + false end def country_name_required? - unless @destination_type.blank? - @destination_type == "internationalAddress" - end + return true if @destination_type == "internationalAddress" + false end def us_address? - unless @destination_type.blank? - %w[domesticAddress militaryAddress].include?(@destination_type) - end + return true if %w[domesticAddress militaryAddress].include?(@destination_type) + false + end def destination_params_parse From aa4891ec184fcb300ba0013bb812fb79f6cf0fb8 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Thu, 8 Jun 2023 15:18:25 -0400 Subject: [PATCH 158/308] spec changes, All Green, appropriate codecoverage. edit to one of the validations in mail_request file.Update the factory for mail_request as well --- app/workflows/mail_request.rb | 9 ++--- .../upload_vbms_document_controller_spec.rb | 10 +++--- spec/factories/mail_request.rb | 22 +++++------- spec/workflows/mail_request_spec.rb | 34 +++++++++++++------ 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index b89dc2be45b..0c3c94d0d09 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -11,7 +11,7 @@ class MailRequest :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id with_options presence: true do - validates :recipient_type, if: :recipient_type_valid? + validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } validates :first_name, :last_name, if: :person? validates :poa_code, :claimant_station_of_jurisdiction, if: :ro_colocated? validates :destination_type, if: :destination_type_valid? @@ -55,7 +55,7 @@ def call distribution = create_a_vbms_distribution @vbms_distribution_id = distribution.id create_a_vbms_distribution_destination - elsif invalid? + else raise Caseflow::Error::MissingRecipientInfo end end @@ -70,11 +70,6 @@ def create_a_vbms_distribution_destination VbmsDistributionDestination.create!(destination_params_parse) end - def recipient_type_valid? - return true if %w[organization person system ro-colocated].include?(@recipient_type) - false - end - def person? return true if @recipient_type == "person" unless @recipient_type.blank? false diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 863212ff297..04d63b4a0cc 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -160,17 +160,19 @@ context "when the recipient_info parameters are incomplete" do it "queues the upload(given valid veteran info), returns a descriptive error to the IDT user" do + expect(Raven).to receive(:capture_exception) post :create, params: invalid_mail_request_params success_message = JSON.parse(response.body)["message"] validation_error_msgs = JSON.parse(response.body)["error_messages"] error = JSON.parse(response.body)["error"] - expect(success_message).to eq "Document successfully queued for upload." expect(validation_error_msgs).to eq( - {"first_name" => ["can't be blank"], - "last_name" => ["can't be blank"]} + { + "first_name" => ["can't be blank"], + "last_name" => ["can't be blank"] + } ) - expect(error).to eq("Incomplete mailing informaiton provided. No mail request was created.") + expect(error).to eq("Incomplete mailing information provided. No mail request was created.") expect(response.status).to eq(200) end end diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index d5a09c679fd..9d84ced8809 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -2,7 +2,6 @@ FactoryBot.define do factory :mail_request do - recipient_type { "person" } first_name { "Bob" } last_name { "Smithcole" } participant_id { "487470002" } @@ -14,18 +13,15 @@ state { "FL" } treat_line_2_as_addressee { false } treat_line_3_as_addressee { false } - end - factory :invalid_mail_request do - recipient_type { "person" } - first_name { "Bob" } - participant_id { "487470002" } - address_line_1 { "1234 Main Street" } - city { "Orlando" } - country_code { "US"} - postal_code { "12345" } - state { "FL" } - treat_line_2_as_addressee { false } - treat_line_3_as_addressee { false } + trait :person_recipient_type do + recipient_type { "person" } + end + + trait :nil_recipient_type do + recipient_type { nil } + end + + initialize_with { new(attributes) } end end diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb index dae93f08a40..58ea8697977 100644 --- a/spec/workflows/mail_request_spec.rb +++ b/spec/workflows/mail_request_spec.rb @@ -3,8 +3,7 @@ describe MailRequest, :postgres do let(:mail_request_params) do ActionController::Parameters.new( - { - recipient_type: "person", + { recipient_type: "person", first_name: "Bob", last_name: "Smithmetz", participant_id: "487470002", @@ -16,12 +15,13 @@ state: "FL", postal_code: "12345", country_code: "US" - }) + } + ) end + let(:invalid_mail_request_params) do ActionController::Parameters.new( - { - recipient_type: "", + { recipient_type: nil, last_name: "Smithmetz", participant_id: "487470002", destination_type: "domesticAddress", @@ -30,12 +30,25 @@ treat_line_3_as_addressee: false, city: "Orlando", state: "FL", - postal_code: "12345", + postal_code: nil, country_code: "US" - }) + } + ) + end + + shared_examples "mail request has valid attributes" do + let(:mail_request_spec_object) { build(:mail_request, :person_recipient_type) } + it "is valid with valid attributes" do + expect(mail_request_spec_object).to be_valid + end end - let(:valid_request) { MailRequest.new(mail_request_params) } - let(:invalid_request) { MailRequest.new(invalid_mail_request_params) } + + let(:mail_request_spec_object_1) { build(:mail_request, :nil_recipient_type) } + include_examples "mail request has valid attributes" + it "is not valid without a recipient type" do + expect(mail_request_spec_object_1).to_not be_valid + # expect(mail_request_spec_object.errors[:recipient_type]).to eq(["can't be blank", "is not included in the list"]) + end describe "#call" do context "when valid parameters are passed into the mail requests initialize method." do @@ -52,9 +65,8 @@ context "when invalid parameters are passed into the mail requests initialize method." do subject { described_class.new(invalid_mail_request_params).call } it "raises an error" do - expect { subject }.to raise_error(ActiveRecord::RecordInvalid) + expect { subject }.to raise_error(Caseflow::Error::MissingRecipientInfo) end end - end end From 5dab94ac2c1f338a03d5731be084b8441d6729a3 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 8 Jun 2023 15:27:36 -0400 Subject: [PATCH 159/308] Changed name of method --- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index d6122dadbc1..8c5fd5df4ab 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -9,7 +9,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController def create # Create distributions for Package Manager mail service if recipient info present - create_mail_requests + create_mail_distributions appeal = nil # Find veteran from appeal id and check with db @@ -57,7 +57,7 @@ def mail_requests # @mail_requests ||= Logic from Jonathan's branch goes here end - def create_mail_requests + def create_mail_distributions return if recipient_info.blank? throw_error_if_copies_out_of_range From 3bfc9a4edf41059c1025ec6452c68fbbc6113ef4 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Fri, 9 Jun 2023 09:15:39 -0400 Subject: [PATCH 160/308] Use concern --- app/workflows/mail_request.rb | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 0c3c94d0d09..e95705492a1 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -4,25 +4,15 @@ class MailRequest include ActiveModel::Model include ActiveModel::Validations + include MailRequestValidator::Distribution + include MailRequestValidator::DistributionDestination + attr_accessor :recipient_type, :name, :first_name, :middle_name, :last_name, :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id - with_options presence: true do - validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } - validates :first_name, :last_name, if: :person? - validates :poa_code, :claimant_station_of_jurisdiction, if: :ro_colocated? - validates :destination_type, if: :destination_type_valid? - validates :address_line_1, :city, :country_code, if: :physical_mail? - validates :address_line_2, if: :line_2_addressee? - validates :address_line_3, if: :line_3_addressee? - validates :state, :postal_code, if: :us_address? - validates :country_name, if: :country_name_required? - end - validate :name, unless: :person? - def initialize(recipient_and_destination_hash) @recipient_type = recipient_and_destination_hash[:recipient_type] @name = recipient_and_destination_hash[:name] From 232dd2b1bbd29d4e242d3020dea7f3c95133eabe Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 12:29:15 -0400 Subject: [PATCH 161/308] Merged APPEALS-21121 and APPEALS-21123 in UploadVbmsDocumentController --- app/controllers/idt/api/v1/base_controller.rb | 5 +- .../api/v1/upload_vbms_document_controller.rb | 84 ++++++++++++------- app/jobs/upload_document_to_vbms_job.rb | 8 +- .../prepare_document_upload_to_vbms.rb | 8 +- lib/caseflow/error.rb | 1 + 5 files changed, 63 insertions(+), 43 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 1dc00e6c73e..00b16f33928 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -43,9 +43,8 @@ class Idt::Api::V1::BaseController < ApplicationController rescue_from Caseflow::Error::MissingRecipientInfo do |error| log_error(error) uuid = SecureRandom.uuid - Rails.logger.error("IDT Standard Error ID: " + - uuid + - " Not enough address/recipient information for a successful mail request.") + render(json: { message: "IDT Exception ID:" + uuid + " Recipient information received was invalid or incomplete.", + errors: error.message }, status: :bad_request) end rescue_from Caseflow::Error::VeteranNotFound do |error| diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index f760395387a..575cad1d43a 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -9,28 +9,28 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController def create # Create distributions for Package Manager mail service if recipient info present - begin - create_mail_distributions - rescue Caseflow::Error::MissingRecipientInfo => error - # Raises Caseflow::Error::MissingRecipientInfo if provided params within the recipient_info - # array do not create a valid MailRequest. - success_json[:error] = "Incomplete mailing information provided. No mail request was created." - raise error - ensure - appeal = nil - # Find veteran from appeal id and check with db - if appeal_id.present? - appeal = find_veteran_by_appeal_id - else - find_file_number_by_veteran_identifier - end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call + create_mail_distributions + + appeal = nil + # Find veteran from appeal id and check with db + if appeal_id.present? + appeal = find_veteran_by_appeal_id + else + find_file_number_by_veteran_identifier + end - if result.success? - render json: { message: "Document successfully queued for upload." } - else - render json: result.errors[0], status: :bad_request - end + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call + + success_message = { message: "Document successfully queued for upload." } + + if recipient_info.present? + success_message[:distribution_ids] = distribution_ids + end + + if result.success? + render json: success_message + else + render json: result.errors[0], status: :bad_request end end @@ -41,6 +41,7 @@ def recipient_info end def copies + # Default value of 1 for copies return 1 if params[:copies].blank? params[:copies] @@ -61,24 +62,38 @@ def bgs def mail_requests return nil if recipient_info.blank? - # @mail_requests ||= Logic from Jonathan's branch goes here - recipient_info.map do |recipient| - mail_req = MailRequest.new(recipient) + request_errors = [] + + @mail_requests ||= recipient_info.map.with_index do |recipient, idx| + mail_request = MailRequest.new(recipient) # Given that the mail request is invalid, errors will be taken track of and presented to the # user within the success_JSON object. - if mail_req.invalid? - success_json[:error_messages] = mail_req.errors.messages + if mail_request.invalid? + request_errors << "Recipient #{idx + 1}: " + mail_request.errors.full_messages.join(", ") end - mail_req.call + mail_request end + + if request_errors.any? + fail Caseflow::Error::MissingRecipientInfo, request_errors.flatten.join(", ") + end + + @mail_requests end def create_mail_distributions return if recipient_info.blank? throw_error_if_copies_out_of_range - # Logic from Jonathan's branch goes here + mail_requests.map do |request| + request.call + distribution_ids << request.vbms_distribution_id + end + end + + def distribution_ids + @distribution_ids ||= [] end def throw_error_if_copies_out_of_range @@ -89,7 +104,7 @@ def throw_error_if_copies_out_of_range def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) - throw_not_found_error("appeal") if appeal.nil? + throw_appeal_not_found_error if appeal.nil? update_veteran_file_number(appeal.veteran_file_number) appeal end @@ -97,7 +112,7 @@ def find_veteran_by_appeal_id def find_file_number_by_veteran_identifier file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || bgs.fetch_file_number_by_ssn(veteran_identifier) - throw_not_found_error("veteran") if file_number.nil? + throw_veteran_not_found_error if file_number.nil? update_veteran_file_number(file_number) end @@ -105,8 +120,13 @@ def update_veteran_file_number(file_number) params["veteran_file_number"] = file_number end - def throw_not_found_error(name) + def throw_appeal_not_found_error + uuid = SecureRandom.uuid + fail Caseflow::Error::AppealNotFound, uuid + " The appeal was unable to be found." + end + + def throw_veteran_not_found_error uuid = SecureRandom.uuid - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + uuid + " The #{name} was unable to be found." + fail Caseflow::Error::VeteranNotFound, uuid + " The veteran was unable to be found." end end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index cbd2d225b71..352dd025749 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -12,14 +12,14 @@ class UploadDocumentToVbmsJob < CaseflowJob # copies - Number of copies of document to be included in mail distribution (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_request: nil, copies: nil, application: "idt") + def perform(document_id:, initiator_css_id:, mail_requests: nil, copies: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: document_id) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_request, copies) unless mail_request.nil? + queue_mail_request_job(mail_requests, copies) unless mail_requests.nil? end private @@ -42,10 +42,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_request, copies) + def queue_mail_request_job(mail_requests, copies) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_request, copies) + MailRequestJob.perform_later(document, mail_requests, copies) info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" log_info(info_message) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index f3ff9291738..3d8bbea556a 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -12,12 +12,12 @@ class PrepareDocumentUploadToVbms # mail_request - MailRequest object with address info to be sent to Package Manager (optional) # copies - Number of copies of document to be included in mail distribution (optional) - def initialize(params, user, appeal = nil, mail_request = nil, copies = nil) + def initialize(params, user, appeal = nil, mail_requests = nil, copies = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal - @mail_request = mail_request + @mail_requests = mail_requests @copies = copies end @@ -36,8 +36,8 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_request: @mail_request, - copies: @copies + # mail_requests: @mail_requests, + # copies: @copies ) end end diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index e7601fc7ca3..f37911d4214 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -340,6 +340,7 @@ class MustImplementInSubclass < StandardError; end class AttributeNotLoaded < StandardError; end class VeteranNotFound < StandardError; end class AppealNotFound < StandardError; end + class MissingRecipientInfo < StandardError; end class EstablishClaimFailedInVBMS < StandardError attr_reader :error_code From 0441a78f458c63bf1f416b0f96723cd2a9c58105 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 12:47:57 -0400 Subject: [PATCH 162/308] Uncommented out arguments --- app/workflows/prepare_document_upload_to_vbms.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 3d8bbea556a..776da6ad901 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -36,8 +36,8 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - # mail_requests: @mail_requests, - # copies: @copies + mail_requests: @mail_requests, + copies: @copies ) end end From 10a6f68ce8747255f1282c5a6fbf8b9549b6dbcb Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 15:11:26 -0400 Subject: [PATCH 163/308] Refactored code in controller and fixed formatting of error messages --- app/controllers/idt/api/v1/base_controller.rb | 2 +- .../api/v1/upload_vbms_document_controller.rb | 62 +++++++++---------- app/workflows/mail_request.rb | 41 ------------ .../prepare_document_upload_to_vbms.rb | 2 +- 4 files changed, 33 insertions(+), 74 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 00b16f33928..8f59beae93f 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -44,7 +44,7 @@ class Idt::Api::V1::BaseController < ApplicationController log_error(error) uuid = SecureRandom.uuid render(json: { message: "IDT Exception ID:" + uuid + " Recipient information received was invalid or incomplete.", - errors: error.message }, status: :bad_request) + errors: JSON.parse(error.message) }, status: :bad_request) end rescue_from Caseflow::Error::VeteranNotFound do |error| diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 575cad1d43a..3fd405ab3ea 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -59,52 +59,57 @@ def bgs @bgs ||= BGSService.new end + def create_mail_distributions + return if recipient_info.blank? + + throw_error_if_copies_out_of_range + mail_requests.map do |request| + throw_error_if_recipient_info_invalid + request.call + distribution_ids << request.vbms_distribution_id + end + end + def mail_requests return nil if recipient_info.blank? - request_errors = [] + @mail_requests ||= create_mail_requests_and_track_errors + end - @mail_requests ||= recipient_info.map.with_index do |recipient, idx| + def create_mail_requests_and_track_errors + recipient_info.map.with_index do |recipient, idx| mail_request = MailRequest.new(recipient) - # Given that the mail request is invalid, errors will be taken track of and presented to the - # user within the success_JSON object. if mail_request.invalid? - request_errors << "Recipient #{idx + 1}: " + mail_request.errors.full_messages.join(", ") + recipient_errors["distribution #{idx + 1}"] = mail_request.errors.full_messages.join(", ") end mail_request end + end - if request_errors.any? - fail Caseflow::Error::MissingRecipientInfo, request_errors.flatten.join(", ") + def throw_error_if_copies_out_of_range + unless (1..500).cover?(copies) + fail Caseflow::Error::MissingRecipientInfo, "Copies must be between 1 and 500 (inclusive)".to_json end - - @mail_requests end - def create_mail_distributions - return if recipient_info.blank? + def throw_error_if_recipient_info_invalid + return unless recipient_errors.any? - throw_error_if_copies_out_of_range - mail_requests.map do |request| - request.call - distribution_ids << request.vbms_distribution_id - end + fail Caseflow::Error::MissingRecipientInfo, recipient_errors.to_json end - def distribution_ids - @distribution_ids ||= [] + def recipient_errors + @recipient_errors ||= {} end - def throw_error_if_copies_out_of_range - unless (1..500).cover?(copies) - fail StandardError, "Copies must be between 1 and 500 (inclusive)" - end + def distribution_ids + @distribution_ids ||= [] end def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) - throw_appeal_not_found_error if appeal.nil? + throw_not_found_error(Caseflow::Error::AppealNotFound, "appeal") if appeal.nil? update_veteran_file_number(appeal.veteran_file_number) appeal end @@ -112,7 +117,7 @@ def find_veteran_by_appeal_id def find_file_number_by_veteran_identifier file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || bgs.fetch_file_number_by_ssn(veteran_identifier) - throw_veteran_not_found_error if file_number.nil? + throw_not_found_error(Caseflow::Error::VeteranNotFound, "veteran") if file_number.nil? update_veteran_file_number(file_number) end @@ -120,13 +125,8 @@ def update_veteran_file_number(file_number) params["veteran_file_number"] = file_number end - def throw_appeal_not_found_error - uuid = SecureRandom.uuid - fail Caseflow::Error::AppealNotFound, uuid + " The appeal was unable to be found." - end - - def throw_veteran_not_found_error + def throw_not_found_error(error, name) uuid = SecureRandom.uuid - fail Caseflow::Error::VeteranNotFound, uuid + " The veteran was unable to be found." + fail error, uuid + " The #{name} was unable to be found." end end diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index e95705492a1..ef4cfe1c92c 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -60,47 +60,6 @@ def create_a_vbms_distribution_destination VbmsDistributionDestination.create!(destination_params_parse) end - def person? - return true if @recipient_type == "person" unless @recipient_type.blank? - false - end - - def ro_colocated? - return true if @recipient_type == "ro-colocated" unless @recipient_type.blank? - false - end - - def destination_type_valid? - return true if %w[domesticAddress internationalAddress militaryAddress derived email sms].include?(@destination_type) unless @destination_type.blank? - false - end - - def physical_mail? - return true if %w[domesticAddress internationalAddress militaryAddress].include?(@destination_type) unless @destination_type.blank? - false - end - - def line_2_addressee? - return true if @treat_line_2_as_addressee == true - false - end - - def line_3_addressee? - return true if @treat_line_3_as_addressee == true - false - end - - def country_name_required? - return true if @destination_type == "internationalAddress" - false - end - - def us_address? - return true if %w[domesticAddress militaryAddress].include?(@destination_type) - false - - end - def destination_params_parse { destination_type: @destination_type, diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 776da6ad901..96642fc984a 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -36,7 +36,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_requests: @mail_requests, + mail_requests: @mail_requests.to_json, copies: @copies ) end From 5d06d7eb36463c0e77c488359b90b1812b8ec212 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 15:19:40 -0400 Subject: [PATCH 164/308] Fixed issue of global variable in mail request validator --- .../idt/api/v1/upload_vbms_document_controller.rb | 13 ++++++------- app/validators/mail_request_validator.rb | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 3fd405ab3ea..b2c5d6ae99c 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -19,15 +19,14 @@ def create find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call - - success_message = { message: "Document successfully queued for upload." } - - if recipient_info.present? - success_message[:distribution_ids] = distribution_ids - end + byebug + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call if result.success? + success_message = { message: "Document successfully queued for upload." } + if recipient_info.present? + success_message[:distribution_ids] = distribution_ids + end render json: success_message else render json: result.errors[0], status: :bad_request diff --git a/app/validators/mail_request_validator.rb b/app/validators/mail_request_validator.rb index 987fb5e4c4e..3f3acbcc273 100644 --- a/app/validators/mail_request_validator.rb +++ b/app/validators/mail_request_validator.rb @@ -66,11 +66,11 @@ def valid_us_state_code? end def iso_country_codes - @iso_country_codes ||= ISO3166::Country.codes + ISO3166::Country.codes end def iso_us_state_codes - @iso_us_state_codes ||= ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys + ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys end end end From 4b09e89989572bc4b5409bd5508c695b8f1355d6 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 15:44:40 -0400 Subject: [PATCH 165/308] Fixed so it only checks for recipient errors after mapping through all recipients instead of erroring out at first invalid request --- .../idt/api/v1/upload_vbms_document_controller.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index b2c5d6ae99c..be57081a3b1 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -19,8 +19,6 @@ def create find_file_number_by_veteran_identifier end - byebug - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call if result.success? success_message = { message: "Document successfully queued for upload." } @@ -63,7 +61,6 @@ def create_mail_distributions throw_error_if_copies_out_of_range mail_requests.map do |request| - throw_error_if_recipient_info_invalid request.call distribution_ids << request.vbms_distribution_id end @@ -76,7 +73,7 @@ def mail_requests end def create_mail_requests_and_track_errors - recipient_info.map.with_index do |recipient, idx| + requests = recipient_info.map.with_index do |recipient, idx| mail_request = MailRequest.new(recipient) if mail_request.invalid? recipient_errors["distribution #{idx + 1}"] = mail_request.errors.full_messages.join(", ") @@ -84,6 +81,8 @@ def create_mail_requests_and_track_errors mail_request end + throw_error_if_recipient_info_invalid + requests end def throw_error_if_copies_out_of_range From 0f4c70e4e6fe121877c2748df9b06b5e15a1c401 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 9 Jun 2023 15:48:37 -0400 Subject: [PATCH 166/308] Implemented tap method to consolidate code --- .../idt/api/v1/upload_vbms_document_controller.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index be57081a3b1..961dcdbff4e 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -74,12 +74,11 @@ def mail_requests def create_mail_requests_and_track_errors requests = recipient_info.map.with_index do |recipient, idx| - mail_request = MailRequest.new(recipient) - if mail_request.invalid? - recipient_errors["distribution #{idx + 1}"] = mail_request.errors.full_messages.join(", ") + MailRequest.new(recipient).tap do |request| + if request.invalid? + recipient_errors["distribution #{idx + 1}"] = request.errors.full_messages.join(", ") + end end - - mail_request end throw_error_if_recipient_info_invalid requests From 0bd562db04d7351721a635517f10abd8ae2e64fa Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 10:26:53 -0400 Subject: [PATCH 167/308] Consolidated mail_requests and copies params into one payload to pass through workflow --- .../idt/api/v1/upload_vbms_document_controller.rb | 8 ++++++-- app/jobs/upload_document_to_vbms_job.rb | 11 ++++++----- app/workflows/prepare_document_upload_to_vbms.rb | 9 ++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 961dcdbff4e..20edd5ba35a 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -19,7 +19,7 @@ def create find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests, copies).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests_payload).call if result.success? success_message = { message: "Document successfully queued for upload." } if recipient_info.present? @@ -67,9 +67,13 @@ def create_mail_distributions end def mail_requests + @mail_requests ||= create_mail_requests_and_track_errors + end + + def mail_requests_payload return nil if recipient_info.blank? - @mail_requests ||= create_mail_requests_and_track_errors + { distributions: mail_requests.to_json, copies: copies } end def create_mail_requests_and_track_errors diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 352dd025749..ef5d2bc86f7 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,18 +8,19 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten - # mail_request - MailRequest object with address info to be sent to Package Manager (optional) + # mail_requests - Payload with copies value (integer) and distributions value (array of JSON-formatted + # MailRequest objects) to be submitted to Package Manager if optional recipient info is present # copies - Number of copies of document to be included in mail distribution (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_requests: nil, copies: nil, application: "idt") + def perform(document_id:, initiator_css_id:, mail_requests: nil, application: "idt") RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: document_id) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_requests, copies) unless mail_requests.nil? + queue_mail_request_job(mail_requests) unless mail_requests.nil? end private @@ -42,10 +43,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_requests, copies) + def queue_mail_request_job(mail_requests) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_requests, copies) + MailRequestJob.perform_later(document, mail_requests) info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" log_info(info_message) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 96642fc984a..70db2266ae5 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,16 +9,16 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # mail_request - MailRequest object with address info to be sent to Package Manager (optional) + # mail_requests - Payload with copies value (integer) and distributions value (array of JSON-formatted + # MailRequest objects) to be submitted to Package Manager if optional recipient info is present # copies - Number of copies of document to be included in mail distribution (optional) - def initialize(params, user, appeal = nil, mail_requests = nil, copies = nil) + def initialize(params, user, appeal = nil, mail_requests = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @document_type = @params[:document_type] @user = user @appeal = appeal @mail_requests = mail_requests - @copies = copies end # Purpose: Queues a job to upload a document to vbms @@ -36,8 +36,7 @@ def call document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], - mail_requests: @mail_requests.to_json, - copies: @copies + mail_requests: @mail_requests ) end end From 4334a4586d906595b93c714feaf637c884e9fd33 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 10:48:40 -0400 Subject: [PATCH 168/308] Condensed number of arguments for upload job into a parameter object --- app/workflows/prepare_document_upload_to_vbms.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 70db2266ae5..f3b8e5dd2f2 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -32,12 +32,13 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - UploadDocumentToVbmsJob.perform_later( + upload_job_payload = { document_id: document.id, initiator_css_id: user.css_id, application: @params[:application], mail_requests: @mail_requests - ) + } + UploadDocumentToVbmsJob.perform_later(upload_job_payload) end end From 3d5d540f1f75c78b291eeac291c73c6d9f2880e4 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 10:54:04 -0400 Subject: [PATCH 169/308] Fixed line too long in distribution destination spec --- spec/models/vbms_distribution_destination_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index f89aed1940a..e23f2f1c18f 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -66,7 +66,8 @@ destination.treat_line_3_as_addressee = true destination.treat_line_2_as_addressee = false expect(destination).to_not be_valid - expect(destination.errors[:treat_line_2_as_addressee]).to eq(["cannot be false if line 3 is treated as addressee"]) + expect(destination.errors[:treat_line_2_as_addressee]) + .to eq(["cannot be false if line 3 is treated as addressee"]) end it "is not valid without a city" do From 7d0c5011773899326fcb60625dfa65e41cdc65ca Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 12:22:50 -0400 Subject: [PATCH 170/308] Removing instance variables to comply with reek --- .../api/v1/upload_vbms_document_controller.rb | 39 ++++++++++--------- app/jobs/upload_document_to_vbms_job.rb | 32 ++++++++++++--- .../prepare_document_upload_to_vbms.rb | 37 +++++++++++------- 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 20edd5ba35a..38df1d2ed8f 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -8,8 +8,8 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController before_action :verify_access def create - # Create distributions for Package Manager mail service if recipient info present - create_mail_distributions + # Validate copies and create distributions for Package Manager mail service if recipient info present + build_communication_package appeal = nil # Find veteran from appeal id and check with db @@ -19,7 +19,7 @@ def create find_file_number_by_veteran_identifier end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_requests_payload).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, communication_package).call if result.success? success_message = { message: "Document successfully queued for upload." } if recipient_info.present? @@ -44,19 +44,14 @@ def copies params[:copies] end - def appeal_id - params[:appeal_id] - end - - def veteran_identifier - params[:veteran_identifier] - end + # Payload with distributions value (array of JSON-formatted MailRequest objects) and copies (integer) + def communication_package + return nil if recipient_info.blank? - def bgs - @bgs ||= BGSService.new + { distributions: mail_requests, copies: copies } end - def create_mail_distributions + def build_communication_package return if recipient_info.blank? throw_error_if_copies_out_of_range @@ -70,12 +65,6 @@ def mail_requests @mail_requests ||= create_mail_requests_and_track_errors end - def mail_requests_payload - return nil if recipient_info.blank? - - { distributions: mail_requests.to_json, copies: copies } - end - def create_mail_requests_and_track_errors requests = recipient_info.map.with_index do |recipient, idx| MailRequest.new(recipient).tap do |request| @@ -108,6 +97,18 @@ def distribution_ids @distribution_ids ||= [] end + def appeal_id + params[:appeal_id] + end + + def veteran_identifier + params[:veteran_identifier] + end + + def bgs + @bgs ||= BGSService.new + end + def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) throw_not_found_error(Caseflow::Error::AppealNotFound, "appeal") if appeal.nil? diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index ef5d2bc86f7..ebdea0249ea 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,25 +8,45 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten - # mail_requests - Payload with copies value (integer) and distributions value (array of JSON-formatted + # communication_package - Payload with copies value (integer) and distributions value (array of JSON-formatted # MailRequest objects) to be submitted to Package Manager if optional recipient info is present - # copies - Number of copies of document to be included in mail distribution (optional) # # Return: nil - def perform(document_id:, initiator_css_id:, mail_requests: nil, application: "idt") + def perform(params) + @params = params RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: document_id) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(mail_requests) unless mail_requests.nil? + queue_mail_request_job(communication_package) unless communication_package.nil? end private attr_reader :document, :initiator + def application + return "idt" if @params[:application].blank? + + @params[:application] + end + + def document_id + @params[:document_id] + end + + def initiator_css_id + @params[:initiator_css_id] + end + + def communication_package + return nil if @params[:communication_package].blank? + + @params[:communication_package] + end + def add_context_to_sentry if initiator.present? Raven.user_context( @@ -43,10 +63,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(mail_requests) + def queue_mail_request_job(communication_package) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, mail_requests) + MailRequestJob.perform_later(document, communication_package) info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" log_info(info_message) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index f3b8e5dd2f2..872f1bb6bd2 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,16 +9,14 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # mail_requests - Payload with copies value (integer) and distributions value (array of JSON-formatted + # communication_package - Payload with copies value (integer) and distributions value (array of # MailRequest objects) to be submitted to Package Manager if optional recipient info is present - # copies - Number of copies of document to be included in mail distribution (optional) - def initialize(params, user, appeal = nil, mail_requests = nil) + def initialize(params, user, appeal = nil, communication_package = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) - @document_type = @params[:document_type] + @params[:communication_package] = communication_package unless communication_package.nil? @user = user @appeal = appeal - @mail_requests = mail_requests end # Purpose: Queues a job to upload a document to vbms @@ -32,13 +30,7 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - upload_job_payload = { - document_id: document.id, - initiator_css_id: user.css_id, - application: @params[:application], - mail_requests: @mail_requests - } - UploadDocumentToVbmsJob.perform_later(upload_job_payload) + UploadDocumentToVbmsJob.perform_later(upload_document_job_params(document)) end end @@ -48,7 +40,7 @@ def call private attr_accessor :success - attr_reader :document_type, :params, :user + attr_reader :params, :user def veteran_file_number @params[:veteran_file_number] @@ -66,6 +58,10 @@ def file @params[:file] end + def document_type + @params[:document_type] + end + def valid_document_type errors.add(:document_type, "is not recognized") unless Document.type_id(document_type) end @@ -90,6 +86,21 @@ def document_params } end + def communication_package + return nil if params[:communication_package].blank? + + params[:communication_package] + end + + def upload_document_job_params(document) + { + document_id: document.id, + initiator_css_id: @user.css_id, + application: @params[:application], + communication_package: communication_package.to_json + } + end + def response_errors return if success From 94479acdf2cbc10b039497ddea3d6e3256f0a816 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 13:43:14 -0400 Subject: [PATCH 171/308] Refactor params to resolve reek issues --- .../api/v1/upload_vbms_document_controller.rb | 36 ++++++++++++------- app/jobs/upload_document_to_vbms_job.rb | 14 ++++---- .../prepare_document_upload_to_vbms.rb | 34 ++++++++++-------- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 38df1d2ed8f..61b4f9c2802 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -9,17 +9,9 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController def create # Validate copies and create distributions for Package Manager mail service if recipient info present - build_communication_package + build_mail_package - appeal = nil - # Find veteran from appeal id and check with db - if appeal_id.present? - appeal = find_veteran_by_appeal_id - else - find_file_number_by_veteran_identifier - end - - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, communication_package).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call if result.success? success_message = { message: "Document successfully queued for upload." } if recipient_info.present? @@ -45,20 +37,22 @@ def copies end # Payload with distributions value (array of JSON-formatted MailRequest objects) and copies (integer) - def communication_package + def mail_package return nil if recipient_info.blank? { distributions: mail_requests, copies: copies } end - def build_communication_package + def build_mail_package return if recipient_info.blank? throw_error_if_copies_out_of_range + # Create and validate MailRequest objects, save to database, and store distribution IDs mail_requests.map do |request| request.call distribution_ids << request.vbms_distribution_id end + params[:mail_package] = mail_package end def mail_requests @@ -97,6 +91,15 @@ def distribution_ids @distribution_ids ||= [] end + def vbms_upload_params + params[:mail_package] = mail_package + { + params: params, + user: current_user, + appeal: appeal + } + end + def appeal_id params[:appeal_id] end @@ -109,6 +112,15 @@ def bgs @bgs ||= BGSService.new end + def appeal + if appeal_id.blank? + find_file_number_by_veteran_identifier + return nil + end + + @appeal ||= find_veteran_by_appeal_id + end + def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) throw_not_found_error(Caseflow::Error::AppealNotFound, "appeal") if appeal.nil? diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index ebdea0249ea..f72fcac7722 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,7 +8,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten - # communication_package - Payload with copies value (integer) and distributions value (array of JSON-formatted + # mail_package - Payload with copies value (integer) and distributions value (array of JSON-formatted # MailRequest objects) to be submitted to Package Manager if optional recipient info is present # # Return: nil @@ -20,7 +20,7 @@ def perform(params) @initiator = User.find_by_css_id(initiator_css_id) add_context_to_sentry UploadDocumentToVbms.new(document: document).call - queue_mail_request_job(communication_package) unless communication_package.nil? + queue_mail_request_job(mail_package) unless mail_package.nil? end private @@ -41,10 +41,10 @@ def initiator_css_id @params[:initiator_css_id] end - def communication_package - return nil if @params[:communication_package].blank? + def mail_package + return nil if @params[:mail_package].blank? - @params[:communication_package] + @params[:mail_package] end def add_context_to_sentry @@ -63,10 +63,10 @@ def add_context_to_sentry ) end - def queue_mail_request_job(communication_package) + def queue_mail_request_job(mail_package) return unless document.uploaded_to_vbms_at - MailRequestJob.perform_later(document, communication_package) + MailRequestJob.perform_later(document, mail_package) info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" log_info(info_message) end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 872f1bb6bd2..edcd95558f3 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,12 +9,14 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # communication_package - Payload with copies value (integer) and distributions value (array of - # MailRequest objects) to be submitted to Package Manager if optional recipient info is present - - def initialize(params, user, appeal = nil, communication_package = nil) - @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) - @params[:communication_package] = communication_package unless communication_package.nil? + def initialize(params, user, appeal = nil) + @params = params.slice(:veteran_file_number, + :document_type, + :document_subject, + :document_name, + :file, + :application, + :mail_package) @user = user @appeal = appeal end @@ -30,7 +32,7 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - UploadDocumentToVbmsJob.perform_later(upload_document_job_params(document)) + UploadDocumentToVbmsJob.perform_later(upload_job_params(document)) end end @@ -86,21 +88,23 @@ def document_params } end - def communication_package - return nil if params[:communication_package].blank? - - params[:communication_package] - end - - def upload_document_job_params(document) + def upload_job_params(document) { document_id: document.id, initiator_css_id: @user.css_id, application: @params[:application], - communication_package: communication_package.to_json + mail_package: mail_package } end + # JSON-formatted payload with copies value (integer) and distributions value (array of MailRequest objects) + # to be submitted to Package Manager if optional recipient info is present + def mail_package + return nil if params[:mail_package].blank? + + params[:mail_package].to_json + end + def response_errors return if success From 1290215cc3a9d51b59cab0e6e4796c7d997a8890 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 14:40:01 -0400 Subject: [PATCH 172/308] Rolled back refactoring changes --- .../api/v1/upload_vbms_document_controller.rb | 5 +-- app/jobs/upload_document_to_vbms_job.rb | 23 +----------- .../prepare_document_upload_to_vbms.rb | 37 ++++++------------- 3 files changed, 14 insertions(+), 51 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 61b4f9c2802..44649658294 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -11,7 +11,7 @@ def create # Validate copies and create distributions for Package Manager mail service if recipient info present build_mail_package - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_package).call if result.success? success_message = { message: "Document successfully queued for upload." } if recipient_info.present? @@ -40,7 +40,7 @@ def copies def mail_package return nil if recipient_info.blank? - { distributions: mail_requests, copies: copies } + { distributions: mail_requests.to_json, copies: copies } end def build_mail_package @@ -52,7 +52,6 @@ def build_mail_package request.call distribution_ids << request.vbms_distribution_id end - params[:mail_package] = mail_package end def mail_requests diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index f72fcac7722..7dd00bf4168 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -12,8 +12,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # MailRequest objects) to be submitted to Package Manager if optional recipient info is present # # Return: nil - def perform(params) - @params = params + def perform(document_id:, initiator_css_id:, application: "idt", mail_package: nil) RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: document_id) @@ -27,26 +26,6 @@ def perform(params) attr_reader :document, :initiator - def application - return "idt" if @params[:application].blank? - - @params[:application] - end - - def document_id - @params[:document_id] - end - - def initiator_css_id - @params[:initiator_css_id] - end - - def mail_package - return nil if @params[:mail_package].blank? - - @params[:mail_package] - end - def add_context_to_sentry if initiator.present? Raven.user_context( diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index edcd95558f3..eeca0e02570 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -9,16 +9,13 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - def initialize(params, user, appeal = nil) - @params = params.slice(:veteran_file_number, - :document_type, - :document_subject, - :document_name, - :file, - :application, - :mail_package) + # mail_package - Payload with copies value (integer) and distributions value (array of JSON-formatted + # MailRequest objects) to be submitted to Package Manager if optional recipient info is present + def initialize(params, user, appeal = nil, mail_package = nil) + @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @user = user @appeal = appeal + @mail_package = mail_package end # Purpose: Queues a job to upload a document to vbms @@ -32,7 +29,12 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - UploadDocumentToVbmsJob.perform_later(upload_job_params(document)) + UploadDocumentToVbmsJob.perform_later( + document_id: document.id, + initiator_css_id: @user.css_id, + application: @params[:application], + mail_package: @mail_package + ) end end @@ -88,23 +90,6 @@ def document_params } end - def upload_job_params(document) - { - document_id: document.id, - initiator_css_id: @user.css_id, - application: @params[:application], - mail_package: mail_package - } - end - - # JSON-formatted payload with copies value (integer) and distributions value (array of MailRequest objects) - # to be submitted to Package Manager if optional recipient info is present - def mail_package - return nil if params[:mail_package].blank? - - params[:mail_package].to_json - end - def response_errors return if success From 8b4194ae793e78b7cd7f576a3dfd06cb4b34d14a Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 14:41:06 -0400 Subject: [PATCH 173/308] Removed unnecessary method --- .../idt/api/v1/upload_vbms_document_controller.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 44649658294..ccce89e605b 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -90,15 +90,6 @@ def distribution_ids @distribution_ids ||= [] end - def vbms_upload_params - params[:mail_package] = mail_package - { - params: params, - user: current_user, - appeal: appeal - } - end - def appeal_id params[:appeal_id] end From 683911fc37b7d98b73059622310c6cc81f01da01 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 14:56:03 -0400 Subject: [PATCH 174/308] Fixed linting --- app/workflows/mail_request.rb | 10 ++-- .../upload_vbms_document_controller_spec.rb | 5 +- spec/factories/mail_request.rb | 2 +- spec/workflows/mail_request_spec.rb | 59 +++++++++---------- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index ef4cfe1c92c..92a03c35442 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -8,10 +8,10 @@ class MailRequest include MailRequestValidator::DistributionDestination attr_accessor :recipient_type, :name, :first_name, :middle_name, :last_name, - :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, - :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, - :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, - :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id + :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, + :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, + :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, + :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id def initialize(recipient_and_destination_hash) @recipient_type = recipient_and_destination_hash[:recipient_type] @@ -46,7 +46,7 @@ def call @vbms_distribution_id = distribution.id create_a_vbms_distribution_destination else - raise Caseflow::Error::MissingRecipientInfo + fail Caseflow::Error::MissingRecipientInfo end end diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 04d63b4a0cc..c4a6cac9f79 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -32,8 +32,7 @@ postal_code: "12345", country_code: "US" } - ] - } + ] } end let(:invalid_mail_request_params) do @@ -53,7 +52,7 @@ postal_code: "12345", country_code: "US" } - ]} + ] } end let(:params_identifier) do diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index 9d84ced8809..7e92e50471a 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -8,7 +8,7 @@ destination_type { "domesticAddress" } address_line_1 { "1234 Main Street" } city { "Orlando" } - country_code { "US"} + country_code { "US" } postal_code { "12345" } state { "FL" } treat_line_2_as_addressee { false } diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb index 58ea8697977..4330d608030 100644 --- a/spec/workflows/mail_request_spec.rb +++ b/spec/workflows/mail_request_spec.rb @@ -3,36 +3,34 @@ describe MailRequest, :postgres do let(:mail_request_params) do ActionController::Parameters.new( - { recipient_type: "person", - first_name: "Bob", - last_name: "Smithmetz", - participant_id: "487470002", - destination_type: "domesticAddress", - address_line_1: "1234 Main Street", - treat_line_2_as_addressee: false, - treat_line_3_as_addressee: false, - city: "Orlando", - state: "FL", - postal_code: "12345", - country_code: "US" - } + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" ) end let(:invalid_mail_request_params) do ActionController::Parameters.new( - { recipient_type: nil, - last_name: "Smithmetz", - participant_id: "487470002", - destination_type: "domesticAddress", - address_line_1: "1234 Main Street", - treat_line_2_as_addressee: false, - treat_line_3_as_addressee: false, - city: "Orlando", - state: "FL", - postal_code: nil, - country_code: "US" - } + recipient_type: nil, + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: nil, + country_code: "US" ) end @@ -45,20 +43,19 @@ let(:mail_request_spec_object_1) { build(:mail_request, :nil_recipient_type) } include_examples "mail request has valid attributes" - it "is not valid without a recipient type" do - expect(mail_request_spec_object_1).to_not be_valid - # expect(mail_request_spec_object.errors[:recipient_type]).to eq(["can't be blank", "is not included in the list"]) - end + it "is not valid without a recipient type" do + expect(mail_request_spec_object_1).to_not be_valid + end describe "#call" do context "when valid parameters are passed into the mail requests initialize method." do subject { described_class.new(mail_request_params).call } it "creates a vbms_distribution" do - expect{ subject }.to change(VbmsDistribution, :count).by(1) + expect { subject }.to change(VbmsDistribution, :count).by(1) end it "creates a vbms_distribution_destination" do - expect{ subject }.to change(VbmsDistributionDestination, :count).by(1) + expect { subject }.to change(VbmsDistributionDestination, :count).by(1) end end From e4a9f420511e7b46a4d61991dc47a614181e47fc Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 15:15:09 -0400 Subject: [PATCH 175/308] Reformated instance variables --- .../api/v1/upload_vbms_document_controller.rb | 21 ++++++++++--------- .../prepare_document_upload_to_vbms.rb | 10 ++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index ccce89e605b..68b258f2f65 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -47,7 +47,7 @@ def build_mail_package return if recipient_info.blank? throw_error_if_copies_out_of_range - # Create and validate MailRequest objects, save to database, and store distribution IDs + # Create and validate MailRequest objects, save to db, and store distribution IDs mail_requests.map do |request| request.call distribution_ids << request.vbms_distribution_id @@ -90,6 +90,16 @@ def distribution_ids @distribution_ids ||= [] end + # Find veteran from appeal id and check with db + def appeal + if appeal_id.blank? + find_file_number_by_veteran_identifier + return nil + end + + @appeal ||= find_veteran_by_appeal_id + end + def appeal_id params[:appeal_id] end @@ -102,15 +112,6 @@ def bgs @bgs ||= BGSService.new end - def appeal - if appeal_id.blank? - find_file_number_by_veteran_identifier - return nil - end - - @appeal ||= find_veteran_by_appeal_id - end - def find_veteran_by_appeal_id appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) throw_not_found_error(Caseflow::Error::AppealNotFound, "appeal") if appeal.nil? diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index eeca0e02570..b45d05cb588 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -47,23 +47,23 @@ def call attr_reader :params, :user def veteran_file_number - @params[:veteran_file_number] + params[:veteran_file_number] end def document_subject - @params[:document_subject] + params[:document_subject] end def document_name - @params[:document_name] + params[:document_name] end def file - @params[:file] + params[:file] end def document_type - @params[:document_type] + params[:document_type] end def valid_document_type From c3bc8715d73921fcea8e751d40bd1ee69ae6be86 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 16:06:33 -0400 Subject: [PATCH 176/308] One last shot at fixing reek parameters issuegit add . --- app/jobs/upload_document_to_vbms_job.rb | 22 +++++++++++++++---- .../prepare_document_upload_to_vbms.rb | 18 +++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 7dd00bf4168..b1e1739863a 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -12,11 +12,13 @@ class UploadDocumentToVbmsJob < CaseflowJob # MailRequest objects) to be submitted to Package Manager if optional recipient info is present # # Return: nil - def perform(document_id:, initiator_css_id:, application: "idt", mail_package: nil) + + # document_id:, initiator_css_id:, application: "idt", mail_package: nil + def perform(params) RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user - @document = VbmsUploadedDocument.find_by(id: document_id) - @initiator = User.find_by_css_id(initiator_css_id) + @document = VbmsUploadedDocument.find_by(id: params[:document_id]) + @initiator = User.find_by_css_id(params[:initiator_css_id]) add_context_to_sentry UploadDocumentToVbms.new(document: document).call queue_mail_request_job(mail_package) unless mail_package.nil? @@ -24,7 +26,19 @@ def perform(document_id:, initiator_css_id:, application: "idt", mail_package: n private - attr_reader :document, :initiator + attr_reader :document, :initiator, :params + + def application + return "idt" if params[:application].blank? + + params[:application] + end + + def mail_package + return nil if params[:mail_package].blank? + + params[:mail_package] + end def add_context_to_sentry if initiator.present? diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index b45d05cb588..fe028599b52 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -29,12 +29,7 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - UploadDocumentToVbmsJob.perform_later( - document_id: document.id, - initiator_css_id: @user.css_id, - application: @params[:application], - mail_package: @mail_package - ) + UploadDocumentToVbmsJob.perform_later(upload_job_params(document)) end end @@ -44,7 +39,7 @@ def call private attr_accessor :success - attr_reader :params, :user + attr_reader :params, :user, :mail_package, :document def veteran_file_number params[:veteran_file_number] @@ -90,6 +85,15 @@ def document_params } end + def upload_job_params(document) + { + document_id: document.id, + initiator_css_id: user.css_id, + application: params[:application], + mail_package: mail_package + } + end + def response_errors return if success From bffd27979376a83456869aa97730f174ee7915ca Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 16:28:11 -0400 Subject: [PATCH 177/308] Fixed error and updated spec --- app/jobs/upload_document_to_vbms_job.rb | 1 + spec/jobs/upload_document_to_vbms_job_spec.rb | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index b1e1739863a..3548159c685 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -15,6 +15,7 @@ class UploadDocumentToVbmsJob < CaseflowJob # document_id:, initiator_css_id:, application: "idt", mail_package: nil def perform(params) + @params = params RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user @document = VbmsUploadedDocument.find_by(id: params[:document_id]) diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 2dc3e3a994f..1bffc6fc055 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -6,12 +6,16 @@ let(:service) { instance_double(UploadDocumentToVbms) } let(:user) { create(:user) } let(:mail_request) { instance_double(MailRequest) } + let(:mail_package) do + { distributions: [mail_request.to_json], + copies: 1 } + end let(:mail_request_job) { class_double(MailRequestJob) } let(:params) do { document_id: document.id, initiator_css_id: user.css_id, - mail_request: mail_request } + mail_package: mail_package } end subject { UploadDocumentToVbmsJob.perform_now(params) } @@ -24,15 +28,15 @@ subject end - context "document is associated with a mail request" do + context "document is associated with a mail package" do it "calls #perform_later on MailRequestJob" do - expect(mail_request_job).to receive(:perform_later).with(document, mail_request) + expect(mail_request_job).to receive(:perform_later).with(document, mail_package) subject end end - context "document is not associated with a mail request" do - let(:mail_request) { nil } + context "document is not associated with a mail package" do + let(:mail_package) { nil } it "does not call #perform_later on MailRequestJob" do expect(mail_request_job).to_not receive(:perform_later) subject From 36382b542e9f2e0073fb35cecb5d6fd9b89e5b16 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Mon, 12 Jun 2023 18:21:22 -0400 Subject: [PATCH 178/308] Fixed spacing in base controller --- app/controllers/idt/api/v1/base_controller.rb | 2 +- app/controllers/idt/api/v1/upload_vbms_document_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 8f59beae93f..3318aabe7b1 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -43,7 +43,7 @@ class Idt::Api::V1::BaseController < ApplicationController rescue_from Caseflow::Error::MissingRecipientInfo do |error| log_error(error) uuid = SecureRandom.uuid - render(json: { message: "IDT Exception ID:" + uuid + " Recipient information received was invalid or incomplete.", + render(json: { message: "IDT Exception ID: " + uuid + " Recipient information received was invalid or incomplete.", errors: JSON.parse(error.message) }, status: :bad_request) end diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 68b258f2f65..af42eca3a8a 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -8,7 +8,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController before_action :verify_access def create - # Validate copies and create distributions for Package Manager mail service if recipient info present + # Create distributions for Package Manager mail service if recipient info present build_mail_package result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_package).call From f21f70d9b8419ea767ab5ec50636ed35d5288e57 Mon Sep 17 00:00:00 2001 From: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Date: Tue, 13 Jun 2023 11:35:02 -0400 Subject: [PATCH 179/308] Hotfix/appeals 19651 (#18768) * APPEALS-19561 added two new job files * APPEALS-19651 created query logic * APPEALS-19651 Refactor query methods, adjusted timestamp columns, added some loggin * APPEALS-19651 added batch limit and refactored logic for syncing notification reports method * started writing rspec tests for ama syncing job * APPEALS-19651 made rspec tests for ama appeals * APPEALS-19651 Updated legacy appeal job logic * APPEALS-19651 refactored * APPEALS-19651 fixed code climate errors * APPEALS-19651 fixed code climate errors * APPEALS-1951 fixed recently outcoded issue and seeding notifications in ama rpsec * APPEALS-19651 Update legacy job and add rspec * APPEALS-19651 Added seeding of notification events to rspec * APPEALS-19651 Refactored checks into appropriate submethods (legacy) * APPEALS-19651 refactored the array for previously synced appeals * APPEALS-19651 Change select to map and update rspec for realism * APPEALS-19651 Removed extra "?" * APPEALS-19651 Added Tomdoc comments * APPAEALS-19651 added comments to ama_notification_efolder_sync_job * APPAEALS-19651 added comments to ama_notification_efolder_sync_job * APPEALS-19651 fixed ama rspec tests * APPEALS-19651 fixed rspec tests for legacy efolder job * APPEALS-19651 added new scope for querying successfully uploaded documents * APPEALS-19651 Deleted old job and rspec * APPEALS-19651 Updated scope on vbms uploaded document and changed scheduled jobs * APPEALS-19651 Updated comments and refactored ternary statement * APPEALS-19651 Made changes to rspec to use references to array instead of activerecord * APPEALS-19651 Update scope formatting to allow for multiline * APPEALS-19651 Implemented new query logic (need to clean up existing logic after testing) * APPEALS-19651 Removed commented code. Implemented query on legacy job * APPEALS-19651 Updated query to filter for document_type and updated rspec * Ensure each appeal record has an associated doc upload and notification * APPEALS-19651 Removed date from filename for upload * APPEALS-19651 Consolidated if statement to one-liner using external_id * APPEALS-19651 Added date back to filename temporarily. Added type conversion for batch limit * Use updated VBMS gem * Gemfile.lock was left out of the last one * Add update_document_in_vbms to VbmsService * Add polymorphic association to VbmsUploadedDocument for Appeal/LegacyAppeal * Allow for uploaded docs to be accessible via appeals * Add UpdateDocumentInVbms * Switch to a branch name in gemfile for VBMS gem * Create parallel classes for document update processing. LOTS of duplication with plenty of opportunity to DRY things up. * Change URL * Change job name in prepare_document_update in_vbms.rb and add comment in concern * Saving version and series ref Ids whenever uploading a doc to VBMS * APPEALS-19651 Fetch prev version id and pass along to update call to VBMS * APPEALS-19651 Updated VBMSService fake * APPEALS-19651 fixed the way we pass document_params * APPEALS-19651 Updated fakes to reflect real responses * APPEALS-19651 Updated query and presence check * Update connect_vbms hash * Update Gemfile.lock * APPEALS-19651 Corrected method to get update token * Some test fixes * Give AddClaimantPage Jest test a better chance of succeeding * More exclamations * Remove extra tables * Add back in setting of instance variables. Some older tests were set up to use these. * Even more exclamations * Fix concern tests * Fix a couple of linting errors * APPEALS-19651 Fix linting error in concern * Revert back to v5.1 * Ignore false SQL inject warning * APPEALS-19651 Add update document in vbms job spec * APPEALS-19651 Reduced arguments for update call, add rspec for update workflow * Remove space * Add timeout to rspec job * Try database cleaner tags on specs * More test tweaks * Disable DB truncation test * Reenable db cleaner for now * Fix legacy tests * Try turning back off DB cleaner in after block * Remove comments * Add VbmsDocumentTransactionConcern to DRY things up a bit * DRY up tests a bit * A couple more CC fixes * Min/APPEALS-21753 (#18578) * APPEALS-21753 added new status for when notification is created while veteran deceased without a subtitute * APPEALS-21753 added a new scope and now checking for veterans that are either not deceased or have substitutes * APPEALS-21753 added filters for veteran deceased status * APPEALS-21753 added new scope in appeal and new veteran deceased status checks for legacy appeals * APPEALS-21753 added rspec tests for the new status * APPEALS-21753 added new rspec tests for ama and legacy notification efolder sync * APPEALS-21753 updated notification view snapshot * APPEALS-21753 changed eq to match_array for some rspec tests * APPEALS-21753 adjusted rspec tests in appeal_notification_report_concern_spec --------- Co-authored-by: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> * Update commit hash * APPEALS-19651 Updated ref for connect_vbms and gemfile.lock * Fix key names * APPEALS-19651 Add safety navigator * Remove versioning * Remove param * APPEALS-19651 Add comments on how to enable versioning in the future * Use factory over direct AR calls * APPEALS-19651 Eliminate flakiness and update legacy spec to use factories * APPEALS-19651 Fix linting/CC issues * Tweak perform job blocks * Move job execution * More test tweaks * Switch back to eq * Try remove docs first * Use match_array after all since doc generation is async, and order will differ between runs * Account for appeal IDs changing between test blocks * Create first_run_vbms_document_appeal_ids method * Fix lack of param * Fix other param * Remove notification creation * Locate appeals from first run within the second context instead of carrying them over from the first. --------- Co-authored-by: Minhazur Rahaman Co-authored-by: Marc Steele Co-authored-by: Matthew Thornton Co-authored-by: minhazur9 <65432922+minhazur9@users.noreply.github.com> --- .github/workflows/workflow.yml | 1 + Gemfile | 2 +- Gemfile.lock | 6 +- app/jobs/ama_notification_efolder_sync_job.rb | 159 +++++++++++++++++ .../legacy_notification_efolder_sync_job.rb | 155 ++++++++++++++++ app/jobs/notification_efolder_sync_job.rb | 84 --------- app/jobs/update_document_in_vbms_job.rb | 42 +++++ app/models/appeal.rb | 11 ++ .../appeal_notification_report_concern.rb | 74 ++++++-- .../va_notify/appellant_notification.rb | 2 + app/models/vbms_uploaded_document.rb | 4 + app/queries/appeals_updated_since_query.rb | 1 + app/services/external_api/vbms_service.rb | 25 +++ .../vbms_document_transaction_concern.rb | 33 ++++ .../prepare_document_update_in_vbms.rb | 105 +++++++++++ .../prepare_document_upload_to_vbms.rb | 20 +-- app/workflows/update_document_in_vbms.rb | 105 +++++++++++ app/workflows/upload_document_to_vbms.rb | 7 +- .../addClaimants/AddClaimantPage.test.js | 2 +- config/brakeman.ignore | 48 ++++- config/initializers/scheduled_jobs.rb | 3 +- ...and_series_ids_to_vbms_document_uploads.rb | 27 +++ db/schema.rb | 4 +- lib/fakes/vbms_service.rb | 33 ++++ .../ama_notification_efolder_sync_job_spec.rb | 168 ++++++++++++++++++ ...gacy_notification_efolder_sync_job_spec.rb | 147 +++++++++++++++ .../notification_efolder_sync_job_spec.rb | 139 --------------- spec/jobs/update_document_in_vbms_job_spec.rb | 19 ++ spec/models/appellant_notification_spec.rb | 18 ++ ...appeal_notification_report_concern_spec.rb | 6 +- .../workflows/vbms_document_transactions.rb | 92 ++++++++++ .../workflows/update_document_in_vbms_spec.rb | 47 +++++ .../workflows/upload_document_to_vbms_spec.rb | 91 +--------- 33 files changed, 1318 insertions(+), 362 deletions(-) create mode 100644 app/jobs/ama_notification_efolder_sync_job.rb create mode 100644 app/jobs/legacy_notification_efolder_sync_job.rb delete mode 100644 app/jobs/notification_efolder_sync_job.rb create mode 100644 app/jobs/update_document_in_vbms_job.rb create mode 100644 app/workflows/concerns/vbms_document_transaction_concern.rb create mode 100644 app/workflows/prepare_document_update_in_vbms.rb create mode 100644 app/workflows/update_document_in_vbms.rb create mode 100644 db/migrate/20230508202742_add_doc_reference_and_series_ids_to_vbms_document_uploads.rb create mode 100644 spec/jobs/ama_notification_efolder_sync_job_spec.rb create mode 100644 spec/jobs/legacy_notification_efolder_sync_job_spec.rb delete mode 100644 spec/jobs/notification_efolder_sync_job_spec.rb create mode 100644 spec/jobs/update_document_in_vbms_job_spec.rb create mode 100644 spec/support/shared_examples/workflows/vbms_document_transactions.rb create mode 100644 spec/workflows/update_document_in_vbms_spec.rb diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e51928e2479..622314d76f0 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -14,6 +14,7 @@ jobs: # This job runs the main deployment of caseflow caseflow_rspec_job: runs-on: ubuntu-8-cores-latest + timeout-minutes: 45 services: postgres: image: postgres:11.7 diff --git a/Gemfile b/Gemfile index d8fedbfa5f9..04bf9e255d5 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,7 @@ gem "browser" gem "business_time", "~> 0.9.3" gem "caseflow", git: "https://github.com/department-of-veterans-affairs/caseflow-commons", ref: "6377b46c2639248574673adc6a708d2568c6958c" 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: "43654a058d5a1d3f83f9bfdb832a19b4a9adea8b" +gem "connect_vbms", git: "https://github.com/department-of-veterans-affairs/connect_vbms.git", ref: "98b1f9f8aa368189a59af74d91cb0aa4c55006af" gem "console_tree_renderer", git: "https://github.com/department-of-veterans-affairs/console-tree-renderer.git", tag: "v0.1.1" gem "countries" gem "ddtrace" diff --git a/Gemfile.lock b/Gemfile.lock index 98ffb5dd195..710c4378d8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -35,10 +35,10 @@ GIT GIT remote: https://github.com/department-of-veterans-affairs/connect_vbms.git - revision: 43654a058d5a1d3f83f9bfdb832a19b4a9adea8b - ref: 43654a058d5a1d3f83f9bfdb832a19b4a9adea8b + revision: 98b1f9f8aa368189a59af74d91cb0aa4c55006af + ref: 98b1f9f8aa368189a59af74d91cb0aa4c55006af specs: - connect_vbms (1.2.0) + connect_vbms (1.3.0) httpclient (~> 2.8.0) httpi (~> 2.4) mail diff --git a/app/jobs/ama_notification_efolder_sync_job.rb b/app/jobs/ama_notification_efolder_sync_job.rb new file mode 100644 index 00000000000..b373b4a79fb --- /dev/null +++ b/app/jobs/ama_notification_efolder_sync_job.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +class AmaNotificationEfolderSyncJob < CaseflowJob + queue_with_priority :low_priority + + BATCH_LIMIT = ENV["AMA_NOTIFICATION_REPORT_SYNC_LIMIT"] || 500 + + # Purpose: Determines which appeals need a notification report generated and uploaded to efolder, + # then uploads reports for those appeals + # + # Params: none + # + # Return: Array of appeals that were attempted to upload notification reports to efolder + def perform + RequestStore[:current_user] = User.system_user + all_active_ama_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync + sync_notification_reports(all_active_ama_appeals.first(BATCH_LIMIT.to_i)) + end + + private + + # Purpose: Determines a list of appeals that have been closed in the last day + # These would not be found by other queries and are most important to be synced fist + # + # Params: none + # + # Return: Array of appeals that were closed within the last 24 hours + def appeals_recently_outcoded + Appeal + .where(id: RootTask.where( + appeal_type: "Appeal", + status: "completed", + closed_at: 1.day.ago..Time.zone.now + ) + .pluck(:appeal_id) + .uniq) + end + + # Purpose: Determines which appeals have never had a notification report uploaded to efolder + # + # Params: none + # + # Return: Array of appeals that have never been synced and meet all requirements for syncing + def appeals_never_synced + # A list of unique appeal ids (Primary Key) that exist in VBMSUploadedDocument and are of type BVA Case Notification + appeal_ids_synced = VbmsUploadedDocument.distinct + .where(appeal_type: "Appeal", document_type: "BVA Case Notifications") + .successfully_uploaded + .pluck(:appeal_id) + + # A list of Appeals that have never had notification reports generated and synced with VBMS + Appeal.joins("JOIN notifications ON \ + notifications.appeals_id = appeals.\"uuid\"::text AND \ + notifications.appeals_type = 'Appeal'") + .active + .non_deceased_appellants + .where.not(id: appeal_ids_synced) + .group(:id) + end + + # Purpose: Determines which appeals need a NEW notification report uploaded to efolder + # + # Params: none + # + # Return: Array of appeals that are ready for a new notification report + def ready_for_resync + # Ids for the latest Notification Report for every AMA Appeal ordered from oldest to newest + previously_synced_appeal_ids = VbmsUploadedDocument + .where(appeal_type: "Appeal", document_type: "BVA Case Notifications") + .successfully_uploaded + .order(attempted_at: :desc) + .uniq(&:appeal_id) + .reverse.pluck(:appeal_id) + + # Appeals for all the previously synced reports from oldest to newest + get_appeals_from_prev_synced_ids(previously_synced_appeal_ids) + end + + # Purpose: Determines if a new notification has happened since the last time a + # notification report was uploaded to efolder + # + # Params: Array of appeal ids (primary key) + # + # Return: Array of active appeals + def get_appeals_from_prev_synced_ids(appeal_ids) + Appeal.active.find_by_sql( + <<-SQL + SELECT appeals.* + FROM appeals + JOIN (#{appeals_on_latest_notifications(appeal_ids)}) AS notifs ON + notifs.appeals_id = appeals."uuid"::text AND notifs.appeals_type = 'Appeal' + JOIN (#{appeals_on_latest_doc_uploads(appeal_ids)}) AS vbms_uploads ON + vbms_uploads.appeal_id = appeals.id AND vbms_uploads.appeal_type = 'Appeal' + WHERE + notifs.notified_at > vbms_uploads.attempted_at + OR + notifs.created_at > vbms_uploads.attempted_at + GROUP BY appeals.id + SQL + ) + end + + def appeals_on_latest_notifications(appeal_ids) + <<-SQL + SELECT n1.* FROM appeals a + JOIN notifications n1 on n1.appeals_id = a."uuid"::text AND n1.appeals_type = 'Appeal' + LEFT OUTER JOIN notifications n2 ON (n2.appeals_id = a."uuid"::text AND n1.appeals_type = 'Appeal' AND + (n1.notified_at < n2.notified_at OR (n1.notified_at = n2.notified_at AND n1.id < n2.id))) + WHERE n2.id IS NULL + AND n1.id IS NOT NULL + AND (n1.email_notification_status <> 'Failure Due to Deceased' + OR n1.sms_notification_status <> 'Failure Due to Deceased') + #{format_appeal_ids_sql_list(appeal_ids)} + SQL + end + + def appeals_on_latest_doc_uploads(appeal_ids) + <<-SQL + SELECT doc1.* FROM appeals a + JOIN vbms_uploaded_documents doc1 on doc1.appeal_id = a.id + AND doc1.appeal_type = 'Appeal' + AND doc1.document_type = 'BVA Case Notifications' + LEFT OUTER JOIN vbms_uploaded_documents doc2 ON ( + doc2.appeal_id = a.id AND + doc2.appeal_type = 'Appeal' AND + doc2.document_type = 'BVA Case Notifications' AND + (doc1.attempted_at < doc2.attempted_at OR (doc1.attempted_at = doc2.attempted_at AND doc1.id < doc2.id))) + WHERE doc2.id IS NULL + AND doc1.id IS NOT NULL + #{format_appeal_ids_sql_list(appeal_ids)} + SQL + end + + def format_appeal_ids_sql_list(appeal_ids) + return "" if appeal_ids.empty? + + return "a.id = #{appeal_ids.first}" if appeal_ids.one? + + "AND a.id IN (#{appeal_ids.join(',').chomp(',')})" + end + + # Purpose: Syncs the notification reports in VBMS with the notification table for each appeal + # Params: appeals - AMA appeals records in need of a new notification report to be generated + # Return: none + def sync_notification_reports(appeals) + Rails.logger.info("Starting to sync notification reports for AMA appeals") + gen_count = 0 + appeals.each do |appeal| + begin + appeal.upload_notification_report! + gen_count += 1 + rescue StandardError => error + log_error(error) + next + end + end + Rails.logger.info("Finished generating #{gen_count} notification reports for AMA appeals") + end +end diff --git a/app/jobs/legacy_notification_efolder_sync_job.rb b/app/jobs/legacy_notification_efolder_sync_job.rb new file mode 100644 index 00000000000..1e3a761c803 --- /dev/null +++ b/app/jobs/legacy_notification_efolder_sync_job.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +class LegacyNotificationEfolderSyncJob < CaseflowJob + queue_with_priority :low_priority + + BATCH_LIMIT = ENV["LEGACY_NOTIFICATION_REPORT_SYNC_LIMIT"] || 500 + + # Purpose: Determines which appeals need a notification report generated and uploaded to efolder, + # then uploads reports for those appeals + # + # Params: none + # + # Return: Array of appeals that were attempted to upload notification reports to efolder + def perform + RequestStore[:current_user] = User.system_user + all_active_legacy_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync + sync_notification_reports(all_active_legacy_appeals.first(BATCH_LIMIT.to_i)) + end + + private + + # Purpose: Determines a list of appeals that have been closed in the last day + # These would not be found by other queries and are most important to be synced fist + # + # Params: none + # + # Return: Array of appeals that were closed within the last 24 hours + def appeals_recently_outcoded + LegacyAppeal + .where(id: RootTask.where( + appeal_type: "LegacyAppeal", + status: "completed", + closed_at: 1.day.ago..Time.zone.now + ) + .pluck(:appeal_id) + .uniq) + end + + # Purpose: Determines which appeals have never had a notification report uploaded to efolder + # + # Params: none + # + # Return: Array of appeals that have never been synced and meet all requirements for syncing + def appeals_never_synced + appeal_ids_synced = VbmsUploadedDocument.distinct + .where(appeal_type: "LegacyAppeal", document_type: "BVA Case Notifications") + .successfully_uploaded + .pluck(:appeal_id) + + LegacyAppeal.joins("JOIN notifications ON \ + notifications.appeals_id = legacy_appeals.vacols_id AND \ + notifications.appeals_type = 'LegacyAppeal'") + .where(id: RootTask.open.where(appeal_type: "LegacyAppeal").pluck(:appeal_id)) + .where.not(id: appeal_ids_synced) + .group(:id) + end + + # Purpose: Determines which appeals need a NEW notification report uploaded to efolder + # + # Params: none + # + # Return: Array of appeals that are ready for a new notification report + def ready_for_resync + previously_synced_appeal_ids = VbmsUploadedDocument + .where(appeal_type: "LegacyAppeal", document_type: "BVA Case Notifications") + .successfully_uploaded + .order(attempted_at: :desc) + .uniq(&:appeal_id) + .reverse.pluck(:appeal_id) + + get_appeals_from_prev_synced_ids(previously_synced_appeal_ids) + end + + # Purpose: Determines if a new notification has happened since the last time a + # notification report was uploaded to efolder + # + # Params: Array of appeal ids (primary key) + # + # Return: Array of active appeals + def get_appeals_from_prev_synced_ids(appeal_ids) + LegacyAppeal.where(id: RootTask.open.where(appeal_type: "LegacyAppeal").pluck(:appeal_id)) + .find_by_sql( + <<-SQL + SELECT la.* + FROM legacy_appeals la + JOIN (#{appeals_on_latest_notifications(appeal_ids)}) AS notifs ON + notifs.appeals_id = la.vacols_id AND notifs.appeals_type = 'LegacyAppeal' + JOIN (#{appeals_on_latest_doc_uploads(appeal_ids)}) AS vbms_uploads ON + vbms_uploads.appeal_id = la.id AND vbms_uploads.appeal_type = 'LegacyAppeal' + WHERE + notifs.notified_at > vbms_uploads.attempted_at + OR + notifs.created_at > vbms_uploads.attempted_at + GROUP BY la.id + SQL + ) + end + + def appeals_on_latest_notifications(appeal_ids) + <<-SQL + SELECT n1.* FROM legacy_appeals a + JOIN notifications n1 on n1.appeals_id = a.vacols_id AND n1.appeals_type = 'LegacyAppeal' + LEFT OUTER JOIN notifications n2 ON (n2.appeals_id = a.vacols_id AND n1.appeals_type = 'LegacyAppeal' AND + (n1.notified_at < n2.notified_at OR (n1.notified_at = n2.notified_at AND n1.id < n2.id))) + WHERE n2.id IS NULL + AND n1.id IS NOT NULL + AND (n1.email_notification_status <> 'Failure Due to Deceased' + OR n1.sms_notification_status <> 'Failure Due to Deceased') + #{format_appeal_ids_sql_list(appeal_ids)} + SQL + end + + def appeals_on_latest_doc_uploads(appeal_ids) + <<-SQL + SELECT doc1.* FROM legacy_appeals a + JOIN vbms_uploaded_documents doc1 on doc1.appeal_id = a.id + AND doc1.appeal_type = 'LegacyAppeal' + AND doc1.document_type = 'BVA Case Notifications' + LEFT OUTER JOIN vbms_uploaded_documents doc2 ON ( + doc2.appeal_id = a.id AND + doc2.appeal_type = 'LegacyAppeal' AND + doc2.document_type = 'BVA Case Notifications' AND + (doc1.attempted_at < doc2.attempted_at OR (doc1.attempted_at = doc2.attempted_at AND doc1.id < doc2.id))) + WHERE doc2.id IS NULL + AND doc1.id IS NOT NULL + #{format_appeal_ids_sql_list(appeal_ids)} + SQL + end + + def format_appeal_ids_sql_list(appeal_ids) + return "" if appeal_ids.empty? + + return "a.id = #{appeal_ids.first}" if appeal_ids.one? + + "AND a.id IN (#{appeal_ids.join(',').chomp(',')})" + end + + # Purpose: Syncs the notification reports in VBMS with the notification table for each appeal + # Params: appeals - LegacyAppeals records in need of a new notification report to be generated + # Return: none + def sync_notification_reports(appeals) + Rails.logger.info("Starting to sync notification reports for Legacy appeals") + gen_count = 0 + appeals.each do |appeal| + begin + appeal.upload_notification_report! + gen_count += 1 + rescue StandardError => error + log_error(error) + next + end + end + Rails.logger.info("Finished generating #{gen_count} notification reports for Legacy appeals") + end +end diff --git a/app/jobs/notification_efolder_sync_job.rb b/app/jobs/notification_efolder_sync_job.rb deleted file mode 100644 index e208780e4ba..00000000000 --- a/app/jobs/notification_efolder_sync_job.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -class NotificationEfolderSyncJob < CaseflowJob - queue_with_priority :low_priority - - # * Query gives back a list of both Active AMA and Legacy Appeals that have notifications - # * and has a VBMS uploaded document associated with the appeal and has the - # * document_type = "BVA Case Notifications" and the last notification associated with the Appeal - # * notification datetime is after the vbms uploaded doc uploaded_datetime. If no record exists it will - # * also return the appeal. - - # rubocop:disable Metrics/MethodLength - def perform - RequestStore[:current_user] = User.system_user - appeals_with_notifications = "select appeals.* from appeals - inner join (select distinct(notifications.appeals_id) - from notifications where notifications.appeals_type = 'Appeal') - appeal_uuids on uuid::varchar(255) = appeal_uuids.appeals_id" - - legacy_appeals_with_notifications = "select legacy_appeals.* from legacy_appeals - inner join (select distinct(notifications.appeals_id) - from notifications where notifications.appeals_type = 'LegacyAppeal') - unique_vacols_ids on vacols_id = unique_vacols_ids.appeals_id" - - all_appeals_combined = Appeal.find_by_sql(appeals_with_notifications) + - LegacyAppeal.find_by_sql(legacy_appeals_with_notifications) - - all_appeals_combined.select do |appeal| - begin - if check_if_record_exists_in_vbms_uploaded_doc?(appeal) - - unique_identifier = unique_identifier(appeal) - latest_appeal_notification = last_notification_of_appeal(unique_identifier) - latest_vbms_doc = latest_vbms_uploaded_document(appeal.id) - notification_timestamp = latest_appeal_notification.notified_at || latest_appeal_notification.updated_at - if notification_timestamp > latest_vbms_doc.attempted_at - appeal.upload_notification_report! - end - else - appeal.upload_notification_report! - end - rescue StandardError => error - log_error(error) - next - end - end - end - # rubocop:enable Metrics/MethodLength - - # * Checks if there is a vbms doc associated with the appeal exists. Will return true if it exists - # * and will return false if one does not. - def check_if_record_exists_in_vbms_uploaded_doc?(appeal) - VbmsUploadedDocument.where(appeal_id: appeal.id, appeal_type: appeal.class.name, document_type: "BVA Case Notifications").present? - end - - # * Will return the last notification associated with the appeal. - # * Finds the Notification by the appeals_id orders by notified_at in descending order - # * and grabs the first one - def last_notification_of_appeal(uuid) - Notification.where(appeals_id: uuid).order(notified_at: :desc).first - end - - # * Will get the latest finds the doc by its appeal_id. Will only return if - # * the document_type = "BVA Case Notifications" uploaded at is not nil and - # * returns the list in descending order and gets the first record in that list - def latest_vbms_uploaded_document(appeal_id) - VbmsUploadedDocument.where(appeal_id: appeal_id, document_type: "BVA Case Notifications") - .where.not(attempted_at: nil) - .order(uploaded_to_vbms_at: :desc).first - end - - # * Both Leagcy and AMA appeals have different associations with each table. This method - # * determines which type of appeal it is by the association. If the Appeal is an AMA Appeal - # * it will return the UUID associated with it. If the Appeal is a Legacy Appeal it will return the - # * vacols_id associated with it. - def unique_identifier(appeal) - if appeal.is_a?(Appeal) - appeal.uuid - - elsif appeal.is_a?(LegacyAppeal) - appeal.vacols_id - end - end -end diff --git a/app/jobs/update_document_in_vbms_job.rb b/app/jobs/update_document_in_vbms_job.rb new file mode 100644 index 00000000000..37ca685beb9 --- /dev/null +++ b/app/jobs/update_document_in_vbms_job.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +class UpdateDocumentInVbmsJob < CaseflowJob + queue_with_priority :low_priority + + # Purpose: Calls the UpdateDocumentToVbms workflow to update the given document in VBMS + # + # Params: document_id - integer to search for VbmsUploadedDocument + # initiator_css_id - string to find a user by css_id + # application - string with a default value of "idt" but can be overwritten + # + # Return: nil + def perform(document_id:, initiator_css_id:, application: "idt") + RequestStore.store[:application] = application + RequestStore.store[:current_user] = User.system_user + + @document = VbmsUploadedDocument.find_by(id: document_id) + @initiator = User.find_by_css_id(initiator_css_id) + add_context_to_sentry + UpdateDocumentInVbms.new(document: document).call + end + + private + + attr_reader :document, :initiator + + def add_context_to_sentry + if initiator.present? + Raven.user_context( + email: initiator.email, + css_id: initiator.css_id, + station_id: initiator.station_id, + regional_office: initiator.regional_office + ) + end + Raven.extra_context( + vbms_uploaded_document_id: document.id, + upload_document_path: "/update_document", + veteran_file_number: document.veteran_file_number + ) + end +end diff --git a/app/models/appeal.rb b/app/models/appeal.rb index 5f723e7b3ce..b8550e58709 100644 --- a/app/models/appeal.rb +++ b/app/models/appeal.rb @@ -111,6 +111,17 @@ class IssueAlreadyDuplicated < StandardError; end scope :established, -> { where.not(established_at: nil) } + scope :non_deceased_appellants, lambda { + joins("INNER JOIN veterans ON veterans.file_number = appeals.veteran_file_number") + .where("veterans.date_of_death is null OR (veterans.date_of_death is not null + AND veteran_is_not_claimant = true)") + } + + scope :has_substitute_appellant, lambda { + joins("INNER JOIN veterans ON veterans.file_number = appeals.veteran_file_number") + .where("veterans.date_of_death is not null AND veteran_is_not_claimant = true") + } + UUID_REGEX = /^\h{8}-\h{4}-\h{4}-\h{4}-\h{12}$/.freeze alias_attribute :nod_date, :receipt_date # LegacyAppeal parity diff --git a/app/models/concerns/appeal_notification_report_concern.rb b/app/models/concerns/appeal_notification_report_concern.rb index d38ddb13382..2ee5e8b045b 100644 --- a/app/models/concerns/appeal_notification_report_concern.rb +++ b/app/models/concerns/appeal_notification_report_concern.rb @@ -29,17 +29,11 @@ def initialize(message = "Error while trying to prepare or upload PDF") # Purpose: Generate the PDF and then prepares the document for uploading to S3 or VBMS # Returns: nil + # Replace the upload_notification_report! method call with transmit_document! + # and remove the timestamp from the naming convention when enabling versioning within efolder def upload_notification_report! - document_params = - { - veteran_file_number: veteran_file_number, - document_type: "BVA Case Notifications", - document_subject: "notifications", - document_name: notification_document_name, - application: "notification-report", - file: notification_report - } - upload_document(document_params) + upload_document + nil end @@ -48,11 +42,7 @@ def upload_notification_report! # Purpose: Creates the name for the document # Returns: The document name def notification_document_name - if is_a?(Appeal) - "notification-report_#{uuid}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" - elsif is_a?(LegacyAppeal) - "notification-report_#{vacols_id}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" - end + "notification-report_#{external_id}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" end # Purpose: Generates the PDF @@ -66,12 +56,60 @@ def notification_report end end + def document_params + { + veteran_file_number: veteran_file_number, + document_type: "BVA Case Notifications", + document_subject: "notifications", + document_name: notification_document_name, + application: "notification-report", + file: notification_report + } + end + + # Purpose: Adds a new document version to a series in eFolder if a series already exists + # Returns: The first document ID in the BVA Case Notifications series for the appeal. + def transmit_document! + version_id = document_version_ref_id + version_id.present? ? update_document(version_id) : upload_document + end + + # Purpose: Checks in eFolder for a doc in the veteran's eFolder with the same type + # Returns: document_version_reference_id for newest document in series (string) OR nil + def document_version_ref_id + response = VBMSService.fetch_document_series_for(self) + series = response.select { |obj| obj.series_id == document_series_ref_id } + series&.first&.document_id + end + + # Purpose: gets the document_series_reference_id of the most recently uploaded notification report + # Params: none + # Returns: document_series_reference_id (string) + def document_series_ref_id + vbms_uploaded_documents + .where(document_type: "BVA Case Notifications") + .where.not(uploaded_to_vbms_at: nil) + .order(uploaded_to_vbms_at: :desc) + .first + &.document_series_reference_id + end + # Purpose: Uploads the PDF # Returns: The job being queued - def upload_document(document_params) + def upload_document response = PrepareDocumentUploadToVbms.new(document_params, User.system_user, self).call - if !response.success? - fail PDFUploadError + + fail PDFUploadError unless response.success? + end + + # Purpose: Kicks off a document update in eFolder to overwrite a previous version of the document + # Returns: The job being queued + def update_document(version_id) + updated_params = document_params.tap do |params| + params[:document_version_reference_id] = version_id end + response = PrepareDocumentUpdateInVbms.new(updated_params, User.system_user, self).call + + fail PDFUploadError unless response.success? end end diff --git a/app/models/prepend/va_notify/appellant_notification.rb b/app/models/prepend/va_notify/appellant_notification.rb index da3f4609b7d..ba8e60db288 100644 --- a/app/models/prepend/va_notify/appellant_notification.rb +++ b/app/models/prepend/va_notify/appellant_notification.rb @@ -52,6 +52,8 @@ def self.handle_errors(appeal) Rails.logger.error("#{error.message}\n#{error.backtrace.join("\n")}") message_attributes[:status] = error.status end + elsif appeal.veteran_appellant_deceased? + message_attributes[:status] = "Failure Due to Deceased" else message_attributes[:status] = "Success" end diff --git a/app/models/vbms_uploaded_document.rb b/app/models/vbms_uploaded_document.rb index 7e039ef502e..6a767c13c2f 100644 --- a/app/models/vbms_uploaded_document.rb +++ b/app/models/vbms_uploaded_document.rb @@ -8,6 +8,10 @@ class VbmsUploadedDocument < CaseflowRecord attribute :file, :string + scope :successfully_uploaded, lambda { + where(error: nil).where.not(uploaded_to_vbms_at: nil, attempted_at: nil, processed_at: nil) + } + def cache_file UploadDocumentToVbms.new(document: self).cache_file end diff --git a/app/queries/appeals_updated_since_query.rb b/app/queries/appeals_updated_since_query.rb index b2eb408d9e5..0e1bc75989d 100644 --- a/app/queries/appeals_updated_since_query.rb +++ b/app/queries/appeals_updated_since_query.rb @@ -25,6 +25,7 @@ def call record_synced_by_job request_decision_issues request_issues_updates + vbms_uploaded_documents ].freeze attr_reader :since_date diff --git a/app/services/external_api/vbms_service.rb b/app/services/external_api/vbms_service.rb index bffb2a90eaf..69822a568c7 100644 --- a/app/services/external_api/vbms_service.rb +++ b/app/services/external_api/vbms_service.rb @@ -42,6 +42,12 @@ def self.fetch_document_series_for(appeal) ExternalApi::VbmsDocumentSeriesForAppeal.new(file_number: appeal.veteran_file_number).fetch end + def self.update_document_in_vbms(appeal, uploadable_document) + @vbms_client ||= init_vbms_client + response = initialize_update(appeal, uploadable_document) + update_document(appeal.veteran_file_number, response.updated_document_token, uploadable_document.pdf_location) + end + def self.upload_document_to_vbms(appeal, uploadable_document) @vbms_client ||= init_vbms_client response = initialize_upload(appeal, uploadable_document) @@ -94,6 +100,25 @@ def self.upload_document(vbms_id, upload_token, filepath) send_and_log_request(vbms_id, request) end + def self.initialize_update(appeal, uploadable_document) + content_hash = Digest::SHA1.hexdigest(File.read(uploadable_document.pdf_location)) + request = VBMS::Requests::InitializeUpdate.new( + content_hash: content_hash, + document_version_reference_id: uploadable_document.document_version_reference_id, + va_receive_date: Time.zone.now, + subject: uploadable_document.document_subject.presence || uploadable_document.document_type + ) + send_and_log_request(appeal.veteran_file_number, request) + end + + def self.update_document(vbms_id, upload_token, filepath) + request = VBMS::Requests::UpdateDocument.new( + upload_token: upload_token, + filepath: filepath + ) + send_and_log_request(vbms_id, request) + end + def self.clean_document(location) File.delete(location) end diff --git a/app/workflows/concerns/vbms_document_transaction_concern.rb b/app/workflows/concerns/vbms_document_transaction_concern.rb new file mode 100644 index 00000000000..e807d377401 --- /dev/null +++ b/app/workflows/concerns/vbms_document_transaction_concern.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Houses common methods used for uploading and updating documents in VBMS eFolder +module VbmsDocumentTransactionConcern + extend ActiveSupport::Concern + + # :reek:FeatureEnvy + def persist_efolder_version_info(response, response_key) + document.update!( + document_version_reference_id: response.dig(response_key, :@new_document_version_ref_id), + document_series_reference_id: response.dig(response_key, :@document_series_ref_id) + ) + end + + def throw_error_if_file_number_not_match_bgs + bgs_file_number = nil + if !veteran_file_number.nil? + bgs_file_number = bgs_service.fetch_file_number_by_ssn(veteran_ssn) + end + if bgs_service.fetch_veteran_info(veteran_file_number).nil? + if !bgs_file_number.blank? && !bgs_service.fetch_veteran_info(bgs_file_number).nil? + bgs_file_number + else + fail( + Caseflow::Error::BgsFileNumberMismatch, + file_number: veteran_file_number, user_id: user.id + ) + end + else + veteran_file_number + end + end +end diff --git a/app/workflows/prepare_document_update_in_vbms.rb b/app/workflows/prepare_document_update_in_vbms.rb new file mode 100644 index 00000000000..d92c609c905 --- /dev/null +++ b/app/workflows/prepare_document_update_in_vbms.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +class PrepareDocumentUpdateInVbms + include ActiveModel::Model + include VbmsDocumentTransactionConcern + + validates :veteran_file_number, :file, presence: true + validate :valid_document_type + + # Params: params - hash containing file and document_type at minimum + # user - current user that is preparing the document for upload + # appeal - Appeal object (optional if ssn or file number are passed into params) + def initialize(params, user, appeal = nil) + @params = params.slice(:veteran_file_number, + :document_type, + :document_subject, + :document_name, + :file, + :application, + :document_version_reference_id) + @document_type = @params[:document_type] + @user = user + @appeal = appeal + end + + # Purpose: Queues a job to upload a document to vbms + # + # Params: See initialize + # + # Return: nil + def call + success = valid? + if success + @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs + VbmsUploadedDocument.create(document_params).tap do |document| + document.cache_file + UpdateDocumentInVbmsJob.perform_later( + document_id: document.id, + initiator_css_id: user.css_id, + application: @params[:application] + ) + end + end + + FormResponse.new(success: success, errors: [response_errors]) + end + + private + + attr_accessor :success + attr_reader :document_type, :params, :user + + def document_version_reference_id + @params[:document_version_reference_id] + end + + def veteran_file_number + @params[:veteran_file_number] + end + + def document_subject + @params[:document_subject] + end + + def document_name + @params[:document_name] + end + + def file + @params[:file] + end + + def valid_document_type + errors.add(:document_type, "is not recognized") unless Document.type_id(document_type) + end + + def bgs_service + @bgs_service ||= BGSService.new + end + + def veteran_ssn + (!@appeal.nil? && !@appeal.veteran_ssn.nil? && !@appeal.veteran_ssn.empty?) ? @appeal.veteran_ssn : nil + end + + def document_params + { + appeal_id: @appeal&.id, + appeal_type: @appeal&.class&.name, + veteran_file_number: veteran_file_number, + document_name: document_name, + document_subject: document_subject, + document_type: document_type, + file: file, + document_version_reference_id: document_version_reference_id + } + end + + def response_errors + return if success + + { + message: errors.full_messages.join(", ") + } + end +end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index 68f7737e277..f83f59f8ed6 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -2,6 +2,7 @@ class PrepareDocumentUploadToVbms include ActiveModel::Model + include VbmsDocumentTransactionConcern validates :veteran_file_number, :file, presence: true validate :valid_document_type @@ -90,23 +91,4 @@ def response_errors message: errors.full_messages.join(", ") } end - - def throw_error_if_file_number_not_match_bgs - bgs_file_number = nil - if !veteran_file_number.nil? - bgs_file_number = bgs_service.fetch_file_number_by_ssn(veteran_ssn) - end - if bgs_service.fetch_veteran_info(veteran_file_number).nil? - if !bgs_file_number.blank? && !bgs_service.fetch_veteran_info(bgs_file_number).nil? - bgs_file_number - else - fail( - Caseflow::Error::BgsFileNumberMismatch, - file_number: veteran_file_number, user_id: user.id - ) - end - else - veteran_file_number - end - end end diff --git a/app/workflows/update_document_in_vbms.rb b/app/workflows/update_document_in_vbms.rb new file mode 100644 index 00000000000..97b4fe6a633 --- /dev/null +++ b/app/workflows/update_document_in_vbms.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +class UpdateDocumentInVbms + include VbmsDocumentTransactionConcern + + delegate :document_type, :document_subject, :document_name, :document_version_reference_id, to: :document + + def initialize(document:) + @document = document + end + + def call + return if document.processed_at + + submit_for_processing! + update_in_vbms! + set_processed_at_to_current_time + rescue StandardError => error + save_rescued_error!(error.to_s) + raise error + 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 + + attr_reader :document + + def submit_for_processing! + when_to_start = Time.zone.now + + document.update!( + last_submitted_at: when_to_start, + submitted_at: when_to_start, + processed_at: nil, + attempted_at: when_to_start + ) + end + + def update_in_vbms! + return if document.uploaded_to_vbms_at + + update_response = VBMSService.update_document_in_vbms(document.appeal, self) + + persist_efolder_version_info(update_response, :update_document_response) + + 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 8560a9ba76c..dfcda597753 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class UploadDocumentToVbms + include VbmsDocumentTransactionConcern + delegate :document_type, :document_subject, :document_name, to: :document def initialize(document:) @@ -55,7 +57,10 @@ def submit_for_processing! def upload_to_vbms! return if document.uploaded_to_vbms_at - VBMSService.upload_document_to_vbms_veteran(file_number, self) + upload_response = VBMSService.upload_document_to_vbms_veteran(file_number, self) + + persist_efolder_version_info(upload_response, :upload_document_response) + document.update!(uploaded_to_vbms_at: Time.zone.now) end diff --git a/client/test/app/intake/components/addClaimants/AddClaimantPage.test.js b/client/test/app/intake/components/addClaimants/AddClaimantPage.test.js index 517012388fa..c3ca1b387d6 100644 --- a/client/test/app/intake/components/addClaimants/AddClaimantPage.test.js +++ b/client/test/app/intake/components/addClaimants/AddClaimantPage.test.js @@ -94,7 +94,7 @@ describe('AddClaimantPage', () => { await waitFor(() => { expect(submit).not.toBeDisabled(); }); - }, 15000); + }, 20000); }); describe('Redirection to Intake home page', () => { diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 7775a056959..34bb4f52120 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -233,6 +233,26 @@ "confidence": "Weak", "note": "" }, + { + "warning_type": "SQL Injection", + "warning_code": 0, + "fingerprint": "788fbc4dec8a4fe7dc7494113f49d1ab24a04c0824f7b1fe6749f34a703b0e34", + "check_name": "SQL", + "message": "Possible SQL injection", + "file": "app/jobs/legacy_notification_efolder_sync_job.rb", + "line": 85, + "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", + "code": "LegacyAppeal.where(:id => RootTask.open.where(:appeal_type => \"LegacyAppeal\").pluck(:appeal_id)).find_by_sql(\" SELECT la.*\\n FROM legacy_appeals la\\n JOIN (#{appeals_on_latest_notifications(appeal_ids)}) AS notifs ON\\n notifs.appeals_id = la.vacols_id AND notifs.appeals_type = 'LegacyAppeal'\\n JOIN (#{appeals_on_latest_doc_uploads(appeal_ids)}) AS vbms_uploads ON\\n vbms_uploads.appeal_id = la.id AND vbms_uploads.appeal_type = 'LegacyAppeal'\\n WHERE\\n notifs.notified_at > vbms_uploads.attempted_at\\n OR\\n notifs.created_at > vbms_uploads.attempted_at\\n GROUP BY la.id\\n\")", + "render_path": null, + "location": { + "type": "method", + "class": "LegacyNotificationEfolderSyncJob", + "method": "get_appeals_from_prev_synced_ids" + }, + "user_input": "appeals_on_latest_notifications(appeal_ids)", + "confidence": "Medium", + "note": "" + }, { "warning_type": "SQL Injection", "warning_code": 0, @@ -240,7 +260,7 @@ "check_name": "SQL", "message": "Possible SQL injection", "file": "app/models/task.rb", - "line": 236, + "line": 273, "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", "code": "Arel.sql(\"CASE WHEN #{CachedAppeal.table_name}.is_aod = TRUE THEN #{(\"0 ELSE 1\" or \"1 ELSE 0\")} END, CASE WHEN #{CachedAppeal.table_name}.case_type = 'Court Remand' THEN #{(\"0 ELSE 1\" or \"1 ELSE 0\")} END, #{CachedAppeal.table_name}.docket_number #{order}, #{Task.table_name}.created_at #{order}\")", "render_path": null, @@ -260,7 +280,7 @@ "check_name": "SendFile", "message": "Model attribute used in file name", "file": "app/controllers/idt/api/v2/appeals_controller.rb", - "line": 49, + "line": 61, "link": "https://brakemanscanner.org/docs/warning_types/file_access/", "code": "send_file(Document.find(document_id).serve, :type => \"application/pdf\", :disposition => (\"attachment; filename='#{current_document[0][\"type\"]}-#{document_id}.pdf'\"))", "render_path": null, @@ -272,8 +292,28 @@ "user_input": "Document.find(document_id).serve", "confidence": "Medium", "note": "" + }, + { + "warning_type": "SQL Injection", + "warning_code": 0, + "fingerprint": "d0e669b8d1a56e5cd7ce3c7b761d52b4eb47c0da54623b8104bbf865925b70e3", + "check_name": "SQL", + "message": "Possible SQL injection", + "file": "app/jobs/ama_notification_efolder_sync_job.rb", + "line": 88, + "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", + "code": "Appeal.active.find_by_sql(\" SELECT appeals.*\\n FROM appeals\\n JOIN (#{appeals_on_latest_notifications(appeal_ids)}) AS notifs ON\\n notifs.appeals_id = appeals.\\\"uuid\\\"::text AND notifs.appeals_type = 'Appeal'\\n JOIN (#{appeals_on_latest_doc_uploads(appeal_ids)}) AS vbms_uploads ON\\n vbms_uploads.appeal_id = appeals.id AND vbms_uploads.appeal_type = 'Appeal'\\n WHERE\\n notifs.notified_at > vbms_uploads.attempted_at\\n OR\\n notifs.created_at > vbms_uploads.attempted_at\\n GROUP BY appeals.id\\n\")", + "render_path": null, + "location": { + "type": "method", + "class": "AmaNotificationEfolderSyncJob", + "method": "get_appeals_from_prev_synced_ids" + }, + "user_input": "appeals_on_latest_notifications(appeal_ids)", + "confidence": "Medium", + "note": "" } ], - "updated": "2022-02-02 09:46:55 -0500", - "brakeman_version": "5.2.0" + "updated": "2023-05-26 15:30:49 -0400", + "brakeman_version": "4.7.1" } diff --git a/config/initializers/scheduled_jobs.rb b/config/initializers/scheduled_jobs.rb index 2f73a2213e0..d722a911220 100644 --- a/config/initializers/scheduled_jobs.rb +++ b/config/initializers/scheduled_jobs.rb @@ -40,7 +40,8 @@ "fetch_all_active_legacy_appeals_job" => FetchAllActiveLegacyAppealsJob, "retrieve_and_cache_reader_documents_job" => RetrieveAndCacheReaderDocumentsJob, "travel_board_hearing_sync_job" => Hearings::TravelBoardHearingSyncJob, - "notification_efolder_sync_job" => NotificationEfolderSyncJob, + "ama_notification_efolder_sync_job" => AmaNotificationEfolderSyncJob, + "legacy_notification_efolder_sync_job" => LegacyNotificationEfolderSyncJob, "change_hearing_request_type_task_cancellation_job" => ChangeHearingRequestTypeTaskCancellationJob, "cannot_delete_contention_remediation_job" => CannotDeleteContentionRemediationJob, "contention_not_found_remediation_job" => ContentionNotFoundRemediationJob diff --git a/db/migrate/20230508202742_add_doc_reference_and_series_ids_to_vbms_document_uploads.rb b/db/migrate/20230508202742_add_doc_reference_and_series_ids_to_vbms_document_uploads.rb new file mode 100644 index 00000000000..d74c3c75fe3 --- /dev/null +++ b/db/migrate/20230508202742_add_doc_reference_and_series_ids_to_vbms_document_uploads.rb @@ -0,0 +1,27 @@ +# Adds columns to the vbms_uploaded_documents table to retain the +# documentVersionReferenceId and documentSeriesReferenceId values that are +# returned once a document is uploaded to VBMS eFolder. +# +# These values can be used to refer to documents and +# update documents via the eFolder API. +# + +class AddDocReferenceAndSeriesIdsToVbmsDocumentUploads < Caseflow::Migration + def up + add_column :vbms_uploaded_documents, + :document_version_reference_id, + :string, + comment: "UUID that is provided by eFolder that represents the specific version of the document." + + add_column :vbms_uploaded_documents, + :document_series_reference_id, + :string, + comment: "UUID that is provided by eFolder that represents the group of documents" \ + "this document belongs to. Think of a series as a stack of versions." + end + + def down + remove_column :vbms_uploaded_documents, :document_version_reference_id + remove_column :vbms_uploaded_documents, :document_series_reference_id + end +end diff --git a/db/schema.rb b/db/schema.rb index a22fd7acb3e..6c1456f44a6 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: 2023_04_25_144000) do +ActiveRecord::Schema.define(version: 2023_05_08_202742) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1854,8 +1854,10 @@ t.datetime "canceled_at", comment: "Timestamp when job was abandoned" t.datetime "created_at", null: false t.string "document_name" + t.string "document_series_reference_id", comment: "UUID that is provided by eFolder that represents the group of documentsthis document belongs to. Think of a series as a stack of versions." t.string "document_subject" t.string "document_type", null: false + t.string "document_version_reference_id", comment: "UUID that is provided by eFolder that represents the specific version of the document." t.string "error" t.datetime "last_submitted_at" t.datetime "processed_at" diff --git a/lib/fakes/vbms_service.rb b/lib/fakes/vbms_service.rb index ef19b8a0647..bde1e02782b 100644 --- a/lib/fakes/vbms_service.rb +++ b/lib/fakes/vbms_service.rb @@ -105,14 +105,47 @@ def self.fetch_document_series_for(appeal) end end + def self.update_document_in_vbms(appeal, uploadable_document) + @appeal = appeal + @updated_document = uploadable_document + + { + appeal: appeal, + updated_document: uploadable_document, + prev_version_ref_id: uploadable_document.document_version_reference_id, + update_document_response: { + :@new_document_version_ref_id => "ref", + :@document_series_ref_id => "series" + } + } + end + def self.upload_document_to_vbms(appeal, form8) @uploaded_form8 = form8 @uploaded_form8_appeal = appeal + + { + appeal: appeal, + form8: form8, + upload_document_response: { + :@new_document_version_ref_id => "ref", + :@document_series_ref_id => "series" + } + } end def self.upload_document_to_vbms_veteran(file_number, form8) @uploaded_form8 = form8 @veteran_file_number = file_number + + { + file_number: file_number, + form8: form8, + upload_document_response: { + :@new_document_version_ref_id => "ref", + :@document_series_ref_id => "series" + } + } end def self.clean_document(_location) diff --git a/spec/jobs/ama_notification_efolder_sync_job_spec.rb b/spec/jobs/ama_notification_efolder_sync_job_spec.rb new file mode 100644 index 00000000000..92da9e1b70c --- /dev/null +++ b/spec/jobs/ama_notification_efolder_sync_job_spec.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +describe AmaNotificationEfolderSyncJob, :postgres, type: :job do + include ActiveJob::TestHelper + let!(:current_user) { create(:user, roles: ["System Admin"]) } + let!(:appeals) { create_list(:appeal, 10, :active) } + let!(:job) { AmaNotificationEfolderSyncJob.new } + + BATCH_LIMIT_SIZE = 5 + + describe "perform" do + before { Seeds::NotificationEvents.new.seed! } + + let!(:today) { Time.now.utc.iso8601 } + let!(:notifications) do + appeals.each_with_index do |appeal, index| + next if [3, 7].include? index + + create(:notification, + appeals_id: appeal.uuid, + appeals_type: "Appeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: Time.zone.now - (10 - index).minutes, + email_notification_status: "delivered") + end + end + + let!(:make_appeals_outcoded) do + RootTask.find_by(appeal_id: appeals[5].id).update!(status: "completed", closed_at: 3.days.ago) + RootTask.find_by(appeal_id: appeals[6].id).update!(status: "completed", closed_at: today) + end + + let!(:first_run_outcoded_appeals) { [appeals[6]] } + let!(:first_run_never_synced_appeals) { appeals.first(3) + [appeals[4]] + appeals.last(2) } + + before(:all) { AmaNotificationEfolderSyncJob::BATCH_LIMIT = BATCH_LIMIT_SIZE } + + context "first run" do + before { VbmsUploadedDocument.delete_all } + + it "get all ama appeals that have been recently outcoded" do + expect(job.send(:appeals_recently_outcoded)).to match_array(first_run_outcoded_appeals) + end + + it "get all ama appeals that have never been synced yet" do + expect(job.send(:appeals_never_synced)).to match_array(first_run_never_synced_appeals) + end + + it "get all ama appeals that must be resynced" do + expect(job.send(:ready_for_resync)).to eq([]) + end + + it "running the perform" do + perform_enqueued_jobs { AmaNotificationEfolderSyncJob.perform_later } + + expect(find_appeal_ids_from_first_document_sync.size).to eq BATCH_LIMIT_SIZE + end + end + + context "second run" do + # Gets the appeal IDs for all of the documents created during the first run of the + # AmaNotificationEfolderSyncJob + let(:first_run_vbms_document_appeal_indexes) { find_appeal_ids_from_first_document_sync } + + # These appeals do not have notifications, or were outcoded too long ago. + let(:will_not_sync_appeal_ids) { [appeals[3].id, appeals[5].id, appeals[7].id] } + + # There are no more appeals that have been outcoded within the last 24 hours + let(:second_run_outcoded_appeals) { [] } + + # These appeals will be the ones that have not already been processed but should receive + # notifications reports. + let(:second_run_never_synced_appeals_ids) do + appeals.map(&:id) - + first_run_vbms_document_appeal_ids(first_run_vbms_document_appeal_indexes) - + will_not_sync_appeal_ids + end + + # These appeals should be all that have had notification reports generated for them after two + # runs with BATCH_LIMIT_SIZE number of appeals processed each time. + let(:second_run_vbms_document_appeal_ids) do + first_run_vbms_document_appeal_ids(first_run_vbms_document_appeal_indexes) + + [appeals[4].id] - + will_not_sync_appeal_ids + + second_run_never_synced_appeals_ids + end + + before do + perform_enqueued_jobs { AmaNotificationEfolderSyncJob.perform_later } + + RootTask.find_by(appeal_id: appeals[6].id).update!(closed_at: 25.hours.ago) + end + + it "get all ama appeals that have been recently outcoded" do + expect(job.send(:appeals_recently_outcoded)).to match_array(second_run_outcoded_appeals) + end + + it "get all ama appeals that have never been synced yet" do + expect( + job.send(:appeals_never_synced).map(&:id) + ).to match_array(second_run_never_synced_appeals_ids) + end + + it "get all ama appeals that must be resynced" do + create(:notification, + appeals_id: appeals[4].uuid, + appeals_type: "Appeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: 2.minutes.ago, + email_notification_status: "delivered") + + expect(job.send(:ready_for_resync)).to eq([appeals[4]]) + end + + it "ignore appeals that need to be resynced if latest notification status is 'Failure Due to Deceased" do + create(:notification, + appeals_id: appeals[4].uuid, + appeals_type: "Appeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: 1.minute.ago, + email_notification_status: "Failure Due to Deceased") + + expect(job.send(:ready_for_resync)).to eq([]) + end + + it "running the perform" do + create(:notification, + appeals_id: appeals[4].uuid, + appeals_type: "Appeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: Time.zone.now, + email_notification_status: "delivered") + + perform_enqueued_jobs { AmaNotificationEfolderSyncJob.perform_later } + + expect( + VbmsUploadedDocument + .where(document_type: "BVA Case Notifications") + .order(:id) + .pluck(:appeal_id) + ).to match_array(second_run_vbms_document_appeal_ids) + end + end + + def find_appeal_index_by_id(id) + appeals.map(&:id)&.find_index(id) + end + + def first_run_vbms_document_appeal_ids(appeal_indexes) + appeal_indexes.map { |idx| appeals[idx].id } + end + + def find_appeal_ids_from_first_document_sync + VbmsUploadedDocument.first(BATCH_LIMIT_SIZE) + .pluck(:appeal_id) + .map { |appeal_id| find_appeal_index_by_id(appeal_id) } + .compact + end + end +end diff --git a/spec/jobs/legacy_notification_efolder_sync_job_spec.rb b/spec/jobs/legacy_notification_efolder_sync_job_spec.rb new file mode 100644 index 00000000000..e9827103469 --- /dev/null +++ b/spec/jobs/legacy_notification_efolder_sync_job_spec.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +describe LegacyNotificationEfolderSyncJob, :all_dbs, type: :job do + include ActiveJob::TestHelper + let(:current_user) { create(:user, roles: ["System Admin"]) } + let(:job) { LegacyNotificationEfolderSyncJob.new } + + describe "perform" do + before { Seeds::NotificationEvents.new.seed! } + + let(:today) { Time.now.utc.iso8601 } + + let(:cases) do + create_list(:case, 10) do |vacols_case, i| + vacols_case.update!(bfkey: "70023000#{i}", bfcorlid: "10000010#{i}") + end + end + + let!(:appeals) do + cases.map do |vacols_case| + create(:legacy_appeal, :with_root_task, :with_veteran, vacols_case: vacols_case) + end + end + + let!(:notifications) do + appeals.each_with_index do |appeal, index| + next if [3, 7].include? index + + create(:notification, + appeals_id: appeal.vacols_id, + appeals_type: "LegacyAppeal", + event_date: Time.zone.today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: Time.zone.now - (10 - index).minutes, + email_notification_status: "delivered") + end + end + + let!(:make_appeals_outcoded) do + RootTask.find_by(appeal_id: appeals[5].id).update!(status: "completed", closed_at: 2.days.ago) + RootTask.find_by(appeal_id: appeals[6].id).update!(status: "completed", closed_at: today) + end + + let(:first_run_outcoded_appeals) { [appeals[6]] } + let(:second_run_outcoded_appeals) { [] } + let(:first_run_never_synced_appeals) { appeals.first(3) + [appeals[4]] + appeals.last(2) } + let(:second_run_never_synced_appeals) { appeals.last(2) } + let(:first_run_vbms_document_ids) { [appeals[6].id, appeals[0].id, appeals[1].id, appeals[2].id, appeals[4].id] } + let(:second_run_vbms_document_ids) { first_run_vbms_document_ids + [appeals[8].id, appeals[9].id, appeals[4].id] } + + before(:all) { LegacyNotificationEfolderSyncJob::BATCH_LIMIT = 5 } + + context "first run" do + it "get all legacy appeals that have been recently outcoded" do + expect(job.send(:appeals_recently_outcoded)).to match_array(first_run_outcoded_appeals) + end + + it "get all legacy appeals that have never been synced yet" do + expect(job.send(:appeals_never_synced)).to match_array(first_run_never_synced_appeals) + end + + it "get all legacy appeals that must be resynced" do + expect(job.send(:ready_for_resync)).to eq([]) + end + + it "running the perform" do + LegacyNotificationEfolderSyncJob.perform_now + expect(VbmsUploadedDocument.first(5).pluck(:appeal_id)).to eq(first_run_vbms_document_ids) + end + end + + context "second run" do + before do + perform_enqueued_jobs do + LegacyNotificationEfolderSyncJob.perform_now + end + RootTask.find_by(appeal_id: appeals[6].id).update!(closed_at: 25.hours.ago) + end + + it "get all legacy appeals that have been recently outcoded" do + expect(job.send(:appeals_recently_outcoded)).to match_array(second_run_outcoded_appeals) + end + + it "get all legacy appeals that have never been synced yet" do + create(:notification, + appeals_id: appeals[4].vacols_id, + appeals_type: "LegacyAppeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: 3.minutes.ago, + email_notification_status: "delivered") + create(:vbms_uploaded_document, appeal_id: appeals[4].id, appeal_type: "LegacyAppeal") + expect(job.send(:appeals_never_synced)).to match_array(second_run_never_synced_appeals) + end + + it "get all legacy appeals that must be resynced" do + create(:notification, + appeals_id: appeals[4].vacols_id, + appeals_type: "LegacyAppeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: 2.minutes.ago, + email_notification_status: "delivered") + create(:vbms_uploaded_document, appeal_id: appeals[4].id, appeal_type: "LegacyAppeal") + expect(job.send(:ready_for_resync)).to eq([appeals[4]]) + end + + it "ignore appeals that need to be resynced if latest notification status is 'Failure Due to Deceased" do + create(:notification, + appeals_id: appeals[4].vacols_id, + appeals_type: "LegacyAppeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: 1.minute.ago, + email_notification_status: "Failure Due to Deceased") + create(:vbms_uploaded_document, appeal_id: appeals[4].id, appeal_type: "LegacyAppeal") + expect(job.send(:ready_for_resync)).to eq([]) + end + + it "running the perform" do + create(:notification, + appeals_id: appeals[4].vacols_id, + appeals_type: "LegacyAppeal", + event_date: today, + event_type: "Appeal docketed", + notification_type: "Email", + notified_at: Time.zone.now, + email_notification_status: "delivered") + create(:vbms_uploaded_document, appeal_id: appeals[4].id, appeal_type: "LegacyAppeal") + + LegacyNotificationEfolderSyncJob.perform_now + + expect( + VbmsUploadedDocument + .where(document_type: "BVA Case Notifications") + .where.not("id <= 5") + .order(:id) + .pluck(:appeal_id) + ).to eq(second_run_vbms_document_ids) + end + end + end +end diff --git a/spec/jobs/notification_efolder_sync_job_spec.rb b/spec/jobs/notification_efolder_sync_job_spec.rb deleted file mode 100644 index 7c29bacd73d..00000000000 --- a/spec/jobs/notification_efolder_sync_job_spec.rb +++ /dev/null @@ -1,139 +0,0 @@ -# frozen_string_literal: true - -# * Run specs "bundle exec rspec spec/jobs/notification_efolder_sync_job_spec.rb" - -# * Get code coverage "open coverage/index.html" - -describe NotificationEfolderSyncJob do - before do - Seeds::NotificationEvents.new.seed! - end - - subject { NotificationEfolderSyncJob.new } - - let(:uuid) { appeal_one.uuid } - let(:vacols_id) { legacy_appeal_one.vacols_id } - - # * Appeals, vbms_docs and notifications - # *appeal_one, vbms_docs and notifications ** has notification is after vbms_doc ** Will be in list ** - # rubocop:disable Layout/LineLength - let(:appeal_one) { create(:appeal) } - let(:notification_one_appeal_one) { create(:notification, appeals_id: appeal_one.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-28 14:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:notification_two_appeal_one) { create(:notification, appeals_id: appeal_one.uuid, appeals_type: "Appeal", event_date: "2023-02-28 13:11:51.91467", event_type: "Hearing scheduled", notification_type: "Email" , notified_at: "2023-02-29 14:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:document_one_appeal_one) { create(:vbms_uploaded_document, document_type: "BVA Case Notifications", appeal_id: appeal_one.id, appeal_type: "Appeal", created_at: "2023-02-27 13:11:51.91467", uploaded_to_vbms_at: "2023-02-27 13:11:51.91467", attempted_at:"2023-02-27 13:11:51.91467") } - let(:document_two_appeal_one) { create(:vbms_uploaded_document, document_type: "BVA Case Notifications", appeal_id: appeal_one.id, appeal_type: "Appeal", created_at: "2023-02-28 13:11:51.91467", uploaded_to_vbms_at: "2023-02-28 13:11:51.91467", attempted_at:"2023-02-28 13:11:51.91467") } - - # *appeal_two will not have notification ** Will not be in list ** - let(:appeal_two) { create(:appeal) } - # * Legacy Appeals, vbms_docs, and notifications - # *appeal_one, vbms_docs and notifications ** has notification is after vbms_doc ** Will be in list ** - let(:legacy_appeal_one) { create(:legacy_appeal, :with_veteran, vacols_case: create(:case)) } - let(:notification_one_legacy_appeal_one) { create(:notification, appeals_id: legacy_appeal_one.vacols_id, appeals_type: "LegacyAppeal", event_date: "2023-02-28 07:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-28 07:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:notification_two_legacy_appeal_one) { create(:notification, appeals_id: legacy_appeal_one.vacols_id, appeals_type:"LegacyAppeal", event_date: "2023-02-28 09:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-28 09:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:document_one_legacy_appeal_one) { create(:vbms_uploaded_document, document_type: "BVA Case Notifications", appeal_id: legacy_appeal_one.id, appeal_type: "LegacyAppeal", created_at: "2023-02-27 13:11:51.91467", uploaded_to_vbms_at: "2023-02-27 13:11:51.91467") } - let(:document_two_legacy_appeal_one) { create(:vbms_uploaded_document, document_type: "BVA Case Notifications", appeal_id: legacy_appeal_one.id, appeal_type: "LegacyAppeal", created_at: "2023-02-28 13:11:51.91467", uploaded_to_vbms_at: "2023-02-27 13:11:51.91467") } - let(:old_notification) { create(:notification, appeals_id: appeal_one.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-27 14:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:old_document) { create(:vbms_uploaded_document, document_type: "BVA Case Notifications", appeal_id: appeal_one.id, appeal_type: "Appeal", created_at: "2023-02-27 13:11:51.91467", uploaded_to_vbms_at: "2023-02-28 14:11:51.91467", attempted_at: "2023-02-27 15:11:51.91467") } - let(:new_notification) { create(:notification, appeals_id: appeal_one.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-29 14:11:51.91467", email_notification_status: "Success", sms_notification_status: "Preferences Declined") } - let(:error_notification) { create(:notification, appeals_id: appeal_one.uuid, appeals_type: "Appeal", event_date: "2023-02-27 13:11:51.91467", event_type: "Appeal docketed", notification_type: "Email", notified_at: "2023-02-27 14:11:51.91467") } - - # rubocop:enable Layout/LineLength - - # *appeal_two will not have notification ** Will be in list ** - let(:legacy_appeal_two) { create(:legacy_appeal, :with_veteran, vacols_case: create(:case)) } - - context "Tests check_if_record_exist_in_vbms_upload_doc?(appeal) method" do - it "Returns True if vbms document is present that is associated with appeal" do - document_two_appeal_one - - is_true = subject.check_if_record_exists_in_vbms_uploaded_doc?(appeal_one) - expect(is_true).to eq(true) - end - - it "Returns False if vbms document is present that is associated with appeal" do - is_true = subject.check_if_record_exists_in_vbms_uploaded_doc?(appeal_one) - expect(is_true).to eq(false) - end - - it "Returns True if vbms document is present that is associated with legacy appeal" do - document_one_legacy_appeal_one - is_true = subject.check_if_record_exists_in_vbms_uploaded_doc?(legacy_appeal_one) - expect(is_true).to eq(true) - end - - it "Returns False if vbms document is present that is associated with legacy appeal" do - is_true = subject.check_if_record_exists_in_vbms_uploaded_doc?(legacy_appeal_one) - expect(is_true).to eq(false) - end - end - - context "Determines whether a Legacy Appeal or an AMA Appeal" do - it "If it is an AMA Appeal will return UUID" do - appeal_one - expect(subject.unique_identifier(appeal_one)).to eq(uuid) - end - - it "If it is an Legacy Appeal will return Vacols Id" do - legacy_appeal_one - expect(subject.unique_identifier(legacy_appeal_one)).to eq(vacols_id) - end - end - - context "Returns last notification associated with an appeal" do - it "Expects to get the last notification associated with an appeal" do - appeal_one - notification_one_appeal_one - notification_two_appeal_one - last_notification = subject.last_notification_of_appeal(appeal_one.uuid) - expect(last_notification).to eq(notification_two_appeal_one) - end - end - - context "Returns last uploaded document associated with an appeal or Legacy Appeal" do - it "Expects to get the last uploaded document associated with an appeal" do - appeal_one - document_one_appeal_one - document_two_appeal_one - expect(subject.latest_vbms_uploaded_document(appeal_one.id)) - .to eq(document_two_appeal_one) - end - end - - context "Tests all logic within the perform method" do - it "Expects to create only 1 VbmsUploadedDocument for appeals" do - appeal_one - appeal_two - notification_one_appeal_one - subject.perform_now - expect(VbmsUploadedDocument.count).to eq(1) - end - - it "Expects to create only 1 VbmsUploadedDocument for legacy appeals" do - legacy_appeal_one - legacy_appeal_two - notification_two_legacy_appeal_one - notification_one_legacy_appeal_one - subject.perform_now - expect(VbmsUploadedDocument.count).to eq(1) - end - - it "Expects to create no new VbmsUploadedDocuments when no new notifications" do - appeal_one - old_notification - old_document - count = VbmsUploadedDocument.count - subject.perform_now - expect(VbmsUploadedDocument.count).to eq(count) - end - - it "Expects to create 1 new VbmsSUploadedDocument when 1 appeal has new notifications" do - appeal_one - old_notification - old_document - count = VbmsUploadedDocument.count - new_notification - subject.perform_now - expect(VbmsUploadedDocument.count).to eq(count + 1) - end - end -end diff --git a/spec/jobs/update_document_in_vbms_job_spec.rb b/spec/jobs/update_document_in_vbms_job_spec.rb new file mode 100644 index 00000000000..cfd20d24d3c --- /dev/null +++ b/spec/jobs/update_document_in_vbms_job_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +describe UpdateDocumentInVbmsJob, :postgres do + describe ".perform" do + let(:document) { create(:vbms_uploaded_document) } + let(:service) { instance_double(UpdateDocumentInVbms) } + let(:user) { create(:user) } + + subject { UpdateDocumentInVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id) } + + it "calls #call on UpdateDocumentInVbms instance" do + expect(UpdateDocumentInVbms).to receive(:new).with(document: document).and_return(service) + expect(Raven).to receive(:user_context) + expect(Raven).to receive(:extra_context) + expect(service).to receive(:call) + subject + end + end +end diff --git a/spec/models/appellant_notification_spec.rb b/spec/models/appellant_notification_spec.rb index d68858ca885..53b38476b4d 100644 --- a/spec/models/appellant_notification_spec.rb +++ b/spec/models/appellant_notification_spec.rb @@ -43,6 +43,24 @@ end end + describe "veteran is deceased" do + let(:appeal) { create(:appeal, number_of_claimants: 1) } + let(:substitute_appellant) { create(:appellant_substitution) } + + it "with no substitute appellant" do + appeal.veteran.update!(date_of_death: Time.zone.today) + expect(AppellantNotification.handle_errors(appeal)[:status]).to eq "Failure Due to Deceased" + end + + it "with substitute appellant" do + appeal.veteran.update!(date_of_death: Time.zone.today) + substitute_appellant.update!(source_appeal_id: appeal.id) + substitute_appellant.send(:establish_substitution_on_same_appeal) + appeal.update!(veteran_is_not_claimant: true) + expect(AppellantNotification.handle_errors(appeal)[:status]).to eq "Success" + end + end + describe "self.create_payload" do let(:good_appeal) { create(:appeal, number_of_claimants: 1) } let(:bad_appeal) { create(:appeal) } diff --git a/spec/models/concerns/appeal_notification_report_concern_spec.rb b/spec/models/concerns/appeal_notification_report_concern_spec.rb index b909fe48619..e3792caf07d 100644 --- a/spec/models/concerns/appeal_notification_report_concern_spec.rb +++ b/spec/models/concerns/appeal_notification_report_concern_spec.rb @@ -49,7 +49,7 @@ it "VBMS upload job gets queued up" do ama_document_params[:file] = appeal.send(:notification_report) - expect { appeal.send(:upload_document, ama_document_params) }.to_not raise_error + expect { appeal.send(:upload_document) }.to_not raise_error end end @@ -71,7 +71,9 @@ end it "Error in PDF upload should throw a pdf upload error" do - expect { error_appeal.send(:upload_document, ama_document_params) } + allow(error_appeal).to receive(:document_params).and_return(ama_document_params) + + expect { error_appeal.send(:upload_document) } .to raise_error(AppealNotificationReportConcern::PDFUploadError) end end diff --git a/spec/support/shared_examples/workflows/vbms_document_transactions.rb b/spec/support/shared_examples/workflows/vbms_document_transactions.rb new file mode 100644 index 00000000000..bd0233ad6e3 --- /dev/null +++ b/spec/support/shared_examples/workflows/vbms_document_transactions.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +RSpec.shared_examples "VBMS Document Storage Location Tests" do + describe "#pdf_location" do + 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(doc_to_upload.pdf_location) + .to eq File.join(Rails.root, "tmp", "pdfs", pdf_name) + end + end + + describe "#s3_location" do + 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(doc_to_upload.send(:s3_location)).to include("notification-reports") + end + it "defaults to idt-uploaded-documents" do + expect(doc_to_upload.send(:s3_location)).to include("idt-uploaded-documents") + end + end + end + + context "#call" do + subject { doc_to_upload.call } + + before do + allow(VBMSService).to receive(transaction_method).and_call_original + end + + context "the document has already been uploaded" do + let(:uploaded_to_vbms_at) { Time.zone.now } + + it "does not reupload the document" do + subject + expect(VBMSService).to_not have_received(transaction_method) + end + end + + context "there was no upload error" do + it "uploads/updates document" do + subject + + expect(VBMSService).to have_received(transaction_method).with( + 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) + end + end + + context "when there was an upload error" do + before do + allow(VBMSService).to receive(transaction_method).and_raise("Some VBMS error") + end + + it "saves document as attempted but not processed and saves the error" do + expect { subject }.to raise_error("Some VBMS error") + + expect(document.attempted_at).to eq(Time.zone.now) + expect(document.processed_at).to be_nil + expect(document.error).to eq("Some VBMS error") + end + end + + context "the document has already been processed" do + let(:processed_at) { Time.zone.now } + + it "does not do anything" do + expect(S3Service).to_not receive(:store_file) + + subject + + expect(VBMSService).to_not have_received(transaction_method) + expect(document.submitted_at).to be_nil + expect(document.processed_at).to_not be_nil + end + end + end + + context "#cache_file" do + it "stores the file in S3" do + expected_path = "idt-uploaded-documents/veteran-#{document.veteran_file_number}-doc-#{document.id}.pdf" + + expect(S3Service).to receive(:store_file).with(expected_path, /PDF/) + + doc_to_upload.cache_file + end + end +end diff --git a/spec/workflows/update_document_in_vbms_spec.rb b/spec/workflows/update_document_in_vbms_spec.rb new file mode 100644 index 00000000000..90ad5a86540 --- /dev/null +++ b/spec/workflows/update_document_in_vbms_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +describe UpdateDocumentInVbms, :postgres do + before do + Timecop.freeze(Time.utc(2020, 1, 1, 19, 0, 0)) + end + + let(:veteran) { create(:veteran) } + let(:appeal) do + create(:appeal, number_of_claimants: 1, veteran_file_number: veteran.file_number) + end + let(:document) do + create( + :vbms_uploaded_document, + uploaded_to_vbms_at: uploaded_to_vbms_at, + veteran_file_number: appeal.veteran_file_number, + processed_at: processed_at, + file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + document_version_reference_id: "prev_ref_id" + ) + end + let(:uploaded_to_vbms_at) { nil } + let(:processed_at) { nil } + let!(:doc_to_upload) { UpdateDocumentInVbms.new(document: document) } + let(:transaction_method) { :update_document_in_vbms } + let(:upload_arg) { document.appeal } + + include_examples "VBMS Document Storage Location Tests" + + describe "#source" do + it "is hardcoded to BVA" do + 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(doc_to_upload.document_type_id).to eq 482 + end + end + + describe "#document_type" do + it "reads it from the document instance" do + 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 98754332ad7..045d40be31a 100644 --- a/spec/workflows/upload_document_to_vbms_spec.rb +++ b/spec/workflows/upload_document_to_vbms_spec.rb @@ -21,15 +21,10 @@ let(:uploaded_to_vbms_at) { nil } let(:processed_at) { nil } let!(:doc_to_upload) { UploadDocumentToVbms.new(document: document) } + let(:transaction_method) { :upload_document_to_vbms_veteran } + let(:upload_arg) { document.veteran_file_number } - describe "#pdf_location" do - 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(doc_to_upload.pdf_location) - .to eq File.join(Rails.root, "tmp", "pdfs", pdf_name) - end - end + include_examples "VBMS Document Storage Location Tests" describe "#source" do it "is hardcoded to BVA" do @@ -48,84 +43,4 @@ expect(doc_to_upload.document_type).to eq document.document_type end end - - describe "#s3_location" do - 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(doc_to_upload.send(:s3_location)).to include("notification-reports") - end - it "defaults to idt-uploaded-documents" do - expect(doc_to_upload.send(:s3_location)).to include("idt-uploaded-documents") - end - end - end - - context "#call" do - subject { doc_to_upload.call } - - before do - allow(VBMSService).to receive(:upload_document_to_vbms_veteran).and_call_original - end - - context "the document has already been uploaded" do - let(:uploaded_to_vbms_at) { Time.zone.now } - - it "does not reupload the document" do - subject - expect(VBMSService).to_not have_received(:upload_document_to_vbms_veteran) - end - end - - context "there was no upload error" do - it "uploads document" do - subject - - expect(VBMSService).to have_received(:upload_document_to_vbms_veteran).with( - document.veteran_file_number, 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) - end - end - - context "when there was an upload error" do - before do - allow(VBMSService).to receive(:upload_document_to_vbms_veteran).and_raise("Some VBMS error") - end - - it "saves document as attempted but not processed and saves the error" do - expect { subject }.to raise_error("Some VBMS error") - - expect(document.attempted_at).to eq(Time.zone.now) - expect(document.processed_at).to be_nil - expect(document.error).to eq("Some VBMS error") - end - end - - context "the document has already been processed" do - let(:processed_at) { Time.zone.now } - - it "does not do anything" do - expect(S3Service).to_not receive(:store_file) - - subject - - expect(VBMSService).to_not have_received(:upload_document_to_vbms_veteran) - expect(document.submitted_at).to be_nil - expect(document.processed_at).to_not be_nil - end - end - end - - context "#cache_file" do - it "stores the file in S3" do - expected_path = "idt-uploaded-documents/veteran-#{document.veteran_file_number}-doc-#{document.id}.pdf" - - expect(S3Service).to receive(:store_file).with(expected_path, /PDF/) - - doc_to_upload.cache_file - end - end end From 315e95b887bbad70f418f464602cdced031d3663 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 13 Jun 2023 11:36:48 -0400 Subject: [PATCH 180/308] APPEALS-21118 added to rspec --- spec/jobs/mail_request_job_spec.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 0e501df675e..15abf9d320d 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,14 +1,19 @@ # frozen_string_literal: true describe MailRequestJob do - let!(package) { VbmsCommunicationPackage.create!(comm_package_name: "Jonah", created_at: DateTime.now, updated_at: DateTime.now) } + let!(veteran) { create(:veteran) } + let!(appeal) { create(:appeal, veteran_file_number: veteran.file_number) } + let!(vbms_file) { create(:vbms_uploaded_document, appeal: appeal) } + let!(mail_request) { create(:mail_request, participant_id: veteran.participant_id) } context "successful " do - subject { MailRequestJob.perform(package) } - it "changes package status to success" do - subject - expect(package.status).to eq("success") - end - it "creates distribution" do + subject { MailRequestJob.perform(vbms_file, mail_request) } + it "creates a new VbmsCommunicationPackage" do + expect { subject }.to change { VbmsCommunicationPackage.count }.by(1) end end + context "400 error in package request" do + subject { MailRequestJob.perform(vbms_file, mail_request) } + it "does not create a new VbmsCommunicationPackage" + expect { subject }.to change { VbmsCommunicationPackage.count }.by(0) + end end From 260dbea91d1438d423159e1825347347114c4025 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 13 Jun 2023 12:02:37 -0400 Subject: [PATCH 181/308] changes made to mail_request syntax. --- app/workflows/mail_request.rb | 169 ++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 50 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 92a03c35442..7051eae2688 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -7,35 +7,10 @@ class MailRequest include MailRequestValidator::Distribution include MailRequestValidator::DistributionDestination - attr_accessor :recipient_type, :name, :first_name, :middle_name, :last_name, - :participant_id, :poa_code, :claimant_station_of_jurisdiction, :destination_type, - :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, - :address_line_6, :city, :country_code, :postal_code, :state, :treat_line_2_as_addressee, - :treat_line_3_as_addressee, :country_name, :vbms_distribution_id, :comm_package_id + attr_reader :vbms_distribution_id, :comm_package_id def initialize(recipient_and_destination_hash) - @recipient_type = recipient_and_destination_hash[:recipient_type] - @name = recipient_and_destination_hash[:name] - @first_name = recipient_and_destination_hash[:first_name] - @middle_name = recipient_and_destination_hash[:middle_name] - @last_name = recipient_and_destination_hash[:last_name] - @participant_id = recipient_and_destination_hash[:participant_id] - @poa_code = recipient_and_destination_hash[:poa_code] - @claimant_station_of_jurisdiction = recipient_and_destination_hash[:claimant_station_of_jurisdiction] - @destination_type = recipient_and_destination_hash[:destination_type] - @address_line_1 = recipient_and_destination_hash[:address_line_1] - @address_line_2 = recipient_and_destination_hash[:address_line_2] - @address_line_3 = recipient_and_destination_hash[:address_line_3] - @address_line_4 = recipient_and_destination_hash[:address_line_4] - @address_line_5 = recipient_and_destination_hash[:address_line_5] - @address_line_6 = recipient_and_destination_hash[:address_line_6] - @city = recipient_and_destination_hash[:city] - @country_code = recipient_and_destination_hash[:country_code] - @postal_code = recipient_and_destination_hash[:postal_code] - @state = recipient_and_destination_hash[:state] - @treat_line_2_as_addressee = recipient_and_destination_hash[:treat_line_2_as_addressee] - @treat_line_3_as_addressee = recipient_and_destination_hash[:treat_line_3_as_addressee] - @country_name = recipient_and_destination_hash[:country_name] + @recipient_info = recipient_and_destination_hash @vbms_distribution_id = nil @comm_package_id = nil end @@ -62,35 +37,129 @@ def create_a_vbms_distribution_destination def destination_params_parse { - destination_type: @destination_type, - address_line_1: @address_line_1, - address_line_2: @address_line_2, - address_line_3: @address_line_3, - address_line_4: @address_line_4, - address_line_5: @address_line_5, - address_line_6: @address_line_6, - city: @city, - country_code: @country_code, - postal_code: @postal_code, - state: @state, - treat_line_2_as_addressee: @treat_line_2_as_addressee, - treat_line_3_as_addressee: @treat_line_3_as_addressee, - country_name: @country_name, - vbms_distribution_id: @vbms_distribution_id + destination_type: destination_type, + address_line_1: address_line_1, + address_line_2: address_line_2, + address_line_3: address_line_3, + address_line_4: address_line_4, + address_line_5: address_line_5, + address_line_6: address_line_6, + city: city, + country_code: country_code, + postal_code: postal_code, + state: state, + treat_line_2_as_addressee: treat_line_2_as_addressee, + treat_line_3_as_addressee: treat_line_3_as_addressee, + country_name: country_name, + vbms_distribution_id: vbms_distribution_id } end def recipient_params_parse { - recipient_type: @recipient_type, - name: @name, - first_name: @first_name, - middle_name: @middle_name, - last_name: @last_name, - participant_id: @participant_id, - poa_code: @poa_code, - claimant_station_of_jurisdiction: @claimant_station_of_jurisdiction + recipient_type: recipient_type, + name: name, + first_name: first_name, + middle_name: middle_name, + last_name: last_name, + participant_id: participant_id, + poa_code: poa_code, + claimant_station_of_jurisdiction: claimant_station_of_jurisdiction } end + + def recipient_type + @recipient_info[:recipient_type] + end + + def name + @recipient_info[:name] + end + + def first_name + @recipient_info[:first_name] + end + + def middle_name + @recipient_info[:middle_name] + end + + def last_name + @recipient_info[:last_name] + end + + def participant_id + @recipient_info[:participant_id] + end + + def poa_code + @recipient_info[:poa_code] + end + + def claimant_station_of_jurisdiction + @recipient_info[:claimant_station_of_jurisdiction] + end + + def destination_type + @recipient_info[:destination_type] + end + + # :reek:UncommunicativeMethodName + def address_line_1 + @recipient_info[:address_line_1] + end + + # :reek:UncommunicativeMethodName + def address_line_2 + @recipient_info[:address_line_2] + end + + # :reek:UncommunicativeMethodName + def address_line_3 + @recipient_info[:address_line_3] + end + + # :reek:UncommunicativeMethodName + def address_line_4 + @recipient_info[:address_line_4] + end + + # :reek:UncommunicativeMethodName + def address_line_5 + @recipient_info[:address_line_5] + end + + # :reek:UncommunicativeMethodName + def address_line_6 + @recipient_info[:address_line_6] + end + + def city + @recipient_info[:city] + end + + def country_code + @recipient_info[:country_code] + end + + def postal_code + @recipient_info[:postal_code] + end + + def state + @recipient_info[:state] + end + + def treat_line_2_as_addressee + @recipient_info[:treat_line_2_as_addressee] + end + + def treat_line_3_as_addressee + @recipient_info[:treat_line_3_as_addressee] + end + + def country_name + @recipient_info[:country_name] + end end From 864c3d956d6e73af6242026f285e20b6b957c196 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 13 Jun 2023 14:01:02 -0400 Subject: [PATCH 182/308] Updated spec to account for MailRequestJob queue --- .../upload_vbms_document_controller_spec.rb | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index c4a6cac9f79..8b4a9af3de9 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -1,21 +1,24 @@ # frozen_string_literal: true RSpec.describe Idt::Api::V1::UploadVbmsDocumentController, :all_dbs, type: :controller do + include ActiveJob::TestHelper + describe "POST /idt/api/v1/appeals/:appeal_id/upload_document" do let(:user) { create(:user) } let(:appeal) { create(:appeal) } let(:veteran) { appeal.veteran } let(:file_number) { appeal.veteran.file_number } + let(:file) { "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW" } let(:valid_document_type) { "BVA Decision" } let(:params) do { appeal_id: appeal.external_id, - file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + file: file, document_type: valid_document_type } end let(:mail_request_params) do { veteran_identifier: veteran.file_number, - file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + file: file, document_type: valid_document_type, recipient_info: [ { @@ -184,7 +187,7 @@ appeal_type: appeal.class.name, veteran_file_number: file_number, document_type: params[:document_type], - file: params[:file], + file: file, document_name: nil, document_subject: nil } @@ -241,6 +244,48 @@ it_behaves_like "success_with_valid_parameters" end end + + context "queues async mail request job" do + let(:recipient_info) { mail_request_params[:recipient_info] } + let(:mail_request) { MailRequest.new(recipient_info[0]) } + let(:mail_request_job) { class_double(MailRequestJob) } + let(:mail_package) do + { distributions: [mail_request.to_json], + copies: 1 } + end + let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 1) } + let(:upload_job_params) do + { document_id: uploaded_document.id, + initiator_css_id: user.css_id, + application: nil, + mail_package: mail_package } + end + + context "document is associated with a mail package" do + it "calls #perform_later on MailRequestJob" do + post :create, params: mail_request_params, as: :json + expect(mail_request_job).to receive(:perform_later) + perform_enqueued_jobs do + UploadDocumentToVbmsJob.perform_later(upload_job_params) + end + end + end + + context "document is not associated with a mail package" do + it "does not call #perform_later on MailRequestJob" do + mail_request_params[:recipient_info] = [] + post :create, params: mail_request_params, as: :json + expect(mail_request_job).to_not receive(:perform_later) + end + end + + context "recipient info is incorrect" do + it "does not call #perform_later on MailRequestJob" do + post :create, params: invalid_mail_request_params, as: :json + expect(mail_request_job).to_not receive(:perform_later) + end + end + end end end end From 1e299ca3bab06832fa3b71b113ec110f1ac1fbac Mon Sep 17 00:00:00 2001 From: Marc Steele <71673522+msteele96@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:21:16 -0400 Subject: [PATCH 183/308] Msteele/APPEALS-22957 (#18700) * APPEALS-22957 Add version and series reference ids to vbms_uploaded_documents_audit * APPEALS-22957 Update add_row_to_comm_package function * APPEALS-22957 Fixed typos * APPEALS-22957 Updated function for add_row_to_vbms_uploaded_doc_audit * APPEALS-22957 Updated add_row_to_destination function * APPEALS-22957 Update add_row_to_vbms_distributions_audit function * APPEALS-22957 Added commands to makefile * Removed empty line * APPEALS-22957 Add back missing return value * APPEALS-22957 Update add_row_to_appeal_states_audit function * Add version and series IDs to vbms_uploaded_document factory * Make attrs more accurate --------- Co-authored-by: Matthew Thornton --- Makefile.example | 3 + ...w_to_appeal_states_audit_table_function.rb | 73 ++++++++++++++++-- ..._to_appeal_states_audit_table_function.sql | 75 +++++++++++++++++-- ...unication_packages_audit_table_function.rb | 45 ++++++++++- ...nication_packages_audit_table_function.sql | 45 ++++++++++- ...ution_destinations_audit_table_function.rb | 75 ++++++++++++++++++- ...tion_destinations_audit_table_function.sql | 75 ++++++++++++++++++- ...vbms_distributions_audit_table_function.rb | 57 +++++++++++++- ...bms_distributions_audit_table_function.sql | 57 +++++++++++++- ...uploaded_documents_audit_table_function.rb | 69 ++++++++++++++++- ...ploaded_documents_audit_table_function.sql | 71 +++++++++++++++++- .../create_vbms_uploaded_documents_audit.rb | 2 + .../create_vbms_uploaded_documents_audit.sql | 26 ++++--- spec/factories/vbms_uploaded_document.rb | 3 + 14 files changed, 628 insertions(+), 48 deletions(-) diff --git a/Makefile.example b/Makefile.example index 6dc00eb0500..6b6ac721986 100644 --- a/Makefile.example +++ b/Makefile.example @@ -155,14 +155,17 @@ audit: ## Create caseflow_audit schema, tables, and triggers in postgres bundle exec rails r db/scripts/audit/tables/create_vbms_communication_packages_audit.rb bundle exec rails r db/scripts/audit/tables/create_vbms_distributions_audit.rb bundle exec rails r db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb + bundle exec rails r db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb bundle exec rails r db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb + bundle exec rails r db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb bundle exec rails r db/scripts/audit/triggers/create_appeal_states_audit_trigger.rb bundle exec rails r db/scripts/audit/triggers/create_vbms_communication_packages_audit_trigger.rb bundle exec rails r db/scripts/audit/triggers/create_vbms_distributions_audit_trigger.rb bundle exec rails r db/scripts/audit/triggers/create_vbms_distribution_destinations_audit_trigger.rb + bundle exec rails r db/scripts/audit/triggers/create_vbms_uploaded_documents_audit_trigger.rb audit-remove: ## Remove caseflow_audit schema, tables and triggers in postgres bundle exec rails r db/scripts/audit/remove_caseflow_audit_schema.rb diff --git a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb index 34ce8582389..d729b2a7111 100644 --- a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.rb @@ -6,18 +6,81 @@ conn.execute( "create or replace function caseflow_audit.add_row_to_appeal_states_audit() returns trigger as - $appeal_states_audit$ + $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.appeal_cancelled, + OLD.appeal_docketed, + OLD.appeal_id, + OLD.appeal_type, + OLD.created_at, + OLD.created_by_id, + OLD.decision_mailed, + OLD.hearing_postponed, + OLD.hearing_scheduled, + OLD.hearing_withdrawn, + OLD.privacy_act_complete, + OLD.privacy_act_pending, + OLD.scheduled_in_error, + OLD.updated_at, + OLD.updated_by_id, + OLD.vso_ihp_complete, + OLD.vso_ihp_pending; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.appeal_cancelled, + NEW.appeal_docketed, + NEW.appeal_id, + NEW.appeal_type, + NEW.created_at, + NEW.created_by_id, + NEW.decision_mailed, + NEW.hearing_postponed, + NEW.hearing_scheduled, + NEW.hearing_withdrawn, + NEW.privacy_act_complete, + NEW.privacy_act_pending, + NEW.scheduled_in_error, + NEW.updated_at, + NEW.updated_by_id, + NEW.vso_ihp_complete, + NEW.vso_ihp_pending; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.appeal_cancelled, + NEW.appeal_docketed, + NEW.appeal_id, + NEW.appeal_type, + NEW.created_at, + NEW.created_by_id, + NEW.decision_mailed, + NEW.hearing_postponed, + NEW.hearing_scheduled, + NEW.hearing_withdrawn, + NEW.privacy_act_complete, + NEW.privacy_act_pending, + NEW.scheduled_in_error, + NEW.updated_at, + NEW.updated_by_id, + NEW.vso_ihp_complete, + NEW.vso_ihp_pending; end if; return null; end; - $appeal_states_audit$ + $add_row$ language plpgsql;" ) conn.close diff --git a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql index d3cb5a534d5..22c40f0218d 100644 --- a/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_appeal_states_audit_table_function.sql @@ -1,15 +1,78 @@ create or replace function caseflow_audit.add_row_to_appeal_states_audit() returns trigger as -$appeal_states_audit$ +$add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.appeal_cancelled, + OLD.appeal_docketed, + OLD.appeal_id, + OLD.appeal_type, + OLD.created_at, + OLD.created_by_id, + OLD.decision_mailed, + OLD.hearing_postponed, + OLD.hearing_scheduled, + OLD.hearing_withdrawn, + OLD.privacy_act_complete, + OLD.privacy_act_pending, + OLD.scheduled_in_error, + OLD.updated_at, + OLD.updated_by_id, + OLD.vso_ihp_complete, + OLD.vso_ihp_pending; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.appeal_cancelled, + NEW.appeal_docketed, + NEW.appeal_id, + NEW.appeal_type, + NEW.created_at, + NEW.created_by_id, + NEW.decision_mailed, + NEW.hearing_postponed, + NEW.hearing_scheduled, + NEW.hearing_withdrawn, + NEW.privacy_act_complete, + NEW.privacy_act_pending, + NEW.scheduled_in_error, + NEW.updated_at, + NEW.updated_by_id, + NEW.vso_ihp_complete, + NEW.vso_ihp_pending; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.appeal_states_audit select nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.appeal_states_audit + select + nextval('caseflow_audit.appeal_states_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.appeal_cancelled, + NEW.appeal_docketed, + NEW.appeal_id, + NEW.appeal_type, + NEW.created_at, + NEW.created_by_id, + NEW.decision_mailed, + NEW.hearing_postponed, + NEW.hearing_scheduled, + NEW.hearing_withdrawn, + NEW.privacy_act_complete, + NEW.privacy_act_pending, + NEW.scheduled_in_error, + NEW.updated_at, + NEW.updated_by_id, + NEW.vso_ihp_complete, + NEW.vso_ihp_pending; end if; return null; end; -$appeal_states_audit$ -language plpgsql; \ No newline at end of file +$add_row$ +language plpgsql; diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index df370785325..babea94245e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -9,11 +9,50 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.file_number, + OLD.copies, + OLD.status, + OLD.comm_package_name, + OLD.created_at, + OLD.updated_at, + OLD.vbms_uploaded_document_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.file_number, + NEW.copies, + NEW.status, + NEW.comm_package_name, + NEW.created_at, + NEW.updated_at, + NEW.vbms_uploaded_document_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.file_number, + NEW.copies, + NEW.status, + NEW.comm_package_name, + NEW.created_at, + NEW.updated_at, + NEW.vbms_uploaded_document_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index c47a1a498fb..379b8d26a87 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -3,11 +3,50 @@ as $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.file_number, + OLD.copies, + OLD.status, + OLD.comm_package_name, + OLD.created_at, + OLD.updated_at, + OLD.vbms_uploaded_document_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.file_number, + NEW.copies, + NEW.status, + NEW.comm_package_name, + NEW.created_at, + NEW.updated_at, + NEW.vbms_uploaded_document_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_communication_packages_audit select nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_communication_packages_audit + select + nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.file_number, + NEW.copies, + NEW.status, + NEW.comm_package_name, + NEW.created_at, + NEW.updated_at, + NEW.vbms_uploaded_document_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index a2e69fb7fce..b84153084ef 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -9,11 +9,80 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.destination_type, + OLD.address_line_1, + OLD.address_line_2, + OLD.address_line_3, + OLD.address_line_4, + OLD.address_line_5, + OLD.address_line_6, + OLD.treat_line_2_as_addressee, + OLD.treat_line_3_as_addressee, + OLD.city, + OLD.state, + OLD.postal_code, + OLD.country_name, + OLD.country_code, + OLD.created_at, + OLD.updated_at, + OLD.vbms_distribution_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.destination_type, + NEW.address_line_1, + NEW.address_line_2, + NEW.address_line_3, + NEW.address_line_4, + NEW.address_line_5, + NEW.address_line_6, + NEW.treat_line_2_as_addressee, + NEW.treat_line_3_as_addressee, + NEW.city, + NEW.state, + NEW.postal_code, + NEW.country_name, + NEW.country_code, + NEW.created_at, + NEW.updated_at, + NEW.vbms_distribution_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.destination_type, + NEW.address_line_1, + NEW.address_line_2, + NEW.address_line_3, + NEW.address_line_4, + NEW.address_line_5, + NEW.address_line_6, + NEW.treat_line_2_as_addressee, + NEW.treat_line_3_as_addressee, + NEW.city, + NEW.state, + NEW.postal_code, + NEW.country_name, + NEW.country_code, + NEW.created_at, + NEW.updated_at, + NEW.vbms_distribution_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index fd5922c5872..6c8f9b1aa9e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -3,11 +3,80 @@ as $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.destination_type, + OLD.address_line_1, + OLD.address_line_2, + OLD.address_line_3, + OLD.address_line_4, + OLD.address_line_5, + OLD.address_line_6, + OLD.treat_line_2_as_addressee, + OLD.treat_line_3_as_addressee, + OLD.city, + OLD.state, + OLD.postal_code, + OLD.country_name, + OLD.country_code, + OLD.created_at, + OLD.updated_at, + OLD.vbms_distribution_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.destination_type, + NEW.address_line_1, + NEW.address_line_2, + NEW.address_line_3, + NEW.address_line_4, + NEW.address_line_5, + NEW.address_line_6, + NEW.treat_line_2_as_addressee, + NEW.treat_line_3_as_addressee, + NEW.city, + NEW.state, + NEW.postal_code, + NEW.country_name, + NEW.country_code, + NEW.created_at, + NEW.updated_at, + NEW.vbms_distribution_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distribution_destinations_audit select nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distribution_destinations_audit + select + nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.destination_type, + NEW.address_line_1, + NEW.address_line_2, + NEW.address_line_3, + NEW.address_line_4, + NEW.address_line_5, + NEW.address_line_6, + NEW.treat_line_2_as_addressee, + NEW.treat_line_3_as_addressee, + NEW.city, + NEW.state, + NEW.postal_code, + NEW.country_name, + NEW.country_code, + NEW.created_at, + NEW.updated_at, + NEW.vbms_distribution_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 19d015d4162..26276c72561 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -9,11 +9,62 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.recipient_type, + OLD.name, + OLD.first_name, + OLD.middle_name, + OLD.last_name, + OLD.participant_id, + OLD.poa_code, + OLD.claimant_station_of_jurisdiction, + OLD.created_at, + OLD.updated_at, + OLD.vbms_communication_package_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.recipient_type, + NEW.name, + NEW.first_name, + NEW.middle_name, + NEW.last_name, + NEW.participant_id, + NEW.poa_code, + NEW.claimant_station_of_jurisdiction, + NEW.created_at, + NEW.updated_at, + NEW.vbms_communication_package_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.recipient_type, + NEW.name, + NEW.first_name, + NEW.middle_name, + NEW.last_name, + NEW.participant_id, + NEW.poa_code, + NEW.claimant_station_of_jurisdiction, + NEW.created_at, + NEW.updated_at, + NEW.vbms_communication_package_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 5c5baaf75f2..95dbc63bd40 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -3,11 +3,62 @@ as $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.recipient_type, + OLD.name, + OLD.first_name, + OLD.middle_name, + OLD.last_name, + OLD.participant_id, + OLD.poa_code, + OLD.claimant_station_of_jurisdiction, + OLD.created_at, + OLD.updated_at, + OLD.vbms_communication_package_id, + OLD.created_by_id, + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.recipient_type, + NEW.name, + NEW.first_name, + NEW.middle_name, + NEW.last_name, + NEW.participant_id, + NEW.poa_code, + NEW.claimant_station_of_jurisdiction, + NEW.created_at, + NEW.updated_at, + NEW.vbms_communication_package_id, + NEW.created_by_id, + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_distributions_audit + select + nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.recipient_type, + NEW.name, + NEW.first_name, + NEW.middle_name, + NEW.last_name, + NEW.participant_id, + NEW.poa_code, + NEW.claimant_station_of_jurisdiction, + NEW.created_at, + NEW.updated_at, + NEW.vbms_communication_package_id, + NEW.created_by_id, + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb index b59a54de15e..1b13c9a74f4 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.rb @@ -9,11 +9,74 @@ $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.appeal_id, + OLD.appeal_type, + OLD.attempted_at, + OLD.canceled_at, + OLD.created_at, + OLD.document_name, + OLD.document_series_reference_id, + OLD.document_subject, + OLD.document_type, + OLD.document_version_reference_id, + OLD.error, + OLD.last_submitted_at, + OLD.processed_at, + OLD.submitted_at, + OLD.updated_at, + OLD.uploaded_to_vbms_at, + OLD.veteran_file_number; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.appeal_id, + NEW.appeal_type, + NEW.attempted_at, + NEW.canceled_at, + NEW.created_at, + NEW.document_name, + NEW.document_series_reference_id, + NEW.document_subject, + NEW.document_type, + NEW.document_version_reference_id, + NEW.error, + NEW.last_submitted_at, + NEW.processed_at, + NEW.submitted_at, + NEW.updated_at, + NEW.uploaded_to_vbms_at, + NEW.veteran_file_number; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_uploaded_documents_audit select nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.appeal_id, + NEW.appeal_type, + NEW.attempted_at, + NEW.canceled_at, + NEW.created_at, + NEW.document_name, + NEW.document_series_reference_id, + NEW.document_subject, + NEW.document_type, + NEW.document_version_reference_id, + NEW.error, + NEW.last_submitted_at, + NEW.processed_at, + NEW.submitted_at, + NEW.updated_at, + NEW.uploaded_to_vbms_at, + NEW.veteran_file_number; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql index 5c5baaf75f2..2b366270a34 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_uploaded_documents_audit_table_function.sql @@ -1,13 +1,76 @@ -create or replace function caseflow_audit.add_row_to_vbms_distributions_audit() returns trigger +create or replace function caseflow_audit.add_row_to_vbms_uploaded_documents_audit() returns trigger as $add_row$ begin if (TG_OP = 'DELETE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'D', + OLD.id, + OLD.appeal_id, + OLD.appeal_type, + OLD.attempted_at, + OLD.canceled_at, + OLD.created_at, + OLD.document_name, + OLD.document_series_reference_id, + OLD.document_subject, + OLD.document_type, + OLD.document_version_reference_id, + OLD.error, + OLD.last_submitted_at, + OLD.processed_at, + OLD.submitted_at, + OLD.updated_at, + OLD.uploaded_to_vbms_at, + OLD.veteran_file_number; elsif (TG_OP = 'UPDATE') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'U', + NEW.id, + NEW.appeal_id, + NEW.appeal_type, + NEW.attempted_at, + NEW.canceled_at, + NEW.created_at, + NEW.document_name, + NEW.document_series_reference_id, + NEW.document_subject, + NEW.document_type, + NEW.document_version_reference_id, + NEW.error, + NEW.last_submitted_at, + NEW.processed_at, + NEW.submitted_at, + NEW.updated_at, + NEW.uploaded_to_vbms_at, + NEW.veteran_file_number; elsif (TG_OP = 'INSERT') then - insert into caseflow_audit.vbms_distributions_audit select nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.*; + insert into caseflow_audit.vbms_uploaded_documents_audit + select + nextval('caseflow_audit.vbms_uploaded_documents_audit_id_seq'::regclass), + 'I', + NEW.id, + NEW.appeal_id, + NEW.appeal_type, + NEW.attempted_at, + NEW.canceled_at, + NEW.created_at, + NEW.document_name, + NEW.document_series_reference_id, + NEW.document_subject, + NEW.document_type, + NEW.document_version_reference_id, + NEW.error, + NEW.last_submitted_at, + NEW.processed_at, + NEW.submitted_at, + NEW.updated_at, + NEW.uploaded_to_vbms_at, + NEW.veteran_file_number; end if; return null; end; diff --git a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb index 511b1da5da8..34d53368952 100644 --- a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb +++ b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.rb @@ -13,8 +13,10 @@ canceled_at timestamp NULL, created_at timestamp NOT NULL, document_name varchar NULL, + document_series_reference_id varchar NULL, document_subject varchar NULL, document_type varchar NOT NULL, + document_version_reference_id varchar NULL, error varchar NULL, last_submitted_at timestamp NULL, processed_at timestamp NULL, diff --git a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql index abc025d620d..8c467e9851d 100644 --- a/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql +++ b/db/scripts/audit/tables/create_vbms_uploaded_documents_audit.sql @@ -2,19 +2,21 @@ create table caseflow_audit.vbms_uploaded_documents_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_uploaded_documents_id bigint not null, - appeal_id int8, - appeal_type varchar, - attempted_at timestamp, - canceled_at timestamp, + appeal_id int8 NULL, + appeal_type varchar NULL, + attempted_at timestamp NULL, + canceled_at timestamp NULL, created_at timestamp NOT NULL, - document_name varchar, - document_subject varchar, + document_name varchar NULL, + document_series_reference_id varchar NULL, + document_subject varchar NULL, document_type varchar NOT NULL, - error varchar, - last_submitted_at timestamp, - processed_at timestamp, - submitted_at timestamp, + document_version_reference_id varchar NULL, + error varchar NULL, + last_submitted_at timestamp NULL, + processed_at timestamp NULL, + submitted_at timestamp NULL, updated_at timestamp NOT NULL, - uploaded_to_vbms_at timestamp, - veteran_file_number varchar + uploaded_to_vbms_at timestamp NULL, + veteran_file_number varchar NULL ); diff --git a/spec/factories/vbms_uploaded_document.rb b/spec/factories/vbms_uploaded_document.rb index f6e10724896..3a2ef598365 100644 --- a/spec/factories/vbms_uploaded_document.rb +++ b/spec/factories/vbms_uploaded_document.rb @@ -6,6 +6,9 @@ document_type { "Status Letter" } appeal { create(:appeal) } + document_version_reference_id { "{#{SecureRandom.uuid.upcase}}" } + document_series_reference_id { "{#{SecureRandom.uuid.upcase}}" } + trait :for_legacy_appeal do appeal { create(:legacy_appeal, vacols_case: create(:case)) } end From a71adc78e1260ef689a21f660ce9996805f105c7 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 14 Jun 2023 12:37:25 -0400 Subject: [PATCH 184/308] Oops --- .rubocop.yml | 4 ++++ app/controllers/idt/api/v1/base_controller.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 7ef1e76199f..8a486b6dcc0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -72,6 +72,10 @@ Rails/LexicallyScopedActionFilter: Rails/SkipsModelValidations: Enabled: false +Rails/ApplicationController: + Exclude: + - app/controllers/idt/api/v1/base_controller.rb + Rails/FilePath: Enabled: false diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 3318aabe7b1..ec3819253c8 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Idt::Api::V1::BaseController < ApplicationController +class Idt::Api::V1::BaseController < ActionController::Base include AuthenticatedControllerAction protect_from_forgery with: :exception From 58ed178e8a910c9de3ef3f19a7a8df043a8869ab Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Fri, 16 Jun 2023 16:15:43 -0400 Subject: [PATCH 185/308] updated mail_request method to set the created_by_id attribute of a created vbms_distribution at the time of creation. --- app/workflows/mail_request.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb index 7051eae2688..81da60840b4 100644 --- a/app/workflows/mail_request.rb +++ b/app/workflows/mail_request.rb @@ -9,12 +9,24 @@ class MailRequest attr_reader :vbms_distribution_id, :comm_package_id + # Purpose: initializes a mail_request object making use of the passed in hash and also initializing + # the attributes of vbms_distribution_id and a comm_package_id. Both set to nil until set + # otherwise. + # + # Params: recipient_and_destination_hash - expected parameters that that hold information + # that will be used to create a valid VbmsDistribution and valid VbmsDistributionDestination. + # + # Return: nil def initialize(recipient_and_destination_hash) @recipient_info = recipient_and_destination_hash @vbms_distribution_id = nil @comm_package_id = nil end + # Purpose: With the passed in parameters, the call method creates both a valid VBMSDistribution and + # valid VBMSDistributionDestination. If there is an error it will fail and that information will be provided + # to the IDT user. + # def call if valid? distribution = create_a_vbms_distribution @@ -52,7 +64,6 @@ def destination_params_parse treat_line_3_as_addressee: treat_line_3_as_addressee, country_name: country_name, vbms_distribution_id: vbms_distribution_id - } end @@ -65,7 +76,8 @@ def recipient_params_parse last_name: last_name, participant_id: participant_id, poa_code: poa_code, - claimant_station_of_jurisdiction: claimant_station_of_jurisdiction + claimant_station_of_jurisdiction: claimant_station_of_jurisdiction, + created_by_id: RequestStore[:current_user].id } end From 18d5474d7498eecda1c294c1dc002f0d831a7dc8 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 20 Jun 2023 09:44:40 -0400 Subject: [PATCH 186/308] APPEALS-21118 updated mail_request usage --- app/jobs/mail_request_job.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 062a4417230..dea3b6321d2 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -15,8 +15,6 @@ def perform(vbms_uploaded_document, mail_request) vbms_comm_package.document_referenced) log_info(package_response) vbms_comm_package = create_package(vbms_uploaded_document, mail_request) -# FIXME what do we want when the response is an error? -# should a VbmsCommunicationPackage object still be created? if package_response.code == 201 vbms_comm_package.update!(status: "success") create_distribution_request(vbms_comm_package.id, mail_request) @@ -33,30 +31,33 @@ def perform(vbms_uploaded_document, mail_request) # takes in VbmsUploadedDocument object and MailRequest object # # Response: new VbmsCommunicationPackage object -# FIXME how to get created_by_id def create_package(vbms_uploaded_document, mail_request) VbmsCommunicationPackage.new( - comm_package_name: mail_request.name, + comm_package_name: get_package_name(vbms_uploaded_document), created_at: Time.zone.now, - created_by_id: "", - copies: nil, - file_number: vbms_uploaded_document.veteran_file_number, + created_by_id: mail_request["distributions"][0]["created_by_id"], + copies: mail_request["distributions"]["copies"], + file_number: mail_request["distributions"][0]["veteranFileNumber"], status: nil, updated_at: Time.zone.now, - updated_by_id: " ", + updated_by_id: mail_request["distributions"][0]["created_by_id"], vbms_uploaded_document_id: vbms_uploaded_document.id ) end + def get_package_name(vbms_uploaded_document) + "#{vbms_uploaded_document.document_name}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" + end + # Purpose: sends distribution POST request to Pacman API # # takes in VbmsCommunicationPackage id (string) and MailRequest object # # Response: n/a def create_distribution_request(package_id, mail_request) - distributions = VbmsDistribution.find(participant_id: mail_request.participant_id) + distributions = mail_request["distributions"] distributions.each do |dist| - distribution_destination = VbmsDistributionDestination.find(vbms_distribution_id: dist.id) + distribution_destination = VbmsDistributionDestination.find(vbms_distribution_id: dist["id"]) distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, get_recipient_hash(distribution), get_destinations_hash(distribution_destination)) From e5307f048955704668e84b3757329349cbbe3a6a Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 20 Jun 2023 11:05:44 -0400 Subject: [PATCH 187/308] Created MailPackageConcern and refactored controller to implement concern --- .../concerns/mail_package_concern.rb | 76 +++++++++++++++++++ .../api/v1/upload_vbms_document_controller.rb | 66 +--------------- 2 files changed, 77 insertions(+), 65 deletions(-) create mode 100644 app/controllers/concerns/mail_package_concern.rb diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb new file mode 100644 index 00000000000..84bbfa685ad --- /dev/null +++ b/app/controllers/concerns/mail_package_concern.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +# shared code for building mail packages to submit to Package Manager external service + +module MailPackageConcern + extend ActiveSupport::Concern + + included do + def recipient_info + params[:recipient_info] + end + + def build_mail_package + return if recipient_info.blank? + + throw_error_if_copies_out_of_range + # Create and validate MailRequest objects, save to db, and store distribution IDs + mail_requests.map do |request| + request.call + distribution_ids << request.vbms_distribution_id + end + end + end + + private + + def copies + # Default value of 1 for copies + return 1 if params[:copies].blank? + + params[:copies] + end + + # Payload with distributions value (array of JSON-formatted MailRequest objects) and copies (integer) + def mail_package + return nil if recipient_info.blank? + + { distributions: mail_requests.to_json, copies: copies } + end + + def mail_requests + @mail_requests ||= create_mail_requests_and_track_errors + end + + def create_mail_requests_and_track_errors + requests = recipient_info.map.with_index do |recipient, idx| + MailRequest.new(recipient).tap do |request| + if request.invalid? + recipient_errors["distribution #{idx + 1}"] = request.errors.full_messages.join(", ") + end + end + end + throw_error_if_recipient_info_invalid + requests + end + + def throw_error_if_copies_out_of_range + unless (1..500).cover?(copies) + fail Caseflow::Error::MissingRecipientInfo, "Copies must be between 1 and 500 (inclusive)".to_json + end + end + + def throw_error_if_recipient_info_invalid + return unless recipient_errors.any? + + fail Caseflow::Error::MissingRecipientInfo, recipient_errors.to_json + end + + def recipient_errors + @recipient_errors ||= {} + end + + def distribution_ids + @distribution_ids ||= [] + end +end diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index af42eca3a8a..8721944e6ca 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -2,6 +2,7 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController include ApiRequestLoggingConcern + include MailPackageConcern protect_from_forgery with: :exception skip_before_action :verify_authenticity_token, only: [:create] @@ -25,71 +26,6 @@ def create private - def recipient_info - params[:recipient_info] - end - - def copies - # Default value of 1 for copies - return 1 if params[:copies].blank? - - params[:copies] - end - - # Payload with distributions value (array of JSON-formatted MailRequest objects) and copies (integer) - def mail_package - return nil if recipient_info.blank? - - { distributions: mail_requests.to_json, copies: copies } - end - - def build_mail_package - return if recipient_info.blank? - - throw_error_if_copies_out_of_range - # Create and validate MailRequest objects, save to db, and store distribution IDs - mail_requests.map do |request| - request.call - distribution_ids << request.vbms_distribution_id - end - end - - def mail_requests - @mail_requests ||= create_mail_requests_and_track_errors - end - - def create_mail_requests_and_track_errors - requests = recipient_info.map.with_index do |recipient, idx| - MailRequest.new(recipient).tap do |request| - if request.invalid? - recipient_errors["distribution #{idx + 1}"] = request.errors.full_messages.join(", ") - end - end - end - throw_error_if_recipient_info_invalid - requests - end - - def throw_error_if_copies_out_of_range - unless (1..500).cover?(copies) - fail Caseflow::Error::MissingRecipientInfo, "Copies must be between 1 and 500 (inclusive)".to_json - end - end - - def throw_error_if_recipient_info_invalid - return unless recipient_errors.any? - - fail Caseflow::Error::MissingRecipientInfo, recipient_errors.to_json - end - - def recipient_errors - @recipient_errors ||= {} - end - - def distribution_ids - @distribution_ids ||= [] - end - # Find veteran from appeal id and check with db def appeal if appeal_id.blank? From 6e2eadd420adc0c37f0fbd864de55e5f9abc82ae Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 20 Jun 2023 15:53:44 -0400 Subject: [PATCH 188/308] Updated spec files to reflect introduction of MailRequestJob --- .../idt/api/v1/upload_vbms_document_controller_spec.rb | 7 +++---- spec/jobs/upload_document_to_vbms_job_spec.rb | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 8b4a9af3de9..37cb41dd346 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -248,7 +248,6 @@ context "queues async mail request job" do let(:recipient_info) { mail_request_params[:recipient_info] } let(:mail_request) { MailRequest.new(recipient_info[0]) } - let(:mail_request_job) { class_double(MailRequestJob) } let(:mail_package) do { distributions: [mail_request.to_json], copies: 1 } @@ -264,7 +263,7 @@ context "document is associated with a mail package" do it "calls #perform_later on MailRequestJob" do post :create, params: mail_request_params, as: :json - expect(mail_request_job).to receive(:perform_later) + expect(MailRequestJob).to receive(:perform_later) perform_enqueued_jobs do UploadDocumentToVbmsJob.perform_later(upload_job_params) end @@ -275,14 +274,14 @@ it "does not call #perform_later on MailRequestJob" do mail_request_params[:recipient_info] = [] post :create, params: mail_request_params, as: :json - expect(mail_request_job).to_not receive(:perform_later) + expect(MailRequestJob).to_not receive(:perform_later) end end context "recipient info is incorrect" do it "does not call #perform_later on MailRequestJob" do post :create, params: invalid_mail_request_params, as: :json - expect(mail_request_job).to_not receive(:perform_later) + expect(MailRequestJob).to_not receive(:perform_later) end end end diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 1bffc6fc055..8a55084e187 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -10,7 +10,6 @@ { distributions: [mail_request.to_json], copies: 1 } end - let(:mail_request_job) { class_double(MailRequestJob) } let(:params) do { document_id: document.id, @@ -30,7 +29,7 @@ context "document is associated with a mail package" do it "calls #perform_later on MailRequestJob" do - expect(mail_request_job).to receive(:perform_later).with(document, mail_package) + expect(MailRequestJob).to receive(:perform_later).with(document, mail_package) subject end end @@ -38,7 +37,7 @@ context "document is not associated with a mail package" do let(:mail_package) { nil } it "does not call #perform_later on MailRequestJob" do - expect(mail_request_job).to_not receive(:perform_later) + expect(MailRequestJob).to_not receive(:perform_later) subject end end @@ -46,7 +45,7 @@ context "document is not successfully uploaded to vbms" do it "does not call #perform_later on MailRequestJob" do allow(VBMSService).to receive(:upload_document_to_vbms_veteran).and_raise(StandardError) - expect(mail_request_job).to_not receive(:perform_later) + expect(MailRequestJob).to_not receive(:perform_later) expect { subject }.to raise_error(StandardError) end end From 2184b655320f8ad6546d86193254f6499e3e0fd7 Mon Sep 17 00:00:00 2001 From: breedbah <123968373+breedbah@users.noreply.github.com> Date: Tue, 20 Jun 2023 17:39:41 -0400 Subject: [PATCH 189/308] b_reed/APPEALS-22837 (#18709) * start of distribution controller * rest of distributiion controller and rout * updated controller name * get distribution status * final pacman status changes * Completed r-specs and tested code * Added comments to code * Updated rubocop linting errors * updated response conversion * removed openstruct * new changes * r-spec and api request update * Updated changes and unit tests * linting error and spec updates * Updated error handling unit tests * updated render error test * update * updated 404 test and removed uuid from test --------- Co-authored-by: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Co-authored-by: Matthew Thornton --- .../idt/api/v2/distributions_controller.rb | 66 +++++++ config/routes.rb | 1 + lib/fakes/pacman_service.rb | 128 ++++++++++++ .../api/v2/distributions_controller_spec.rb | 183 ++++++++++++++++++ 4 files changed, 378 insertions(+) create mode 100644 app/controllers/idt/api/v2/distributions_controller.rb create mode 100644 lib/fakes/pacman_service.rb create mode 100644 spec/controllers/idt/api/v2/distributions_controller_spec.rb diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb new file mode 100644 index 00000000000..c0d9182974f --- /dev/null +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +class Idt::Api::V2::DistributionsController < Idt::Api::V1::BaseController + protect_from_forgery with: :exception + before_action :verify_access + + # rubocop:disable Metrics/MethodLength, Naming/AccessorMethodName + def get_distribution + # rubocop:enable Metrics/MethodLength, Naming/AccessorMethodName + distribution_id = params[:distribution_id] + # Checks if the distribution id is blank and if it exists with the database + if distribution_id.blank? || !valid_id?(distribution_id) + render_error(400, "Distribution Does Not Exist Or Id is blank", distribution_id) + return + end + + begin + # Retrieves the distribution package from the PacMan API + distribution = PacManService.get_distribution_request(distribution_id) + response_code = distribution.code + if response_code != 200 + fail StandardError + end + # Handles errors when making any requests both from Pacman and the DB + rescue StandardError + case response_code + when 404 + pending_establishment(distribution_id) + else + render_error(response_code, "Internal Server Error", distribution_id) + end + return + end + + render json: format_response(distribution) + end + + def pending_establishment(distribution_id) + render json: { id: distribution_id, status: "PENDING_ESTABLISHMENT" }, status: :ok + end + + def format_response(response) + new_response = response.raw_body.to_json + parsed_response = JSON.parse(new_response) + # Convert keys from camelCase to snake_case + parsed_response.deep_transform_keys do |key| + key.to_s.underscore.gsub(/e(\d)/, 'e_\1') + end + end + + private + + # Checks if the distribution exists in the database before sending request to PacMan + def valid_id?(distribution_id) + VbmsDistribution.exists?(id: distribution_id) + end + + # Renders errors and logs and tracks the here within Raven + def render_error(status, message, distribution_id) + error_uuid = SecureRandom.uuid + error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" + Rails.logger.error(error_message.to_s + "Error ID: " + error_uuid) + Raven.capture_exception(error_message, extra: { error_uuid: error_uuid }) + render json: { message: error_message + " #{error_uuid}" }, status: status + end +end diff --git a/config/routes.rb b/config/routes.rb index b3390b552a2..248e4082a02 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,7 @@ post 'appeals/:appeal_id/outcode', to: 'appeals#outcode' get 'appeals/:appeal_id/documents', to: 'appeals#appeal_documents' get 'appeals/:appeal_id/documents/:document_id', to: 'appeals#appeals_single_document' + get 'distributions/:distribution_id', to: 'distributions#get_distribution' end end end diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb new file mode 100644 index 00000000000..395e8090743 --- /dev/null +++ b/lib/fakes/pacman_service.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +class Fakes::PacmanService < ExternalApi::PacmanService + class << self + def send_communication_package_request(file_number, name, document_references) + fake_package_request(file_number, name, document_references) + end + + def send_distribution_request(package_id, recipient, destinations) + fake_distribution_request(package_id, recipient, destinations) + end + + def get_distribution_request(distribution_id) + unless VbmsDistribution.exists?(id: distribution_id) + distribution_not_found_response + end + + fake_distribution_response(distribution_id) + end + + private + + def bad_request_response + HTTPI::Response.new( + 400, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "participant id is not valid" + ) + ) + end + + def bad_access_response + HTTPI::Response.new( + 403, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "package cannot be created because of insufficient privileges" + ) + ) + end + + def distribution_not_found_response + HTTPI::Response.new( + 404, + {}, + OpenStruct.new( + "error": "BadRequestError", + "message": "distribution does not exist at this time" + ) + ) + end + + # POST: /package-manager-service/communication-package + def fake_package_request(file_number, name, document_references) + HTTPI::Response.new( + 201, + {}, + OpenStruct.new( + "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", + "fileNumber": file_number, + "name": name, + "documentReferences": document_references, + "status": "NEW", + "createDate": "" + ) + ) + end + + # rubocop:disable Metrics/MethodLength + # POST: /package-manager-service/distribution + def fake_distribution_request(package_id, recipient, destinations) + HTTPI::Response.new( + 201, + {}, + OpenStruct.new( + "id": "12345", + "recipient": recipient, + "description": "bad", + "communicationPackageId": package_id, + "destinations": destinations, + "status": "", + "sentToCbcmDate": "" + ) + ) + end + + # GET: /package-manager-service/distribution/{id} + def fake_distribution_response(distribution_id) + HTTPI::Response.new( + 200, + {}, + "id": distribution_id, + "recipient": { + "type": "system", + "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name": "VBMS-C" + }, + "description": "Staging Mailing Distribution", + "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations": [{ + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": "", + "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", + "addressLine1": "POSTMASTER GENERAL", + "addressLine2": "UNITED STATES POSTAL SERVICE", + "addressLine3": "475 LENFANT PLZ SW RM 10022", + "addressLine4": "SUITE 123", + "addressLine5": "APO AE 09001-5275", + "addressLine6": "", + "treatLine2AsAddressee": true, + "treatLine3AsAddressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postalCode": "12345", + "countryName": "UNITED STATES", + "countryCode": "us" + }], + "status": "", + "sentToCbcmDate": "" + ) + end + # rubocop:enable Metrics/MethodLength + end +end diff --git a/spec/controllers/idt/api/v2/distributions_controller_spec.rb b/spec/controllers/idt/api/v2/distributions_controller_spec.rb new file mode 100644 index 00000000000..e70abf92042 --- /dev/null +++ b/spec/controllers/idt/api/v2/distributions_controller_spec.rb @@ -0,0 +1,183 @@ +# frozen_string_literal: true + +require "rails_helper" + +# This is the command to run rspec in the console +# bundle exec rspec spec/controllers/idt/api/v2/distributions_controller_spec.rb + +# Here is where you look at code coverage +# open coverage/index.html + +RSpec.describe Idt::Api::V2::DistributionsController, type: :controller do + describe "#get_distribution" do + let(:user) { create(:user) } + let(:distribution_id) { 123_456 } + let(:appeal) { create(:appeal, :at_attorney_drafting) } + let(:distribution) { create(:distribution, judge: JudgeTask.find_by(appeal: appeal).assigned_to) } + let(:uuid) { "a9df0251-8350-464b-9aa4-a7d56a8ac173" } + + before do + allow(controller).to receive(:params).and_return(distribution_id: distribution_id) + allow(VbmsDistribution).to receive(:exists?).with(id: distribution_id).and_return(true) + allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + allow(SecureRandom).to receive(:uuid).and_return(uuid) + key, t = Idt::Token.generate_one_time_key_and_proposed_token + Idt::Token.activate_proposed_token(key, user.css_id) + request.headers["TOKEN"] = t + create(:staff, :attorney_role, sdomainid: user.css_id) + end + + context "when distribution_id is blank or invalid" do + let(:distribution_id) { "" } + let(:error_msg) do + "[IDT] Http Status Code: 400, Distribution Does Not Exist Or Id is blank," \ + " (Distribution ID: #{distribution_id}) #{uuid}" + end + + it "renders an error with status 400" do + get :get_distribution, params: { distribution_id: distribution_id } + expect(response.code).to eq "400" + expect(JSON.parse(response.body)).to eq( + "message" => error_msg + ) + end + end + + context "when PacManService fails with a 404 error" do + let(:distribution_id) { 123_456 } + it "renders the expected response with status 200, Pacman api has a 404" do + expected_response = { + "id" => distribution_id, + "status" => "PENDING_ESTABLISHMENT" + } + + allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + OpenStruct.new(code: 404) + end + + get :get_distribution, params: { distribution_id: distribution_id } + + expect(response).to have_http_status(200) + expect(JSON.parse(response.body)).to eq(expected_response) + end + end + + context "when PacManService fails with a 500 error" do + let(:distribution) { double("Distribution", code: 500) } + let(:error_msg) do + "[IDT] Http Status Code: 500, Internal Server Error," \ + " (Distribution ID: #{distribution_id}) #{uuid}" + end + + it "renders an error with status 500" do + get :get_distribution, params: { distribution_id: distribution_id } + expect(response.code).to eq "500" + expect(JSON.parse(response.body)).to eq( + "message" => error_msg + ) + end + end + + context "when converting the distribution" do + let(:distribution_id) { 123_456 } + let(:distribution) do + HTTPI::Response.new( + 200, + {}, + "id": distribution_id, + "recipient": { + "type": "system", + "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name": "VBMS-C" + }, + "description": "Staging Mailing Distribution", + "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations": [{ + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": "", + "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", + "addressLine1": "POSTMASTER GENERAL", + "addressLine2": "UNITED STATES POSTAL SERVICE", + "addressLine3": "475 LENFANT PLZ SW RM 10022", + "addressLine4": "SUITE 123", + "addressLine5": "APO AE 09001-5275", + "addressLine6": "", + "treatLine2AsAddressee": true, + "treatLine3AsAddressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postalCode": "12345", + "countryName": "UNITED STATES", + "countryCode": "us" + }], + "status": "NEW", + "sentToCbcmDate": "" + ) + end + + before do + allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + end + + it "returns the expected converted response" do + expected_response = { + "id": distribution_id, + "recipient": { + "type": "system", + "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name": "VBMS-C" + }, + "description": "Staging Mailing Distribution", + "communication_package_id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "destinations": [{ + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": "", + "cbcm_send_attempt_date": "2022-06-06T16:35:27.996", + "address_line_1": "POSTMASTER GENERAL", + "address_line_2": "UNITED STATES POSTAL SERVICE", + "address_line_3": "475 LENFANT PLZ SW RM 10022", + "address_line_4": "SUITE 123", + "address_line_5": "APO AE 09001-5275", + "address_line_6": "", + "treat_line_2_as_addressee": true, + "treat_line_3_as_addressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postal_code": "12345", + "country_name": "UNITED STATES", + "country_code": "us" + }], + "status": "NEW", + "sent_to_cbcm_date": "" + } + get :get_distribution, params: { distribution_id: distribution_id } + expect(response).to have_http_status(200) + expect(JSON.parse(response.body.to_json)).to eq(expected_response.to_json) + end + end + + context "render_error" do + let(:status) { 500 } + let(:message) { "Internal Server Error" } + let(:distribution_id) { "123456" } + + it "renders the error response with correct status, message, and distribution ID" do + error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" + expect(Rails.logger).to receive(:error).with("#{error_message}Error ID: #{uuid}") + + allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + OpenStruct.new(code: 500) + end + + get :get_distribution, params: { distribution_id: distribution_id } + + expect(response).to have_http_status(status) + expect(JSON.parse(response.body)).to eq( + "message" => error_message + " #{error_uuid}" + ) + end + end + end +end From 3137821604d8b527850f56789a2adaff64041091 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Wed, 21 Jun 2023 14:03:42 -0400 Subject: [PATCH 190/308] Refactored mail package concern to remove unnecessary included_do black --- .../concerns/mail_package_concern.rb | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb index 84bbfa685ad..84a19ecfabf 100644 --- a/app/controllers/concerns/mail_package_concern.rb +++ b/app/controllers/concerns/mail_package_concern.rb @@ -5,25 +5,12 @@ module MailPackageConcern extend ActiveSupport::Concern - included do - def recipient_info - params[:recipient_info] - end - - def build_mail_package - return if recipient_info.blank? + private - throw_error_if_copies_out_of_range - # Create and validate MailRequest objects, save to db, and store distribution IDs - mail_requests.map do |request| - request.call - distribution_ids << request.vbms_distribution_id - end - end + def recipient_info + params[:recipient_info] end - private - def copies # Default value of 1 for copies return 1 if params[:copies].blank? @@ -38,6 +25,17 @@ def mail_package { distributions: mail_requests.to_json, copies: copies } end + def build_mail_package + return if recipient_info.blank? + + throw_error_if_copies_out_of_range + # Create and validate MailRequest objects, save to db, and store distribution IDs + mail_requests.map do |request| + request.call + distribution_ids << request.vbms_distribution_id + end + end + def mail_requests @mail_requests ||= create_mail_requests_and_track_errors end From 27c9f1dcdd4bfc4d842fc0a35a31f7eefbb4f21e Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 22 Jun 2023 14:02:22 -0400 Subject: [PATCH 191/308] Added created_by_id to mail package payload --- app/controllers/concerns/mail_package_concern.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb index 84a19ecfabf..c91419fb9df 100644 --- a/app/controllers/concerns/mail_package_concern.rb +++ b/app/controllers/concerns/mail_package_concern.rb @@ -22,7 +22,7 @@ def copies def mail_package return nil if recipient_info.blank? - { distributions: mail_requests.to_json, copies: copies } + { distributions: mail_requests.to_json, copies: copies, created_by_id: user.id } end def build_mail_package From b350128dc20a14e8ef3543c918ce31fcf90d628a Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Thu, 22 Jun 2023 15:40:07 -0400 Subject: [PATCH 192/308] Convert mail requests to json instead of array of mail requests to json --- app/controllers/concerns/mail_package_concern.rb | 13 +++++++++++-- .../idt/api/v1/upload_vbms_document_controller.rb | 1 + app/jobs/upload_document_to_vbms_job.rb | 7 +++---- app/workflows/prepare_document_upload_to_vbms.rb | 6 ++++-- .../api/v1/upload_vbms_document_controller_spec.rb | 5 +++-- spec/jobs/upload_document_to_vbms_job_spec.rb | 3 ++- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb index c91419fb9df..c68fe5d9419 100644 --- a/app/controllers/concerns/mail_package_concern.rb +++ b/app/controllers/concerns/mail_package_concern.rb @@ -18,13 +18,18 @@ def copies params[:copies] end - # Payload with distributions value (array of JSON-formatted MailRequest objects) and copies (integer) def mail_package return nil if recipient_info.blank? - { distributions: mail_requests.to_json, copies: copies, created_by_id: user.id } + { distributions: json_mail_requests, copies: copies, created_by_id: user.id } end + # Purpose: - Creates and validates a MailRequest object for each recipient + # - Calls #call method on each MailRequest to save corresponding VbmsDistirbution and + # VbmsDistributionDestination to the db + # - Stores the distribution IDs (to be returned to the IDT user as an immediate means of tracking + # each distribution) + # def build_mail_package return if recipient_info.blank? @@ -40,6 +45,10 @@ def mail_requests @mail_requests ||= create_mail_requests_and_track_errors end + def json_mail_requests + mail_requests.map(&:to_json) + end + def create_mail_requests_and_track_errors requests = recipient_info.map.with_index do |recipient, idx| MailRequest.new(recipient).tap do |request| diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index 8721944e6ca..a3b6aa80834 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -13,6 +13,7 @@ def create build_mail_package result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_package).call + if result.success? success_message = { message: "Document successfully queued for upload." } if recipient_info.present? diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 3548159c685..64346ee0dbc 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,12 +8,11 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten - # mail_package - Payload with copies value (integer) and distributions value (array of JSON-formatted - # MailRequest objects) to be submitted to Package Manager if optional recipient info is present + # mail_package - Payload with distributions value (array of JSON-formatted MailRequest objects), + # copies value (integer), and created_by_id value (integer) to be submitted to + # Package Manager if optional recipient info is present # # Return: nil - - # document_id:, initiator_css_id:, application: "idt", mail_package: nil def perform(params) @params = params RequestStore.store[:application] = application diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index a037db8b915..8270e8ca595 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,8 +10,10 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - # mail_package - Payload with copies value (integer) and distributions value (array of JSON-formatted - # MailRequest objects) to be submitted to Package Manager if optional recipient info is present + # mail_package - Payload with distributions value (array of JSON-formatted MailRequest objects), + # copies value (integer), and created_by_id value (integer) to be submitted to + # Package Manager if optional recipient info is present + # def initialize(params, user, appeal = nil, mail_package = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) @user = user diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 37cb41dd346..b3a5cbceeb6 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -250,9 +250,10 @@ let(:mail_request) { MailRequest.new(recipient_info[0]) } let(:mail_package) do { distributions: [mail_request.to_json], - copies: 1 } + copies: 1, + created_by_id: user.id } end - let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 1) } + let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 4) } let(:upload_job_params) do { document_id: uploaded_document.id, initiator_css_id: user.css_id, diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 8a55084e187..025b6c18485 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -8,7 +8,8 @@ let(:mail_request) { instance_double(MailRequest) } let(:mail_package) do { distributions: [mail_request.to_json], - copies: 1 } + copies: 1, + created_by_id: user.id } end let(:params) do From 9f798bd274c0e9b6b685482916d3a1a28e3da01f Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 22 Jun 2023 15:51:19 -0400 Subject: [PATCH 193/308] APPEALS-21118 fixed parameters --- app/jobs/mail_request_job.rb | 58 ++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index dea3b6321d2..ab4cb236877 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -11,8 +11,8 @@ class MailRequestJob < CaseflowJob # Response: n/a def perform(vbms_uploaded_document, mail_request) package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, - mail_request.name, - vbms_comm_package.document_referenced) + get_package_name(vbms_uploaded_document), + document_referenced(vbms_uploaded_document.id, mail_request[:copies])) log_info(package_response) vbms_comm_package = create_package(vbms_uploaded_document, mail_request) if package_response.code == 201 @@ -20,12 +20,16 @@ def perform(vbms_uploaded_document, mail_request) create_distribution_request(vbms_comm_package.id, mail_request) else vbms_comm_package.update!(status: "error") - log_error(error_msg(package_response.code)) + # log_error(error_msg(package_response.code)) end end private + def document_referenced(doc_id, copies) + [{ "id": doc_id, "copies": copies }] + end + # Purpose: Creates new VbmsCommunicationPackage # # takes in VbmsUploadedDocument object and MailRequest object @@ -35,12 +39,12 @@ def create_package(vbms_uploaded_document, mail_request) VbmsCommunicationPackage.new( comm_package_name: get_package_name(vbms_uploaded_document), created_at: Time.zone.now, - created_by_id: mail_request["distributions"][0]["created_by_id"], - copies: mail_request["distributions"]["copies"], - file_number: mail_request["distributions"][0]["veteranFileNumber"], + created_by_id: mail_request[:created_by_id], + copies: mail_request[:copies], + file_number: vbms_uploaded_document.veteran_file_number, status: nil, updated_at: Time.zone.now, - updated_by_id: mail_request["distributions"][0]["created_by_id"], + updated_by_id: mail_request[:created_by_id], vbms_uploaded_document_id: vbms_uploaded_document.id ) end @@ -55,17 +59,18 @@ def get_package_name(vbms_uploaded_document) # # Response: n/a def create_distribution_request(package_id, mail_request) - distributions = mail_request["distributions"] + distributions = mail_request[:distributions] distributions.each do |dist| - distribution_destination = VbmsDistributionDestination.find(vbms_distribution_id: dist["id"]) + dist_hash = JSON.parse(dist) + distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, - get_recipient_hash(distribution), - get_destinations_hash(distribution_destination)) + get_recipient_hash(distribution), + get_destinations_hash(dist_hash)) log_info(distribution_response) if distribution_response.code == 201 - dist.update!(vbms_communication_package_id: package_id) + distribution.update!(vbms_communication_package_id: package_id) else - log_error(error_msg(distribution.code)) + # log_error(error_msg(distribution.code)) end end end @@ -95,18 +100,18 @@ def get_recipient_hash(distribution) # Response: array that holds a hash def get_destinations_hash(destination) [{ - "type" => destination.destination_type, - "addressLine1" => destination.address_line_1, - "addressLine2" => destination.address_line_2, - "addressLine3" => destination.address_line_3, - "addressLine4" => destination.address_line_4, - "addressLine5" => destination.address_line_5, - "addressLine6" => destination.address_line_6, - "city" => destination.city, - "state" => destination.state, - "postalCode" => destination.postal_code, - "countryName" => destination.country_name, - "countryCode" => destination.country_code + "type" => destination["destination_type"], + "addressLine1" => destination["address_line_1"], + "addressLine2" => destination["address_line_2"], + "addressLine3" => destination["address_line_3"], + "addressLine4" => destination["address_line_4"], + "addressLine5" => destination["address_line_5"], + "addressLine6" => destination["address_line_6"], + "city" => destination["city"], + "state" => destination["state"], + "postalCode" => destination["postal_code"], + "countryName" => destination["country_name"], + "countryCode" => destination["country_code"] }] end @@ -144,6 +149,7 @@ def error_msg(code) # Response: n/a def log_info(info_message) uuid = SecureRandom.uuid - Rails.logger.info(info_message + "ID: " + uuid) + info_message.body.uuid = uuid + Rails.logger.info(info_message) end end From 92a7d53d47e6a1cf14b3b877b86b0b78b6ea5b6d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Thu, 22 Jun 2023 16:00:55 -0400 Subject: [PATCH 194/308] APPEALS-21118 organized comments --- app/jobs/mail_request_job.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index ab4cb236877..edba0fd4752 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -10,7 +10,7 @@ class MailRequestJob < CaseflowJob # # Response: n/a def perform(vbms_uploaded_document, mail_request) - package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, + package_response = Fakes::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, get_package_name(vbms_uploaded_document), document_referenced(vbms_uploaded_document.id, mail_request[:copies])) log_info(package_response) @@ -20,12 +20,17 @@ def perform(vbms_uploaded_document, mail_request) create_distribution_request(vbms_comm_package.id, mail_request) else vbms_comm_package.update!(status: "error") - # log_error(error_msg(package_response.code)) + log_error(error_msg(package_response.code)) end end private + # Purpose: arranges id and copies to pass into package post request + # + # takes in VbmsUploadedDocument id and copies integer + # + # Response: Array of json with document id and copies def document_referenced(doc_id, copies) [{ "id": doc_id, "copies": copies }] end @@ -63,14 +68,14 @@ def create_distribution_request(package_id, mail_request) distributions.each do |dist| dist_hash = JSON.parse(dist) distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, + distribution_response = Fakes::PacmanService.send_distribution_request(package_id, get_recipient_hash(distribution), get_destinations_hash(dist_hash)) log_info(distribution_response) if distribution_response.code == 201 distribution.update!(vbms_communication_package_id: package_id) else - # log_error(error_msg(distribution.code)) + log_error(error_msg(distribution.code)) end end end From db096c0a00fbf860f311c1083b313f0c336b5deb Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 23 Jun 2023 10:26:45 -0400 Subject: [PATCH 195/308] Updated spec file --- app/jobs/upload_document_to_vbms_job.rb | 2 +- .../idt/api/v1/upload_vbms_document_controller_spec.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index 64346ee0dbc..e0337e31ad4 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -17,7 +17,7 @@ def perform(params) @params = params RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user - @document = VbmsUploadedDocument.find_by(id: params[:document_id]) + @document = VbmsUploadedDocument.find(params[:document_id]) @initiator = User.find_by_css_id(params[:initiator_css_id]) add_context_to_sentry UploadDocumentToVbms.new(document: document).call diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index b3a5cbceeb6..b75c675afab 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -223,7 +223,8 @@ expect(UploadDocumentToVbmsJob).to receive(:perform_later).with( document_id: uploaded_document.id, initiator_css_id: user.css_id, - application: anything + application: anything, + mail_package: nil ) expect(uploaded_document).to receive(:cache_file) @@ -253,7 +254,7 @@ copies: 1, created_by_id: user.id } end - let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 4) } + let(:uploaded_document) { create(:vbms_uploaded_document) } let(:upload_job_params) do { document_id: uploaded_document.id, initiator_css_id: user.css_id, From bb9d615ba2c1ca0ef98e7ee4bae6cdb5c32f6cfe Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Fri, 23 Jun 2023 10:30:53 -0400 Subject: [PATCH 196/308] Changed comment --- app/controllers/concerns/mail_package_concern.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb index c68fe5d9419..12461498df3 100644 --- a/app/controllers/concerns/mail_package_concern.rb +++ b/app/controllers/concerns/mail_package_concern.rb @@ -34,7 +34,6 @@ def build_mail_package return if recipient_info.blank? throw_error_if_copies_out_of_range - # Create and validate MailRequest objects, save to db, and store distribution IDs mail_requests.map do |request| request.call distribution_ids << request.vbms_distribution_id From b98df5a0b86e9452d0b10da31dc0c24cdc3efd84 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Fri, 23 Jun 2023 13:26:34 -0400 Subject: [PATCH 197/308] APPEALS-21118 fakes->externalapi --- app/jobs/mail_request_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index edba0fd4752..0195b79ee98 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -10,7 +10,7 @@ class MailRequestJob < CaseflowJob # # Response: n/a def perform(vbms_uploaded_document, mail_request) - package_response = Fakes::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, + package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, get_package_name(vbms_uploaded_document), document_referenced(vbms_uploaded_document.id, mail_request[:copies])) log_info(package_response) @@ -68,7 +68,7 @@ def create_distribution_request(package_id, mail_request) distributions.each do |dist| dist_hash = JSON.parse(dist) distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - distribution_response = Fakes::PacmanService.send_distribution_request(package_id, + distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, get_recipient_hash(distribution), get_destinations_hash(dist_hash)) log_info(distribution_response) From d431b3c97c39fc0c101e1e34cc0b4acf9a96a107 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 26 Jun 2023 11:53:19 -0400 Subject: [PATCH 198/308] made rubocop changes in spec file. --- .../api/v1/upload_vbms_document_controller_spec.rb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index b75c675afab..e6233103a9e 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -24,15 +24,15 @@ { recipient_type: "person", first_name: "Bob", - last_name: "Smithmetz", + last_name: "Smithmets", participant_id: "487470002", destination_type: "domesticAddress", - address_line_1: "1234 Main Street", + address_line_1: "1235 Main Street", treat_line_2_as_addressee: false, treat_line_3_as_addressee: false, city: "Orlando", state: "FL", - postal_code: "12345", + postal_code: "13246", country_code: "US" } ] } @@ -169,10 +169,8 @@ error = JSON.parse(response.body)["error"] expect(success_message).to eq "Document successfully queued for upload." expect(validation_error_msgs).to eq( - { - "first_name" => ["can't be blank"], - "last_name" => ["can't be blank"] - } + "first_name" => ["can't be blank"], + "last_name" => ["can't be blank"] ) expect(error).to eq("Incomplete mailing information provided. No mail request was created.") expect(response.status).to eq(200) From 27b02618e742a93f71334896b36711b5cc74d24c Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Mon, 26 Jun 2023 12:30:50 -0400 Subject: [PATCH 199/308] Remove deprecated URI.escape method --- app/services/external_api/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 4b6691de208..24ad3e90890 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -144,7 +144,7 @@ def destinations_data(destination) # # Return: service_response: JSON from Pacman or error def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) - url = URI.escape(BASE_URL + endpoint) + url = ERB::Util.url_encode(BASE_URL + endpoint) request = HTTPI::Request.new(url) request.open_timeout = 30 request.read_timeout = 30 From 8a179bbf1153a915f18ac11312327fbaca1d5f39 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Mon, 26 Jun 2023 14:19:11 -0400 Subject: [PATCH 200/308] Key name to camelCase --- app/services/external_api/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 24ad3e90890..ccd12149661 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -108,7 +108,7 @@ def recipient_data(recipient) firstName: recipient[:first_name], middleName: recipient[:middle_name], lastName: recipient[:last_name], - participant_id: recipient[:participant_id], + participantId: recipient[:participant_id], poaCode: recipient[:poa_code], claimantStationOfJurisdiction: recipient[:claimant_station_of_jurisdiction] } From bf6c7803e6de75dd214e4693df447cc4ca375f49 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Mon, 26 Jun 2023 15:17:28 -0400 Subject: [PATCH 201/308] APPEALS-21118 fixed code based on feedback --- app/jobs/mail_request_job.rb | 52 +++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 0195b79ee98..73d3614bae6 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -2,22 +2,34 @@ class MailRequestJob < CaseflowJob queue_with_priority :low_priority - application_attr :intake + application_attr :api # Purpose: performs job # - # takes in VbmsUploadedDocument object and MailRequest object + # takes in VbmsUploadedDocument object and JSON payload + # mail_package looks like this: + # { + # "distributions": [ + # { + # "recipient_info": json of MailRequest object + # } + # ] + # "copies": integer value, + # "created_by_id": integer value + # } # # Response: n/a - def perform(vbms_uploaded_document, mail_request) - package_response = ExternalApi::PacmanService.send_communication_package_request(vbms_uploaded_document.veteran_file_number, - get_package_name(vbms_uploaded_document), - document_referenced(vbms_uploaded_document.id, mail_request[:copies])) + def perform(vbms_uploaded_document, mail_package) + package_response = PacmanService.send_communication_package_request( + vbms_uploaded_document.veteran_file_number, + get_package_name(vbms_uploaded_document), + document_referenced(vbms_uploaded_document.id, mail_package[:copies]) + ) log_info(package_response) - vbms_comm_package = create_package(vbms_uploaded_document, mail_request) + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) if package_response.code == 201 vbms_comm_package.update!(status: "success") - create_distribution_request(vbms_comm_package.id, mail_request) + create_distribution_request(vbms_comm_package.id, mail_package) else vbms_comm_package.update!(status: "error") log_error(error_msg(package_response.code)) @@ -40,16 +52,16 @@ def document_referenced(doc_id, copies) # takes in VbmsUploadedDocument object and MailRequest object # # Response: new VbmsCommunicationPackage object - def create_package(vbms_uploaded_document, mail_request) + def create_package(vbms_uploaded_document, mail_package) VbmsCommunicationPackage.new( comm_package_name: get_package_name(vbms_uploaded_document), created_at: Time.zone.now, - created_by_id: mail_request[:created_by_id], - copies: mail_request[:copies], + created_by_id: mail_package[:created_by_id], + copies: mail_package[:copies], file_number: vbms_uploaded_document.veteran_file_number, status: nil, updated_at: Time.zone.now, - updated_by_id: mail_request[:created_by_id], + updated_by_id: mail_package[:created_by_id], vbms_uploaded_document_id: vbms_uploaded_document.id ) end @@ -63,14 +75,16 @@ def get_package_name(vbms_uploaded_document) # takes in VbmsCommunicationPackage id (string) and MailRequest object # # Response: n/a - def create_distribution_request(package_id, mail_request) - distributions = mail_request[:distributions] + def create_distribution_request(package_id, mail_package) + distributions = mail_package[:distributions] distributions.each do |dist| dist_hash = JSON.parse(dist) distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - distribution_response = ExternalApi::PacmanService.send_distribution_request(package_id, - get_recipient_hash(distribution), - get_destinations_hash(dist_hash)) + distribution_response = PacmanService.send_distribution_request( + package_id, + get_recipient_hash(distribution), + get_destinations_hash(dist_hash) + ) log_info(distribution_response) if distribution_response.code == 201 distribution.update!(vbms_communication_package_id: package_id) @@ -92,7 +106,7 @@ def get_recipient_hash(distribution) firstName: distribution.first_name, middleName: distribution.middle_name, lastName: distribution.last_name, - participant_id: distribution.participant_id, + participantId: distribution.participant_id, poaCode: distribution.poa_code, claimantStationOfJurisdiction: distribution.claimant_station_of_jurisdiction } @@ -112,6 +126,8 @@ def get_destinations_hash(destination) "addressLine4" => destination["address_line_4"], "addressLine5" => destination["address_line_5"], "addressLine6" => destination["address_line_6"], + "treatLine2AsAddressee" => destination["treat_line_2_as_addressee"], + "treatLine3AsAddressee" => destination["treat_line_3_as_addressee"], "city" => destination["city"], "state" => destination["state"], "postalCode" => destination["postal_code"], From afbe0abd4b16bd6bb83b3159fd1039c4ff847f55 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 26 Jun 2023 16:02:55 -0400 Subject: [PATCH 202/308] provided changes to spec files per PR request. Also Fixed failing tests in MailRequestSpec. --- spec/factories/mail_request.rb | 5 +---- spec/workflows/mail_request_spec.rb | 7 ++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb index 7e92e50471a..256c80ed196 100644 --- a/spec/factories/mail_request.rb +++ b/spec/factories/mail_request.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :mail_request do + recipient_type { "person" } first_name { "Bob" } last_name { "Smithcole" } participant_id { "487470002" } @@ -14,10 +15,6 @@ treat_line_2_as_addressee { false } treat_line_3_as_addressee { false } - trait :person_recipient_type do - recipient_type { "person" } - end - trait :nil_recipient_type do recipient_type { nil } end diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb index 4330d608030..ef43959f4e7 100644 --- a/spec/workflows/mail_request_spec.rb +++ b/spec/workflows/mail_request_spec.rb @@ -35,7 +35,7 @@ end shared_examples "mail request has valid attributes" do - let(:mail_request_spec_object) { build(:mail_request, :person_recipient_type) } + let(:mail_request_spec_object) { build(:mail_request) } it "is valid with valid attributes" do expect(mail_request_spec_object).to be_valid end @@ -50,6 +50,11 @@ describe "#call" do context "when valid parameters are passed into the mail requests initialize method." do subject { described_class.new(mail_request_params).call } + + before do + RequestStore.store[:current_user] = User.system_user + end + it "creates a vbms_distribution" do expect { subject }.to change(VbmsDistribution, :count).by(1) end From b524e313d51915f9e76a8b79834fbdda33069353 Mon Sep 17 00:00:00 2001 From: Lauren Berry Date: Mon, 26 Jun 2023 20:10:46 -0700 Subject: [PATCH 203/308] committing code --- lib/helpers/report_load_end_product_sync.rb | 31 ++++++++++++------- .../scripts/priority_sync_cancelled_eps.sh | 2 +- .../scripts/priority_sync_cleared_eps.sh | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/helpers/report_load_end_product_sync.rb b/lib/helpers/report_load_end_product_sync.rb index 145aaff7b3b..eafe06669c8 100644 --- a/lib/helpers/report_load_end_product_sync.rb +++ b/lib/helpers/report_load_end_product_sync.rb @@ -29,14 +29,14 @@ def run_by_report_load(report_load) # The next two methods are part of the APPEALS-22696 initiative to priority sync # all EPs in Caseflow with VBMS # The following method is priority syncing cleared EPs - def run_for_cleared_eps(batch_limit, env) + def run_for_cleared_eps(batch_limit) RequestStore[:current_user] = User.system_user conn = ActiveRecord::Base.connection @error_log = [] @run_log = [] - error_ids = get_error_ids(env) + error_ids = get_error_ids eps_queried = get_cleared_eps(batch_limit, error_ids, conn) eps_queried.each do |x| @@ -53,14 +53,14 @@ def run_for_cleared_eps(batch_limit, env) end # Priority sync for cancelled EPs - def run_for_cancelled_eps(batch_limit, env) + def run_for_cancelled_eps(batch_limit) RequestStore[:current_user] = User.system_user conn = ActiveRecord::Base.connection @error_log = [] @run_log = [] - error_ids = get_error_ids(env) + error_ids = get_error_ids eps_queried = get_cancelled_eps(batch_limit, error_ids, conn) eps_queried.each do |x| @@ -128,14 +128,20 @@ def call_sync_by_report_load(ep_ref, rep_load, conn) #################################################################### # Grab txt file of previously errored EP reference ids from s3 and return as an array - def get_error_ids(env) - # Set Client Resources for AWS - Aws.config.update(region: "us-gov-west-1") - s3client = Aws::S3::Client.new - key_name = "ep_establishment_workaround/#{env}/ep_priority_sync/error_ids.txt" - - filepath = s3client.get_object(bucket:'appeals-dbas', key:key_name) - filepath.body.read.gsub("\r","").split("\n").map{ |obj| obj[1...-1] } + def get_error_ids + error_txt = S3Service.fetch_content(S3_BUCKET_NAME + "/error_ids.txt") + error_txt.gsub("\r","").split("\n").map{ |obj| obj[1...-1] } + end + + # Method to log errors to S3 error_ids txt file in real time in case of + # sync failure mid batch processing + # S3 does not support appending or modifying files in any way so the current txt file + # of errors has to be pulled and stored locally, modified locally, and then re-uploaded + def realtime_log_error_to_s3(reference_id) + error_txt = S3Service.fetch_content(S3_BUCKET_NAME + "/error_ids.txt") + error_txt << "\r\n" + error_txt << '"' + "#{reference_id}"+ '"' + S3Service.store_file(S3_BUCKET_NAME + "/error_ids.txt", error_txt) end # Grab cleared EPs that are out of sync @@ -228,6 +234,7 @@ def call_priority_sync(ep_ref, conn) prev_synced_status: sync_status_before, error: error.message ) + realtime_log_error_to_s3(epe.reference_id) end end diff --git a/lib/helpers/scripts/priority_sync_cancelled_eps.sh b/lib/helpers/scripts/priority_sync_cancelled_eps.sh index 867b2a57767..a0fe67b19ad 100644 --- a/lib/helpers/scripts/priority_sync_cancelled_eps.sh +++ b/lib/helpers/scripts/priority_sync_cancelled_eps.sh @@ -1,5 +1,5 @@ #! /bin/bash cd /opt/caseflow-certification/src; bin/rails c << DONETOKEN x = WarRoom::ReportLoadEndProductSync.new -x.run_for_cancelled_eps("$1", "$2") +x.run_for_cancelled_eps("$1") DONETOKEN diff --git a/lib/helpers/scripts/priority_sync_cleared_eps.sh b/lib/helpers/scripts/priority_sync_cleared_eps.sh index 4917258ce8e..893e0ec87c9 100644 --- a/lib/helpers/scripts/priority_sync_cleared_eps.sh +++ b/lib/helpers/scripts/priority_sync_cleared_eps.sh @@ -1,5 +1,5 @@ #! /bin/bash cd /opt/caseflow-certification/src; bin/rails c << DONETOKEN x = WarRoom::ReportLoadEndProductSync.new -x.run_for_cleared_eps("$1", "$2") +x.run_for_cleared_eps("$1") DONETOKEN From 3b9870825d24b021c5d3e63abf01cf4457aaef76 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 08:57:35 -0400 Subject: [PATCH 204/308] Add some lint ignores to methods that will no need to change --- app/controllers/idt/api/v2/distributions_controller.rb | 5 +++-- app/jobs/mail_request_job.rb | 1 + app/services/external_api/pacman_service.rb | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index c0d9182974f..1ef880cffc8 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -35,6 +35,8 @@ def get_distribution render json: format_response(distribution) end + private + def pending_establishment(distribution_id) render json: { id: distribution_id, status: "PENDING_ESTABLISHMENT" }, status: :ok end @@ -48,14 +50,13 @@ def format_response(response) end end - private - # Checks if the distribution exists in the database before sending request to PacMan def valid_id?(distribution_id) VbmsDistribution.exists?(id: distribution_id) end # Renders errors and logs and tracks the here within Raven + # :reek:FeatureEnvy def render_error(status, message, distribution_id) error_uuid = SecureRandom.uuid error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 73d3614bae6..79f4d27c869 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -52,6 +52,7 @@ def document_referenced(doc_id, copies) # takes in VbmsUploadedDocument object and MailRequest object # # Response: new VbmsCommunicationPackage object + # :reek:FeatureEnvy def create_package(vbms_uploaded_document, mail_package) VbmsCommunicationPackage.new( comm_package_name: get_package_name(vbms_uploaded_document), diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index ccd12149661..81ee9322f05 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -143,6 +143,7 @@ def destinations_data(destination) # Params: general requirements for HTTP request # # Return: service_response: JSON from Pacman or error + # :reek:LongParameterList def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) url = ERB::Util.url_encode(BASE_URL + endpoint) request = HTTPI::Request.new(url) From dc4239c864a3fbf00107f65fbe28af130259ef2d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 10:59:58 -0400 Subject: [PATCH 205/308] APPEALS-21118 error handling changes --- app/jobs/mail_request_job.rb | 74 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 73d3614bae6..9b9c1fcdbac 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -20,20 +20,20 @@ class MailRequestJob < CaseflowJob # # Response: n/a def perform(vbms_uploaded_document, mail_package) - package_response = PacmanService.send_communication_package_request( - vbms_uploaded_document.veteran_file_number, - get_package_name(vbms_uploaded_document), - document_referenced(vbms_uploaded_document.id, mail_package[:copies]) - ) - log_info(package_response) - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) - if package_response.code == 201 - vbms_comm_package.update!(status: "success") - create_distribution_request(vbms_comm_package.id, mail_package) - else + begin + package_response = Fakes::PacmanService.send_communication_package_request( + vbms_uploaded_document.veteran_file_number, + get_package_name(vbms_uploaded_document), + document_referenced(vbms_uploaded_document.id, mail_package[:copies]) + ) + log_info(package_response) + rescue Caseflow::Error::PacmanApiError => error vbms_comm_package.update!(status: "error") - log_error(error_msg(package_response.code)) + log_error(error) end + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) + vbms_comm_package.update!(status: "success") + create_distribution_request(vbms_comm_package.id, mail_package) end private @@ -78,19 +78,25 @@ def get_package_name(vbms_uploaded_document) def create_distribution_request(package_id, mail_package) distributions = mail_package[:distributions] distributions.each do |dist| - dist_hash = JSON.parse(dist) - distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - distribution_response = PacmanService.send_distribution_request( + begin + dist_hash = JSON.parse(dist) + rescue Caseflow::Error::PacmanApiError => error + log_error(error) + end + begin + distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) + rescue ActiveRecord::RecordNotFound => error + uuid = SecureRandom.uuid + Rails.logger.error(error.to_s + "Error ID: " + uuid) + Raven.capture_exception(error, extra: { error_uuid: uuid }) + end + distribution_response = Fakes::PacmanService.send_distribution_request( package_id, get_recipient_hash(distribution), get_destinations_hash(dist_hash) ) log_info(distribution_response) - if distribution_response.code == 201 - distribution.update!(vbms_communication_package_id: package_id) - else - log_error(error_msg(distribution.code)) - end + distribution.update!(vbms_communication_package_id: package_id) end end @@ -141,27 +147,19 @@ def get_destinations_hash(destination) # takes in error message (string) # # Response: n/a - def log_error(error_msg) + def log_error(error) uuid = SecureRandom.uuid - Rails.logger.error(error_msg + "Error ID: " + uuid) - Raven.capture_exception(error_msg, extra: { error_uuid: uuid }) + Rails.logger.error(ERROR_MESSAGES[error.code] + "Error ID: " + uuid) + Raven.capture_exception(error, extra: { error_uuid: uuid }) end - # Purpose: gets an error message based on the error code - # - # takes in error code (int) - # - # Response: error message string - def error_msg(code) - if code == 400 - "400 PacmanBadRequestError The server cannot create the new communication package due to a client error " - elsif code == 403 - "403 PacmanForbiddenError The server cannot create the new communication package due to insufficient privileges." - elsif code == 404 - "404 PacmanNotFoundError The communication package could not be found but may be available again in the future. - Subsequent requests by the client are permissible. " - end - end + ERROR_MESSAGES = { + 400 => "400 PacmanBadRequestError The server cannot create the new communication package due to a client error.", + 403 => "403 PacmanForbiddenError The server cannot create the new communication package" \ + "due to insufficient privileges.", + 404 => "404 PacmanNotFoundError The communication package could not be found but may be available" \ + "again in the future. Subsequent requests by the client are permissible." + }.freeze # Purpose: logs information in Rails logger # From 733a955b916836f2c6fa99b56943d8f559d5511d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 11:13:06 -0400 Subject: [PATCH 206/308] APPEALS-21118 removed fakes --- app/jobs/mail_request_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 3cd1a907ee9..4489bcdec41 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -21,7 +21,7 @@ class MailRequestJob < CaseflowJob # Response: n/a def perform(vbms_uploaded_document, mail_package) begin - package_response = Fakes::PacmanService.send_communication_package_request( + package_response = PacmanService.send_communication_package_request( vbms_uploaded_document.veteran_file_number, get_package_name(vbms_uploaded_document), document_referenced(vbms_uploaded_document.id, mail_package[:copies]) @@ -91,7 +91,7 @@ def create_distribution_request(package_id, mail_package) Rails.logger.error(error.to_s + "Error ID: " + uuid) Raven.capture_exception(error, extra: { error_uuid: uuid }) end - distribution_response = Fakes::PacmanService.send_distribution_request( + distribution_response = PacmanService.send_distribution_request( package_id, get_recipient_hash(distribution), get_destinations_hash(dist_hash) From 7b49bcc42d259ff7184011f7007fe79ca4a1fa3d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 11:16:22 -0400 Subject: [PATCH 207/308] APPEALS-21118 removed unnecessary error handling --- app/jobs/mail_request_job.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 4489bcdec41..c1be012dd0e 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -84,13 +84,7 @@ def create_distribution_request(package_id, mail_package) rescue Caseflow::Error::PacmanApiError => error log_error(error) end - begin - distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - rescue ActiveRecord::RecordNotFound => error - uuid = SecureRandom.uuid - Rails.logger.error(error.to_s + "Error ID: " + uuid) - Raven.capture_exception(error, extra: { error_uuid: uuid }) - end + distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) distribution_response = PacmanService.send_distribution_request( package_id, get_recipient_hash(distribution), From b57112c9a4fcc5f249bb66c09cab85766cd7a844 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 11:52:02 -0400 Subject: [PATCH 208/308] APPEALS-21118 updated rspec --- spec/jobs/mail_request_job_spec.rb | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 15abf9d320d..90e83a3ade5 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,19 +1,20 @@ # frozen_string_literal: true describe MailRequestJob do - let!(veteran) { create(:veteran) } - let!(appeal) { create(:appeal, veteran_file_number: veteran.file_number) } - let!(vbms_file) { create(:vbms_uploaded_document, appeal: appeal) } - let!(mail_request) { create(:mail_request, participant_id: veteran.participant_id) } + let!(:user) { create(:user, id: 1) } + let!(:vbms_file) { create(:vbms_uploaded_document) } + let!(:mail_request) { build(:mail_request) } context "successful " do - subject { MailRequestJob.perform(vbms_file, mail_request) } it "creates a new VbmsCommunicationPackage" do - expect { subject }.to change { VbmsCommunicationPackage.count }.by(1) + mail_request.call + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: user.id } + MailRequestJob.perform_now(vbms_file, mail_package) + expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) + expect(VbmsCommunicationPackage.first.status).to eq("success") end end - context "400 error in package request" do - subject { MailRequestJob.perform(vbms_file, mail_request) } - it "does not create a new VbmsCommunicationPackage" - expect { subject }.to change { VbmsCommunicationPackage.count }.by(0) - end + # context "400 error in package request" do + # it "does not create a new VbmsCommunicationPackage" + # expect { MailRequestJob.perform_now(vbms_file, nil) }.to change { VbmsCommunicationPackage.count }.by(0) + # end end From b354caffa505d00fcfba4fb9751575986c1d37d2 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 11:54:02 -0400 Subject: [PATCH 209/308] APPEALS-21118 PacMan -> Pacman --- .../idt/api/v2/distributions_controller.rb | 6 +++--- config/environments/test.rb | 2 +- config/initializers/pacman.rb | 2 +- .../idt/api/v2/distributions_controller_spec.rb | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 1ef880cffc8..384a5fcd416 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -15,8 +15,8 @@ def get_distribution end begin - # Retrieves the distribution package from the PacMan API - distribution = PacManService.get_distribution_request(distribution_id) + # Retrieves the distribution package from the Pacman API + distribution = PacmanService.get_distribution_request(distribution_id) response_code = distribution.code if response_code != 200 fail StandardError @@ -50,7 +50,7 @@ def format_response(response) end end - # Checks if the distribution exists in the database before sending request to PacMan + # Checks if the distribution exists in the database before sending request to Pacman def valid_id?(distribution_id) VbmsDistribution.exists?(id: distribution_id) end diff --git a/config/environments/test.rb b/config/environments/test.rb index db2c4a78410..f13945cb2ef 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -113,7 +113,7 @@ ENV['TEST_VACOLS_HOST'] ||= "localhost" - # PacMan environment variables + # Pacman environment variables ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov" ENV["PACMAN_API_KEY"] ||= "secret-key" end diff --git a/config/initializers/pacman.rb b/config/initializers/pacman.rb index 9dded20eed5..481795e510d 100644 --- a/config/initializers/pacman.rb +++ b/config/initializers/pacman.rb @@ -1 +1 @@ -PacManService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) +PacmanService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) diff --git a/spec/controllers/idt/api/v2/distributions_controller_spec.rb b/spec/controllers/idt/api/v2/distributions_controller_spec.rb index e70abf92042..690a6dd06b2 100644 --- a/spec/controllers/idt/api/v2/distributions_controller_spec.rb +++ b/spec/controllers/idt/api/v2/distributions_controller_spec.rb @@ -19,7 +19,7 @@ before do allow(controller).to receive(:params).and_return(distribution_id: distribution_id) allow(VbmsDistribution).to receive(:exists?).with(id: distribution_id).and_return(true) - allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) allow(SecureRandom).to receive(:uuid).and_return(uuid) key, t = Idt::Token.generate_one_time_key_and_proposed_token Idt::Token.activate_proposed_token(key, user.css_id) @@ -43,7 +43,7 @@ end end - context "when PacManService fails with a 404 error" do + context "when PacmanService fails with a 404 error" do let(:distribution_id) { 123_456 } it "renders the expected response with status 200, Pacman api has a 404" do expected_response = { @@ -51,7 +51,7 @@ "status" => "PENDING_ESTABLISHMENT" } - allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do OpenStruct.new(code: 404) end @@ -62,7 +62,7 @@ end end - context "when PacManService fails with a 500 error" do + context "when PacmanService fails with a 500 error" do let(:distribution) { double("Distribution", code: 500) } let(:error_msg) do "[IDT] Http Status Code: 500, Internal Server Error," \ @@ -117,7 +117,7 @@ end before do - allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) end it "returns the expected converted response" do @@ -167,7 +167,7 @@ error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" expect(Rails.logger).to receive(:error).with("#{error_message}Error ID: #{uuid}") - allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do OpenStruct.new(code: 500) end From 9fc2908f3be3681050dfc1203e477b165c216ca0 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 11:56:46 -0400 Subject: [PATCH 210/308] APPEALS-21118 fixed current_user in rspec --- spec/jobs/mail_request_job_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 90e83a3ade5..b8a7469e3d3 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true describe MailRequestJob do - let!(:user) { create(:user, id: 1) } + let!(:current_user) { User.authenticate! } let!(:vbms_file) { create(:vbms_uploaded_document) } let!(:mail_request) { build(:mail_request) } context "successful " do it "creates a new VbmsCommunicationPackage" do mail_request.call - mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: user.id } + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } MailRequestJob.perform_now(vbms_file, mail_package) expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) expect(VbmsCommunicationPackage.first.status).to eq("success") From 85ca67b7d1c07fccf2c18322e5e70ef2cd4256e1 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 27 Jun 2023 13:45:53 -0400 Subject: [PATCH 211/308] Corrected validation on copies attribute of VbmsCommunicationPackage --- app/models/vbms_communication_package.rb | 2 +- spec/models/vbms_communication_package_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 5a139dd6600..21d4d4bb290 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -6,5 +6,5 @@ class VbmsCommunicationPackage < CaseflowRecord validates :file_number, :comm_package_name, :copies, presence: true validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } - validates :copies, length: { in: 1..500 } + validates :copies, numericality: { only_integer: true, greater_than: 0, less_than: 501 } end diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index d30f7c30159..182a91e6367 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -47,13 +47,13 @@ it "is not valid without a copies attribute" do package.copies = nil expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) + expect(package.errors[:copies]).to eq(["can't be blank", "is not a number"]) end it "is not valid with less than one copy" do package.copies = 0 expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) + expect(package.errors[:copies]).to eq(["must be greater than 0"]) end it "is not valid with more than 500 copies" do @@ -62,7 +62,7 @@ package.copies = 501 expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) + expect(package.errors[:copies]).to eq(["must be less than 501"]) end it "is not valid without an associated VbmsUploadedDocument" do From 3cefbed81cbd4c0d1f5c216201298908f1358010 Mon Sep 17 00:00:00 2001 From: Jeff Marks Date: Tue, 27 Jun 2023 14:38:14 -0400 Subject: [PATCH 212/308] Correct unit test for VbmsDistribution to reflect optional communication package --- spec/models/vbms_distribution_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index da76b6cba2a..7182708ceab 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -20,10 +20,9 @@ include_examples "distribution has valid attributes" - it "is not valid without an associated VbmsCommunicationPackage" do + it "is valid without an associated VbmsCommunicationPackage" do distribution.vbms_communication_package = nil - expect(distribution).to_not be_valid - expect(distribution.errors[:vbms_communication_package]).to eq(["must exist"]) + expect(distribution).to be_valid end it "is not valid without a recipient type" do From 3d56e99b44fd4660f9cc1981444ceb13d11084ba Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 14:38:51 -0400 Subject: [PATCH 213/308] APPEALS-21118 fixed pacman service spec: participant_id to participantId --- spec/services/external_api/pacman_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 76250708375..0242cc7275d 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -55,7 +55,7 @@ "firstName" => nil, "middleName" => nil, "lastName" => nil, - "participant_id" => nil, + "participantId" => nil, "poaCode" => nil, "claimantStationOfJurisdiction" => nil }, From 3ef15e62a39eb961c9f3bcfb9d41ec319273090a Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Tue, 27 Jun 2023 15:01:00 -0400 Subject: [PATCH 214/308] updated failing tests. Green is Go. --- .../upload_vbms_document_controller_spec.rb | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index e6233103a9e..f0ec8422828 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -161,19 +161,14 @@ end context "when the recipient_info parameters are incomplete" do - it "queues the upload(given valid veteran info), returns a descriptive error to the IDT user" do + it "returns a descriptive error to the IDT user" do expect(Raven).to receive(:capture_exception) - post :create, params: invalid_mail_request_params - success_message = JSON.parse(response.body)["message"] - validation_error_msgs = JSON.parse(response.body)["error_messages"] - error = JSON.parse(response.body)["error"] - expect(success_message).to eq "Document successfully queued for upload." + post :create, params: invalid_mail_request_params, as: :json + validation_error_msgs = JSON.parse(response.body)["errors"] expect(validation_error_msgs).to eq( - "first_name" => ["can't be blank"], - "last_name" => ["can't be blank"] + "distribution 1"=>"First name can't be blank, Last name can't be blank" ) - expect(error).to eq("Incomplete mailing information provided. No mail request was created.") - expect(response.status).to eq(200) + expect(response.status).to eq(400) end end @@ -192,19 +187,21 @@ end shared_examples "success_with_valid_parameters" do + before do + RequestStore.store[:current_user] = User.system_user + end + it "creates a new Mail Request object when optional params exist" do expect_any_instance_of(MailRequest).to receive(:call) - post :create, params: mail_request_params + post :create, params: mail_request_params, as: :json end it "returns a list of vbms_distribution ids alongside a success message" do - post :create, params: mail_request_params + post :create, params: mail_request_params, as: :json success_message = JSON.parse(response.body)["message"] success_id = JSON.parse(response.body)["distribution_ids"] - # expect(VbmsDistribution).to change(:count).by(1) expect(success_message).to eq "Document successfully queued for upload." expect(success_id).not_to eq([]) - expect(response.status).to eq(200) end it "returns a successful message and creates a new VbmsUploadedDocument" do From 4de22e4b6315260a1ed862830d5f74e4f01f882a Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 15:12:46 -0400 Subject: [PATCH 215/308] Add early return --- lib/fakes/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 395e8090743..d1542f80acc 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -12,7 +12,7 @@ def send_distribution_request(package_id, recipient, destinations) def get_distribution_request(distribution_id) unless VbmsDistribution.exists?(id: distribution_id) - distribution_not_found_response + return distribution_not_found_response end fake_distribution_response(distribution_id) From d9c900ddbf51b09d0714516d15669a2805c35185 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 15:14:31 -0400 Subject: [PATCH 216/308] Remove mocks --- spec/services/external_api/pacman_service_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 0242cc7275d..d2ba089686a 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -152,13 +152,11 @@ subject { Fakes::PacmanService.get_distribution_request(distribution["id"]) } it "gets correct distribution" do subject - allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) expect(subject.body.as_json["table"]).to eq(get_distribution_success_response.body) end context "not found" do subject { Fakes::PacmanService.get_distribution_request("fake") } it "returns 404 PacmanNotFoundError" do - allow(HTTPI).to receive(:get).and_return(not_found_response) expect(subject.code).to eq(not_found_response.code) end end From d0e710235153718f276bfaca7463e19a7c0e0bac Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 16:38:50 -0400 Subject: [PATCH 217/308] DB migration to add UUID columns to Pacman tables --- ...0230627203547_add_uuid_to_pacman_tables.rb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 db/migrate/20230627203547_add_uuid_to_pacman_tables.rb diff --git a/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb b/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb new file mode 100644 index 00000000000..8d7b2d3478b --- /dev/null +++ b/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb @@ -0,0 +1,24 @@ +class AddUuidToPacmanTables < Caseflow::Migration + def up + add_column :vbms_communication_packages, + :uuid, + :string, + comment: "UUID of the communication package in Package Manager (Pacman)" + + add_column :vbms_distribution_destinations, + :uuid, + :string, + comment: "UUID of the distrubtion destination in Package Manager (Pacman)" + + add_column :vbms_distributions, + :uuid, + :string, + comment: "UUID of the distrubtion in Package Manager (Pacman)" + end + + def down + remove_column :vbms_communication_packages, :uuid + remove_column :vbms_distribution_destinations, :uuid + remove_column :vbms_distributions, :uuid + end +end From ff2ad6866a8504ee9cc9378bf20e777b7eb4aaec Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 16:43:40 -0400 Subject: [PATCH 218/308] APPEALS-21118 fixed vbms factories --- spec/factories/vbms_distribution.rb | 26 ++++++------ .../vbms_distribution_destination.rb | 40 +++++++++---------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index 2a0c9299d69..a2c6564cb6d 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -2,18 +2,18 @@ FactoryBot.define do factory :vbms_distribution do - claimant_station_of_jurisdiction - created_at - created_by_id - first_name - last_name - middle_name - name - participant_id - poa_code - recipient_type - updated_at - updated_by_id - vbms_communication_package_id + claimant_station_of_jurisdiction { nil } + created_at { Time.zone.now} + created_by_id { nil } + first_name { "Bob" } + last_name { "Bobjoe" } + middle_name { "Joe" } + name { nil } + participant_id { generate :participant_id} + poa_code { nil } + recipient_type { "person" } + updated_at { Time.zone.now } + updated_by_id { nil } + vbms_communication_package_id { "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431" } end end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index 34eeded3a0e..699bd75ce56 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -2,26 +2,24 @@ FactoryBot.define do factory :vbms_distribution_destination do - address_line_1 - address_line_2 - address_line_3 - address_line_4 - address_line_5 - address_line_6 - city - country_code - country_name - created_at - created_by_id - destination_type - email_address - phone_number - postal_code - state - treat_line_2_as_addressee - treat_line_3_as_addressee - updated_at - updated_by_id - vbms_distribution_id + address_line_1 { "POSTMASTER GENERAL" } + address_line_2 { "UNITED STATES POSTAL SERVICE" } + address_line_3 { "475 LENFANT PLZ SW RM 10022" } + address_line_4 { "SUITE 123" } + address_line_5 { "APO AE 09001-5275" } + address_line_6 { nil } + city { "WASHINGTON DC" } + country_code { "us" } + country_name { "UNITED STATES" } + created_at { Time.zone.now } + created_by_id { nil } + destination_type { "physicalAddress" } + postal_code { "12345" } + state { "DC" } + treat_line_2_as_addressee { true } + treat_line_3_as_addressee { true } + updated_at { Time.zone.now } + updated_by_id { nil } + vbms_distribution_id { nil } end end From bc0f41b952f3cc0acdc690e53ea7434a76b89343 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 27 Jun 2023 17:01:07 -0400 Subject: [PATCH 219/308] APPEALS-24643 Added pacman_uuid column to comm package, distribution, and destination audit tables and functions --- ...o_vbms_communication_packages_audit_table_function.rb | 9 ++++++--- ..._vbms_communication_packages_audit_table_function.sql | 9 ++++++--- ...bms_distribution_destinations_audit_table_function.rb | 9 ++++++--- ...ms_distribution_destinations_audit_table_function.sql | 9 ++++++--- ...add_row_to_vbms_distributions_audit_table_function.rb | 9 ++++++--- ...dd_row_to_vbms_distributions_audit_table_function.sql | 9 ++++++--- .../tables/create_vbms_communication_packages_audit.rb | 3 ++- .../tables/create_vbms_communication_packages_audit.sql | 3 ++- .../create_vbms_distribution_destinations_audit.rb | 3 ++- .../create_vbms_distribution_destinations_audit.sql | 3 ++- .../audit/tables/create_vbms_distributions_audit.rb | 3 ++- .../audit/tables/create_vbms_distributions_audit.sql | 3 ++- 12 files changed, 48 insertions(+), 24 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index babea94245e..683a006190e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -22,7 +22,8 @@ OLD.updated_at, OLD.vbms_uploaded_document_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id, + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -37,7 +38,8 @@ NEW.updated_at, NEW.vbms_uploaded_document_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -52,7 +54,8 @@ NEW.updated_at, NEW.vbms_uploaded_document_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index 379b8d26a87..ad50b63ce81 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -16,7 +16,8 @@ begin OLD.updated_at, OLD.vbms_uploaded_document_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id, + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -31,7 +32,8 @@ begin NEW.updated_at, NEW.vbms_uploaded_document_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -46,7 +48,8 @@ begin NEW.updated_at, NEW.vbms_uploaded_document_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index b84153084ef..1c15e1e0d4f 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -32,7 +32,8 @@ OLD.updated_at, OLD.vbms_distribution_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id, + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -57,7 +58,8 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -82,7 +84,8 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index 6c8f9b1aa9e..aaa34638231 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -26,7 +26,8 @@ begin OLD.updated_at, OLD.vbms_distribution_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id, + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -51,7 +52,8 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -76,7 +78,8 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 26276c72561..03721b4a525 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -26,7 +26,8 @@ OLD.updated_at, OLD.vbms_communication_package_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit select @@ -45,7 +46,8 @@ NEW.updated_at, NEW.vbms_communication_package_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distributions_audit select @@ -64,7 +66,8 @@ NEW.updated_at, NEW.vbms_communication_package_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 95dbc63bd40..6bdcd27c1bc 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -20,7 +20,8 @@ begin OLD.updated_at, OLD.vbms_communication_package_id, OLD.created_by_id, - OLD.updated_by_id; + OLD.updated_by_id + OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit select @@ -39,7 +40,8 @@ begin NEW.updated_at, NEW.vbms_communication_package_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id, + NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distributions_audit select @@ -58,7 +60,8 @@ begin NEW.updated_at, NEW.vbms_communication_package_id, NEW.created_by_id, - NEW.updated_by_id; + NEW.updated_by_id + NEW.pacman_uuid; end if; return null; end; diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index a13fac0c276..8f691c39f03 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -15,6 +15,7 @@ updated_at timestamp NOT NULL, vbms_uploaded_document_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 31c0b8f960d..10a55b3076a 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -10,5 +10,6 @@ create table caseflow_audit.vbms_communication_packages_audit ( updated_at timestamp NOT NULL, vbms_uploaded_document_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL ); diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 48664479ef3..d1eb45d674c 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -27,6 +27,7 @@ updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index b36bc275374..1c8010db2ff 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -22,5 +22,6 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL ); diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index e61e3eed950..00c7a9a20d9 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -19,6 +19,7 @@ updated_at timestamp NOT NULL, vbms_communication_package_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql index 03f16de76b2..6f9451fd032 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.sql @@ -14,5 +14,6 @@ create table caseflow_audit.vbms_distributions_audit ( updated_at timestamp NOT NULL, vbms_communication_package_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL + updated_by_id int8 NULL, + pacman_uuid varchar NULL ); From 1e690365b6e5707b210097e1dff389db556f6fa8 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 17:15:56 -0400 Subject: [PATCH 220/308] APPEALS-21118 pacman service rspec changes --- spec/factories/vbms_distribution.rb | 2 +- spec/services/external_api/pacman_service_spec.rb | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index a2c6564cb6d..de642bdcdf8 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -14,6 +14,6 @@ recipient_type { "person" } updated_at { Time.zone.now } updated_by_id { nil } - vbms_communication_package_id { "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431" } + vbms_communication_package_id { nil } end end diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index d2ba089686a..90bbda3d8db 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -46,6 +46,10 @@ }.as_json end + let(:vbms_distribution) do + create(:vbms_distribution, vbms_communication_package_id: distribution["communicationPackageId"]) + end + let(:distribution_post_request) do { "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", @@ -149,10 +153,10 @@ end context "get distribution" do - subject { Fakes::PacmanService.get_distribution_request(distribution["id"]) } + subject { Fakes::PacmanService.get_distribution_request(vbms_distribution.id) } it "gets correct distribution" do subject - expect(subject.body.as_json["table"]).to eq(get_distribution_success_response.body) + expect(subject.body.as_json).to eq(get_distribution_success_response.body) end context "not found" do subject { Fakes::PacmanService.get_distribution_request("fake") } From 7bec4d0bc656674aed47785d12ac65cd70faec23 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 17:40:39 -0400 Subject: [PATCH 221/308] APPEALS-21118 get_distribution_request in pacmanservice should take in int not string --- app/services/external_api/pacman_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 81ee9322f05..d0f7b8f4931 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -44,13 +44,13 @@ def send_distribution_request(package_id, recipient, destinations) # Purpose: Gets distribution from distribution id # POST: /package-manager-service/distribution # - # takes in distribution_id(string) + # takes in distribution_id(int) # # Response: JSON of distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_response' method def get_distribution_request(distribution_id) request = { - endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get + endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id.to_s, method: :get } send_pacman_request(request) end From 2a4d350d9e9fa204357a74fbfa951987f1de382d Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Tue, 27 Jun 2023 17:46:08 -0400 Subject: [PATCH 222/308] APPEALS-21118 pacmanservice spec: fixed get distribution tests by changing distribution id and communicationpackageid from string to int --- lib/fakes/pacman_service.rb | 2 +- spec/services/external_api/pacman_service_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index d1542f80acc..a9508ebd393 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -99,7 +99,7 @@ def fake_distribution_response(distribution_id) "name": "VBMS-C" }, "description": "Staging Mailing Distribution", - "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "communicationPackageId": 1, "destinations": [{ "type": "physicalAddress", "id": "28440040-51a5-4d2a-81a2-28730827be14", diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 90bbda3d8db..7eff71ce866 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -14,14 +14,14 @@ let(:distribution) do { - "id" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "id" => 1, "recipient" => { "type" => "system", "id" => "a050a21e-23f6-4743-a1ff-aa1e24412eff", "name" => "VBMS-C" }, "description" => "Staging Mailing Distribution", - "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "communicationPackageId" => 1, "destinations" => [{ "type" => "physicalAddress", "id" => "28440040-51a5-4d2a-81a2-28730827be14", @@ -47,7 +47,7 @@ end let(:vbms_distribution) do - create(:vbms_distribution, vbms_communication_package_id: distribution["communicationPackageId"]) + create(:vbms_distribution) end let(:distribution_post_request) do From d38eb9837c92490dbcf753181953b41c968cebe8 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 18:50:38 -0400 Subject: [PATCH 223/308] Audit tables updates --- ..._row_to_vbms_communication_packages_audit_table_function.rb | 3 +++ ...row_to_vbms_communication_packages_audit_table_function.sql | 3 +++ ...w_to_vbms_distribution_destinations_audit_table_function.rb | 3 +++ ..._to_vbms_distribution_destinations_audit_table_function.sql | 3 +++ .../add_row_to_vbms_distributions_audit_table_function.rb | 3 +++ .../add_row_to_vbms_distributions_audit_table_function.sql | 3 +++ .../audit/tables/create_vbms_communication_packages_audit.rb | 1 + .../audit/tables/create_vbms_communication_packages_audit.sql | 1 + .../tables/create_vbms_distribution_destinations_audit.rb | 1 + .../tables/create_vbms_distribution_destinations_audit.sql | 1 + db/scripts/audit/tables/create_vbms_distributions_audit.rb | 1 + db/scripts/audit/tables/create_vbms_distributions_audit.sql | 1 + 12 files changed, 24 insertions(+) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index babea94245e..45ad239c29e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -14,6 +14,7 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.file_number, OLD.copies, OLD.status, @@ -29,6 +30,7 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.file_number, NEW.copies, NEW.status, @@ -44,6 +46,7 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.file_number, NEW.copies, NEW.status, diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index 379b8d26a87..96086fed080 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -8,6 +8,7 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.file_number, OLD.copies, OLD.status, @@ -23,6 +24,7 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.file_number, NEW.copies, NEW.status, @@ -38,6 +40,7 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.file_number, NEW.copies, NEW.status, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index b84153084ef..0aa0a6b685c 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -14,6 +14,7 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.destination_type, OLD.address_line_1, OLD.address_line_2, @@ -39,6 +40,7 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, @@ -64,6 +66,7 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index 6c8f9b1aa9e..05a9943dc29 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -8,6 +8,7 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.destination_type, OLD.address_line_1, OLD.address_line_2, @@ -33,6 +34,7 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, @@ -58,6 +60,7 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 26276c72561..b665d370b66 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -14,6 +14,7 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.recipient_type, OLD.name, OLD.first_name, @@ -33,6 +34,7 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, @@ -52,6 +54,7 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 95dbc63bd40..f768c2fc911 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -8,6 +8,7 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.id, + OLD.uuid, OLD.recipient_type, OLD.name, OLD.first_name, @@ -27,6 +28,7 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.id, + NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, @@ -46,6 +48,7 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.id, + NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index a13fac0c276..77cf3600323 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -7,6 +7,7 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, + uuid varchar NULL, file_number varchar NULL, copies int8 NULL DEFAULT 1, status varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 31c0b8f960d..22ffa39ccbf 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -2,6 +2,7 @@ create table caseflow_audit.vbms_communication_packages_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, + uuid varchar NULL, file_number varchar NULL, copies int8 NULL DEFAULT 1, status varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 48664479ef3..9b244e26d01 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -7,6 +7,7 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, + uuid varchar NULL, destination_type varchar NOT NULL, address_line_1 varchar NOT NULL, address_line_2 varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index b36bc275374..96692a63e4f 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -2,6 +2,7 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, + uuid varchar NULL, destination_type varchar NOT NULL, address_line_1 varchar NOT NULL, address_line_2 varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index e61e3eed950..79b77bfa124 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -7,6 +7,7 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, + uuid varchar NULL, recipient_type varchar NOT NULL, name varchar NULL, first_name varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql index 03f16de76b2..8e47089c659 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.sql @@ -2,6 +2,7 @@ create table caseflow_audit.vbms_distributions_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, + uuid varchar NULL, recipient_type varchar NOT NULL, name varchar NULL, first_name varchar NULL, From 15b06652f008f3fe036c6a9c6eb6320bd93287ce Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 18:55:18 -0400 Subject: [PATCH 224/308] Change get distro route to look up using pkid --- .../idt/api/v2/distributions_controller.rb | 11 +++++++++-- app/services/external_api/pacman_service.rb | 6 +++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index c0d9182974f..b4f185c5183 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -16,7 +16,10 @@ def get_distribution begin # Retrieves the distribution package from the PacMan API - distribution = PacManService.get_distribution_request(distribution_id) + distribution_response = PacManService.get_distribution_request( + distribution_uuid_from_id(distribution_id) + ) + response_code = distribution.code if response_code != 200 fail StandardError @@ -32,7 +35,7 @@ def get_distribution return end - render json: format_response(distribution) + render json: format_response(distribution_response) end def pending_establishment(distribution_id) @@ -55,6 +58,10 @@ def valid_id?(distribution_id) VbmsDistribution.exists?(id: distribution_id) end + def distribution_uuid_from_id(pk_id) + VbmsDistribution.find(pk_id).uuid + end + # Renders errors and logs and tracks the here within Raven def render_error(status, message, distribution_id) error_uuid = SecureRandom.uuid diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 4b6691de208..b97e90841c9 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -44,13 +44,13 @@ def send_distribution_request(package_id, recipient, destinations) # Purpose: Gets distribution from distribution id # POST: /package-manager-service/distribution # - # takes in distribution_id(string) + # takes in distribution_uuid(string) # # Response: JSON of distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_response' method - def get_distribution_request(distribution_id) + def get_distribution_request(distribution_uuid) request = { - endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get + endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_uuid, method: :get } send_pacman_request(request) end From de9becf16b54c00d28c763d0345314f3c95e6ecb Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 18:57:43 -0400 Subject: [PATCH 225/308] Revert "Audit tables updates" This reverts commit d38eb9837c92490dbcf753181953b41c968cebe8. --- ..._row_to_vbms_communication_packages_audit_table_function.rb | 3 --- ...row_to_vbms_communication_packages_audit_table_function.sql | 3 --- ...w_to_vbms_distribution_destinations_audit_table_function.rb | 3 --- ..._to_vbms_distribution_destinations_audit_table_function.sql | 3 --- .../add_row_to_vbms_distributions_audit_table_function.rb | 3 --- .../add_row_to_vbms_distributions_audit_table_function.sql | 3 --- .../audit/tables/create_vbms_communication_packages_audit.rb | 1 - .../audit/tables/create_vbms_communication_packages_audit.sql | 1 - .../tables/create_vbms_distribution_destinations_audit.rb | 1 - .../tables/create_vbms_distribution_destinations_audit.sql | 1 - db/scripts/audit/tables/create_vbms_distributions_audit.rb | 1 - db/scripts/audit/tables/create_vbms_distributions_audit.sql | 1 - 12 files changed, 24 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index 3c24eaf7ae7..683a006190e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -14,7 +14,6 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.file_number, OLD.copies, OLD.status, @@ -31,7 +30,6 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.file_number, NEW.copies, NEW.status, @@ -48,7 +46,6 @@ nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.file_number, NEW.copies, NEW.status, diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index 11a913180fd..ad50b63ce81 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -8,7 +8,6 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.file_number, OLD.copies, OLD.status, @@ -25,7 +24,6 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.file_number, NEW.copies, NEW.status, @@ -42,7 +40,6 @@ begin nextval('caseflow_audit.vbms_communication_packages_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.file_number, NEW.copies, NEW.status, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index 26172d5407f..1c15e1e0d4f 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -14,7 +14,6 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.destination_type, OLD.address_line_1, OLD.address_line_2, @@ -41,7 +40,6 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, @@ -68,7 +66,6 @@ nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index d140258b773..aaa34638231 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -8,7 +8,6 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.destination_type, OLD.address_line_1, OLD.address_line_2, @@ -35,7 +34,6 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, @@ -62,7 +60,6 @@ begin nextval('caseflow_audit.vbms_distribution_destinations_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.destination_type, NEW.address_line_1, NEW.address_line_2, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index e4e48bb549d..03721b4a525 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -14,7 +14,6 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.recipient_type, OLD.name, OLD.first_name, @@ -35,7 +34,6 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, @@ -56,7 +54,6 @@ nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 00daf4455f0..6bdcd27c1bc 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -8,7 +8,6 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'D', OLD.id, - OLD.uuid, OLD.recipient_type, OLD.name, OLD.first_name, @@ -29,7 +28,6 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'U', NEW.id, - NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, @@ -50,7 +48,6 @@ begin nextval('caseflow_audit.vbms_distributions_audit_id_seq'::regclass), 'I', NEW.id, - NEW.uuid, NEW.recipient_type, NEW.name, NEW.first_name, diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index 4807e0fdb93..8f691c39f03 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -7,7 +7,6 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, - uuid varchar NULL, file_number varchar NULL, copies int8 NULL DEFAULT 1, status varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 4d772b10cd2..10a55b3076a 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -2,7 +2,6 @@ create table caseflow_audit.vbms_communication_packages_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_communication_package_id bigint not null, - uuid varchar NULL, file_number varchar NULL, copies int8 NULL DEFAULT 1, status varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 40ae5617202..d1eb45d674c 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -7,7 +7,6 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, - uuid varchar NULL, destination_type varchar NOT NULL, address_line_1 varchar NOT NULL, address_line_2 varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index 38654a7cc71..1c8010db2ff 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -2,7 +2,6 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distribution_destinations_id bigint not null, - uuid varchar NULL, destination_type varchar NOT NULL, address_line_1 varchar NOT NULL, address_line_2 varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index 85c2d5d9b67..00c7a9a20d9 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -7,7 +7,6 @@ id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, - uuid varchar NULL, recipient_type varchar NOT NULL, name varchar NULL, first_name varchar NULL, diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql index daedc429965..6f9451fd032 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.sql @@ -2,7 +2,6 @@ create table caseflow_audit.vbms_distributions_audit ( id BIGSERIAL PRIMARY KEY, type_of_change CHAR(1) not null, vbms_distributions_id bigint not null, - uuid varchar NULL, recipient_type varchar NOT NULL, name varchar NULL, first_name varchar NULL, From 88bccf9f6262d87a5f4618ced7c6228b942ffcfd Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 18:59:13 -0400 Subject: [PATCH 226/308] Use different column name --- app/controllers/idt/api/v2/distributions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index b4f185c5183..bdb5a4889f0 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -59,7 +59,7 @@ def valid_id?(distribution_id) end def distribution_uuid_from_id(pk_id) - VbmsDistribution.find(pk_id).uuid + VbmsDistribution.find(pk_id).pacman_uuid end # Renders errors and logs and tracks the here within Raven From 38a63d1407cb9cab93c86a4709ebf827e18b95cc Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 19:00:56 -0400 Subject: [PATCH 227/308] Update schema --- db/schema.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 6c1456f44a6..1a591647766 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: 2023_05_08_202742) do +ActiveRecord::Schema.define(version: 2023_06_27_203547) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1797,6 +1797,7 @@ t.string "status" t.datetime "updated_at", null: false t.bigint "updated_by_id" + t.string "uuid", comment: "UUID of the communication package in Package Manager (Pacman)" t.bigint "vbms_uploaded_document_id" t.index ["created_by_id"], name: "index_vbms_communication_packages_on_created_by_id" t.index ["updated_by_id"], name: "index_vbms_communication_packages_on_updated_by_id" @@ -1822,6 +1823,7 @@ t.boolean "treat_line_3_as_addressee", comment: "If true, treatLine2AsAddressee must also be true" t.datetime "updated_at", null: false t.bigint "updated_by_id" + t.string "uuid", comment: "UUID of the distrubtion destination in Package Manager (Pacman)" t.bigint "vbms_distribution_id" t.index ["created_by_id"], name: "index_vbms_distribution_destinations_on_created_by_id" t.index ["updated_by_id"], name: "index_vbms_distribution_destinations_on_updated_by_id" @@ -1841,6 +1843,7 @@ t.string "recipient_type", null: false, comment: "Must be one of [person, organization, ro-colocated, System]." t.datetime "updated_at", null: false t.bigint "updated_by_id" + t.string "uuid", comment: "UUID of the distrubtion in Package Manager (Pacman)" t.bigint "vbms_communication_package_id" t.index ["created_by_id"], name: "index_vbms_distributions_on_created_by_id" t.index ["updated_by_id"], name: "index_vbms_distributions_on_updated_by_id" From 5c955cbd7633fe3d6867b88b47096dc06f0f96d0 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 19:07:34 -0400 Subject: [PATCH 228/308] Minor refactoring --- .../idt/api/v2/distributions_controller.rb | 28 +++++++------------ config/routes.rb | 2 +- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index bdb5a4889f0..9973ed602f4 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -4,35 +4,27 @@ class Idt::Api::V2::DistributionsController < Idt::Api::V1::BaseController protect_from_forgery with: :exception before_action :verify_access - # rubocop:disable Metrics/MethodLength, Naming/AccessorMethodName - def get_distribution - # rubocop:enable Metrics/MethodLength, Naming/AccessorMethodName + def distribution distribution_id = params[:distribution_id] # Checks if the distribution id is blank and if it exists with the database if distribution_id.blank? || !valid_id?(distribution_id) - render_error(400, "Distribution Does Not Exist Or Id is blank", distribution_id) - return + return render_error(400, "Distribution Does Not Exist Or Id is blank", distribution_id) end + distribution_uuid = distribution_uuid_from_id(distribution_id) + + return pending_establishment(distribution_id) unless distribution_uuid + begin # Retrieves the distribution package from the PacMan API - distribution_response = PacManService.get_distribution_request( - distribution_uuid_from_id(distribution_id) - ) + distribution_response = PacManService.get_distribution_request(distribution_uuid) response_code = distribution.code - if response_code != 200 - fail StandardError - end + + fail StandardError if response_code != 200 # Handles errors when making any requests both from Pacman and the DB rescue StandardError - case response_code - when 404 - pending_establishment(distribution_id) - else - render_error(response_code, "Internal Server Error", distribution_id) - end - return + return render_error(response_code, "Internal Server Error", distribution_id) end render json: format_response(distribution_response) diff --git a/config/routes.rb b/config/routes.rb index 248e4082a02..81670f08808 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,7 +80,7 @@ post 'appeals/:appeal_id/outcode', to: 'appeals#outcode' get 'appeals/:appeal_id/documents', to: 'appeals#appeal_documents' get 'appeals/:appeal_id/documents/:document_id', to: 'appeals#appeals_single_document' - get 'distributions/:distribution_id', to: 'distributions#get_distribution' + get 'distributions/:distribution_id', to: 'distributions#distribution' end end end From be99980339cb4d71fbc16b4d7b2fc98a49d97f73 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 19:12:02 -0400 Subject: [PATCH 229/308] Add missing commas --- .../add_row_to_vbms_distributions_audit_table_function.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 6bdcd27c1bc..3098b405bc5 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -20,7 +20,7 @@ begin OLD.updated_at, OLD.vbms_communication_package_id, OLD.created_by_id, - OLD.updated_by_id + OLD.updated_by_id, OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit @@ -60,7 +60,7 @@ begin NEW.updated_at, NEW.vbms_communication_package_id, NEW.created_by_id, - NEW.updated_by_id + NEW.updated_by_id, NEW.pacman_uuid; end if; return null; From 84b6cf8b126f1a4f85c7d43d62e205c83c0a8a2f Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 19:15:51 -0400 Subject: [PATCH 230/308] missed another comma --- .../add_row_to_vbms_distributions_audit_table_function.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index 03721b4a525..ed743585e22 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -26,7 +26,7 @@ OLD.updated_at, OLD.vbms_communication_package_id, OLD.created_by_id, - OLD.updated_by_id + OLD.updated_by_id, OLD.pacman_uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit From d09b4cf3d92ae12c49df607261facff75ab8c724 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 19:19:06 -0400 Subject: [PATCH 231/308] More commas --- ..._to_vbms_distribution_destinations_audit_table_function.rb | 4 ++-- ...to_vbms_distribution_destinations_audit_table_function.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index 1c15e1e0d4f..acbec3269ed 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -58,7 +58,7 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id + NEW.updated_by_id, NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit @@ -84,7 +84,7 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id + NEW.updated_by_id, NEW.pacman_uuid; end if; return null; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index aaa34638231..539d2ce95f5 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -52,7 +52,7 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id + NEW.updated_by_id, NEW.pacman_uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit @@ -78,7 +78,7 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id + NEW.updated_by_id, NEW.pacman_uuid; end if; return null; From 95b92e34d0d6b17686866f9ec664b9c41327c12d Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 21:16:51 -0400 Subject: [PATCH 232/308] CC Fixes --- app/controllers/idt/api/v1/base_controller.rb | 4 +++- .../idt/api/v1/upload_vbms_document_controller_spec.rb | 2 +- spec/factories/vbms_distribution.rb | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index ec3819253c8..03fd90fe8d4 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -16,7 +16,9 @@ class Idt::Api::V1::BaseController < ActionController::Base if error.class.method_defined?(:serialize_response) render(error.serialize_response) else - render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, status: :internal_server_error + render json: { + message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" + }, status: :internal_server_error end end # :nocov: diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index f0ec8422828..33251249622 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -166,7 +166,7 @@ post :create, params: invalid_mail_request_params, as: :json validation_error_msgs = JSON.parse(response.body)["errors"] expect(validation_error_msgs).to eq( - "distribution 1"=>"First name can't be blank, Last name can't be blank" + "distribution 1" => "First name can't be blank, Last name can't be blank" ) expect(response.status).to eq(400) end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index de642bdcdf8..b367b6542c3 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -3,13 +3,13 @@ FactoryBot.define do factory :vbms_distribution do claimant_station_of_jurisdiction { nil } - created_at { Time.zone.now} + created_at { Time.zone.now } created_by_id { nil } first_name { "Bob" } last_name { "Bobjoe" } middle_name { "Joe" } name { nil } - participant_id { generate :participant_id} + participant_id { generate :participant_id } poa_code { nil } recipient_type { "person" } updated_at { Time.zone.now } From ef98d6196b37357fd5cdd37f2af882202ef0b454 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 21:32:21 -0400 Subject: [PATCH 233/308] Add pacman_uuid to factories --- spec/factories/vbms_communication_package.rb | 1 + spec/factories/vbms_distribution.rb | 1 + spec/factories/vbms_distribution_destination.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index c245fdd8bd3..c15de854698 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -11,5 +11,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_uploaded_document_id { nil } + pacman_uuid { nil } end end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index b367b6542c3..3fcc7e44492 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -15,5 +15,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_communication_package_id { nil } + pacman_uuid { nil } end end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index 699bd75ce56..dbf899029dd 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -21,5 +21,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_distribution_id { nil } + pacman_uuid { nil } end end From 086c12a2a45d16a55f63b7cc937d25e256b2cfe7 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 21:38:43 -0400 Subject: [PATCH 234/308] pacman_uuid to uuid to ease transition --- app/controllers/idt/api/v2/distributions_controller.rb | 2 +- ...w_to_vbms_communication_packages_audit_table_function.rb | 6 +++--- ..._to_vbms_communication_packages_audit_table_function.sql | 6 +++--- ...o_vbms_distribution_destinations_audit_table_function.rb | 6 +++--- ..._vbms_distribution_destinations_audit_table_function.sql | 6 +++--- .../add_row_to_vbms_distributions_audit_table_function.rb | 6 +++--- .../add_row_to_vbms_distributions_audit_table_function.sql | 6 +++--- .../tables/create_vbms_communication_packages_audit.rb | 2 +- .../tables/create_vbms_communication_packages_audit.sql | 2 +- .../tables/create_vbms_distribution_destinations_audit.rb | 2 +- .../tables/create_vbms_distribution_destinations_audit.sql | 2 +- db/scripts/audit/tables/create_vbms_distributions_audit.rb | 2 +- db/scripts/audit/tables/create_vbms_distributions_audit.sql | 2 +- spec/factories/vbms_communication_package.rb | 2 +- spec/factories/vbms_distribution.rb | 2 +- spec/factories/vbms_distribution_destination.rb | 2 +- 16 files changed, 28 insertions(+), 28 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 194cdfff859..7e81eb23ffe 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -51,7 +51,7 @@ def valid_id?(distribution_id) end def distribution_uuid_from_id(pk_id) - VbmsDistribution.find(pk_id).pacman_uuid + VbmsDistribution.find(pk_id).uuid end # Renders errors and logs and tracks the here within Raven diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index 683a006190e..837295f0e20 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -23,7 +23,7 @@ OLD.vbms_uploaded_document_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -39,7 +39,7 @@ NEW.vbms_uploaded_document_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -55,7 +55,7 @@ NEW.vbms_uploaded_document_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index ad50b63ce81..891abc0ed4d 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -17,7 +17,7 @@ begin OLD.vbms_uploaded_document_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -33,7 +33,7 @@ begin NEW.vbms_uploaded_document_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_communication_packages_audit select @@ -49,7 +49,7 @@ begin NEW.vbms_uploaded_document_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index acbec3269ed..f8dda5cbe3f 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -33,7 +33,7 @@ OLD.vbms_distribution_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -59,7 +59,7 @@ NEW.vbms_distribution_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -85,7 +85,7 @@ NEW.vbms_distribution_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index 539d2ce95f5..4432f9d17ec 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -27,7 +27,7 @@ begin OLD.vbms_distribution_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -53,7 +53,7 @@ begin NEW.vbms_distribution_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -79,7 +79,7 @@ begin NEW.vbms_distribution_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb index ed743585e22..93f1d2e4fe9 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.rb @@ -27,7 +27,7 @@ OLD.vbms_communication_package_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit select @@ -47,7 +47,7 @@ NEW.vbms_communication_package_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distributions_audit select @@ -67,7 +67,7 @@ NEW.vbms_communication_package_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql index 3098b405bc5..b5b74937baf 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distributions_audit_table_function.sql @@ -21,7 +21,7 @@ begin OLD.vbms_communication_package_id, OLD.created_by_id, OLD.updated_by_id, - OLD.pacman_uuid; + OLD.uuid; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distributions_audit select @@ -41,7 +41,7 @@ begin NEW.vbms_communication_package_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distributions_audit select @@ -61,7 +61,7 @@ begin NEW.vbms_communication_package_id, NEW.created_by_id, NEW.updated_by_id, - NEW.pacman_uuid; + NEW.uuid; end if; return null; end; diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index 8f691c39f03..5e79e627024 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -16,6 +16,6 @@ vbms_uploaded_document_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 10a55b3076a..9e288f69dc5 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -11,5 +11,5 @@ create table caseflow_audit.vbms_communication_packages_audit ( vbms_uploaded_document_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL ); diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index d1eb45d674c..a2a6642414d 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -28,6 +28,6 @@ vbms_distribution_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index 1c8010db2ff..4b76407fd72 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -23,5 +23,5 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( vbms_distribution_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL ); diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.rb b/db/scripts/audit/tables/create_vbms_distributions_audit.rb index 00c7a9a20d9..c8ddddc7879 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.rb @@ -20,6 +20,6 @@ vbms_communication_package_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_distributions_audit.sql b/db/scripts/audit/tables/create_vbms_distributions_audit.sql index 6f9451fd032..817c9ff2d73 100644 --- a/db/scripts/audit/tables/create_vbms_distributions_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distributions_audit.sql @@ -15,5 +15,5 @@ create table caseflow_audit.vbms_distributions_audit ( vbms_communication_package_id int8 NULL, created_by_id int8 NULL, updated_by_id int8 NULL, - pacman_uuid varchar NULL + uuid varchar NULL ); diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index c15de854698..8bf9119bb78 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -11,6 +11,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_uploaded_document_id { nil } - pacman_uuid { nil } + uuid { nil } end end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb index 3fcc7e44492..512d9234622 100644 --- a/spec/factories/vbms_distribution.rb +++ b/spec/factories/vbms_distribution.rb @@ -15,6 +15,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_communication_package_id { nil } - pacman_uuid { nil } + uuid { nil } end end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index dbf899029dd..6c93bad376f 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -21,6 +21,6 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_distribution_id { nil } - pacman_uuid { nil } + uuid { nil } end end From 8254e61b725a1ce7b4fd47dfefdde5445b29d976 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 21:56:17 -0400 Subject: [PATCH 235/308] Fix typo --- app/controllers/idt/api/v2/distributions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 7e81eb23ffe..477178d9a3d 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -19,7 +19,7 @@ def distribution # Retrieves the distribution package from the PacMan API distribution_response = PacmanService.get_distribution_request(distribution_uuid) - response_code = distribution.code + response_code = distribution_response.code fail StandardError if response_code != 200 # Handles errors when making any requests both from Pacman and the DB From 3e7e0bdbb36eb2a91fe531d3b990889e955cee5c Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 22:08:52 -0400 Subject: [PATCH 236/308] Alter fake --- lib/fakes/pacman_service.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index a9508ebd393..63563f5ee52 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -10,12 +10,12 @@ def send_distribution_request(package_id, recipient, destinations) fake_distribution_request(package_id, recipient, destinations) end - def get_distribution_request(distribution_id) - unless VbmsDistribution.exists?(id: distribution_id) - return distribution_not_found_response - end + def get_distribution_request(distribution_uuid) + distribution = VbmsDistribution.find(uuid: distribution_uuid) - fake_distribution_response(distribution_id) + return distribution_not_found_response unless distribution + + fake_distribution_response(distribution) end private @@ -88,11 +88,12 @@ def fake_distribution_request(package_id, recipient, destinations) end # GET: /package-manager-service/distribution/{id} - def fake_distribution_response(distribution_id) + def fake_distribution_response(distribution) HTTPI::Response.new( 200, {}, - "id": distribution_id, + "id": distribution.id, + "pacman_id": distribution.uuid, "recipient": { "type": "system", "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", From 4534b174ae1580c15de3e2461dfcaca00df2d46f Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 22:11:05 -0400 Subject: [PATCH 237/308] Missed a word --- lib/fakes/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 63563f5ee52..8ecf09287cc 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -11,7 +11,7 @@ def send_distribution_request(package_id, recipient, destinations) end def get_distribution_request(distribution_uuid) - distribution = VbmsDistribution.find(uuid: distribution_uuid) + distribution = VbmsDistribution.find_by(uuid: distribution_uuid) return distribution_not_found_response unless distribution From afb462d5b501c5aff3c0ba664dada802b623bdc9 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 22:22:02 -0400 Subject: [PATCH 238/308] Fix distributions_controller_spec tests --- .../api/v2/distributions_controller_spec.rb | 155 +++++++----------- 1 file changed, 60 insertions(+), 95 deletions(-) diff --git a/spec/controllers/idt/api/v2/distributions_controller_spec.rb b/spec/controllers/idt/api/v2/distributions_controller_spec.rb index 690a6dd06b2..dd0e1d2ef5e 100644 --- a/spec/controllers/idt/api/v2/distributions_controller_spec.rb +++ b/spec/controllers/idt/api/v2/distributions_controller_spec.rb @@ -5,24 +5,18 @@ # This is the command to run rspec in the console # bundle exec rspec spec/controllers/idt/api/v2/distributions_controller_spec.rb -# Here is where you look at code coverage -# open coverage/index.html - RSpec.describe Idt::Api::V2::DistributionsController, type: :controller do - describe "#get_distribution" do + describe "#distribution" do let(:user) { create(:user) } - let(:distribution_id) { 123_456 } - let(:appeal) { create(:appeal, :at_attorney_drafting) } - let(:distribution) { create(:distribution, judge: JudgeTask.find_by(appeal: appeal).assigned_to) } - let(:uuid) { "a9df0251-8350-464b-9aa4-a7d56a8ac173" } + let(:error_uuid) { "a9df0251-8350-464b-9aa4-a7d56a8ac173" } + let(:distro_uuid) { "df7fc6b2-8be3-4124-a796-6a77bdd8f66a" } before do - allow(controller).to receive(:params).and_return(distribution_id: distribution_id) - allow(VbmsDistribution).to receive(:exists?).with(id: distribution_id).and_return(true) - allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) - allow(SecureRandom).to receive(:uuid).and_return(uuid) + allow(SecureRandom).to receive(:uuid).and_return(error_uuid) + key, t = Idt::Token.generate_one_time_key_and_proposed_token Idt::Token.activate_proposed_token(key, user.css_id) + request.headers["TOKEN"] = t create(:staff, :attorney_role, sdomainid: user.css_id) end @@ -31,11 +25,12 @@ let(:distribution_id) { "" } let(:error_msg) do "[IDT] Http Status Code: 400, Distribution Does Not Exist Or Id is blank," \ - " (Distribution ID: #{distribution_id}) #{uuid}" + " (Distribution ID: #{distribution_id}) #{error_uuid}" end it "renders an error with status 400" do - get :get_distribution, params: { distribution_id: distribution_id } + get :distribution, params: { distribution_id: distribution_id } + expect(response.code).to eq "400" expect(JSON.parse(response.body)).to eq( "message" => error_msg @@ -44,18 +39,15 @@ end context "when PacmanService fails with a 404 error" do - let(:distribution_id) { 123_456 } + let!(:vbms_distribution) { create(:vbms_distribution) } + it "renders the expected response with status 200, Pacman api has a 404" do expected_response = { - "id" => distribution_id, + "id" => vbms_distribution.id.to_s, "status" => "PENDING_ESTABLISHMENT" } - allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do - OpenStruct.new(code: 404) - end - - get :get_distribution, params: { distribution_id: distribution_id } + get :distribution, params: { distribution_id: vbms_distribution.id } expect(response).to have_http_status(200) expect(JSON.parse(response.body)).to eq(expected_response) @@ -63,14 +55,19 @@ end context "when PacmanService fails with a 500 error" do - let(:distribution) { double("Distribution", code: 500) } let(:error_msg) do "[IDT] Http Status Code: 500, Internal Server Error," \ - " (Distribution ID: #{distribution_id}) #{uuid}" + " (Distribution ID: #{vbms_distribution.id}) #{error_uuid}" end + let(:vbms_distribution) { create(:vbms_distribution, uuid: distro_uuid) } it "renders an error with status 500" do - get :get_distribution, params: { distribution_id: distribution_id } + allow(PacmanService).to receive(:get_distribution_request).with(vbms_distribution.uuid) do + OpenStruct.new(code: 500) + end + + get :distribution, params: { distribution_id: vbms_distribution.id } + expect(response.code).to eq "500" expect(JSON.parse(response.body)).to eq( "message" => error_msg @@ -79,80 +76,48 @@ end context "when converting the distribution" do - let(:distribution_id) { 123_456 } - let(:distribution) do - HTTPI::Response.new( - 200, - {}, - "id": distribution_id, - "recipient": { + let(:vbms_distribution) { create(:vbms_distribution, uuid: distro_uuid) } + let(:expected_response) do + { + "id": vbms_distribution.id, + "pacman_id": vbms_distribution.uuid, + "recipient": + { "type": "system", "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", "name": "VBMS-C" }, "description": "Staging Mailing Distribution", - "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations": [{ - "type": "physicalAddress", - "id": "28440040-51a5-4d2a-81a2-28730827be14", - "status": "", - "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", - "addressLine1": "POSTMASTER GENERAL", - "addressLine2": "UNITED STATES POSTAL SERVICE", - "addressLine3": "475 LENFANT PLZ SW RM 10022", - "addressLine4": "SUITE 123", - "addressLine5": "APO AE 09001-5275", - "addressLine6": "", - "treatLine2AsAddressee": true, - "treatLine3AsAddressee": true, - "city": "WASHINGTON DC", - "state": "DC", - "postalCode": "12345", - "countryName": "UNITED STATES", - "countryCode": "us" - }], - "status": "NEW", - "sentToCbcmDate": "" - ) - end - - before do - allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + "communication_package_id": 1, + "destinations": [ + { + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": "", + "cbcm_send_attempt_date": "2022-06-06T16:35:27.996", + "address_line_1": "POSTMASTER GENERAL", + "address_line_2": "UNITED STATES POSTAL SERVICE", + "address_line_3": "475 LENFANT PLZ SW RM 10022", + "address_line_4": "SUITE 123", + "address_line_5": "APO AE 09001-5275", + "address_line_6": "", + "treat_line_2_as_addressee": true, + "treat_line_3_as_addressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postal_code": "12345", + "country_name": "UNITED STATES", + "country_code": "us" + } + ], + "status": "", + "sent_to_cbcm_date": "" + } end it "returns the expected converted response" do - expected_response = { - "id": distribution_id, - "recipient": { - "type": "system", - "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", - "name": "VBMS-C" - }, - "description": "Staging Mailing Distribution", - "communication_package_id": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", - "destinations": [{ - "type": "physicalAddress", - "id": "28440040-51a5-4d2a-81a2-28730827be14", - "status": "", - "cbcm_send_attempt_date": "2022-06-06T16:35:27.996", - "address_line_1": "POSTMASTER GENERAL", - "address_line_2": "UNITED STATES POSTAL SERVICE", - "address_line_3": "475 LENFANT PLZ SW RM 10022", - "address_line_4": "SUITE 123", - "address_line_5": "APO AE 09001-5275", - "address_line_6": "", - "treat_line_2_as_addressee": true, - "treat_line_3_as_addressee": true, - "city": "WASHINGTON DC", - "state": "DC", - "postal_code": "12345", - "country_name": "UNITED STATES", - "country_code": "us" - }], - "status": "NEW", - "sent_to_cbcm_date": "" - } - get :get_distribution, params: { distribution_id: distribution_id } + get :distribution, params: { distribution_id: vbms_distribution.id } + expect(response).to have_http_status(200) expect(JSON.parse(response.body.to_json)).to eq(expected_response.to_json) end @@ -161,17 +126,17 @@ context "render_error" do let(:status) { 500 } let(:message) { "Internal Server Error" } - let(:distribution_id) { "123456" } + let(:vbms_distribution) { create(:vbms_distribution, uuid: distro_uuid) } it "renders the error response with correct status, message, and distribution ID" do - error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" - expect(Rails.logger).to receive(:error).with("#{error_message}Error ID: #{uuid}") + error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{vbms_distribution.id})" + expect(Rails.logger).to receive(:error).with("#{error_message}Error ID: #{error_uuid}") - allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do + allow(PacmanService).to receive(:get_distribution_request).with(distro_uuid) do OpenStruct.new(code: 500) end - get :get_distribution, params: { distribution_id: distribution_id } + get :distribution, params: { distribution_id: vbms_distribution.id } expect(response).to have_http_status(status) expect(JSON.parse(response.body)).to eq( From 195965b1c2ef82530d7924b872dc06e568bb11de Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:19:01 -0400 Subject: [PATCH 239/308] Try new mail_request_spec setup --- spec/jobs/mail_request_job_spec.rb | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index b8a7469e3d3..765b87904d6 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,20 +1,30 @@ # frozen_string_literal: true describe MailRequestJob do + include ActiveJob::TestHelper + let!(:current_user) { User.authenticate! } let!(:vbms_file) { create(:vbms_uploaded_document) } let!(:mail_request) { build(:mail_request) } + context "successful " do it "creates a new VbmsCommunicationPackage" do mail_request.call mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } - MailRequestJob.perform_now(vbms_file, mail_package) - expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) - expect(VbmsCommunicationPackage.first.status).to eq("success") + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(1) + + expect( + find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status + ).to eq("success") end end - # context "400 error in package request" do - # it "does not create a new VbmsCommunicationPackage" - # expect { MailRequestJob.perform_now(vbms_file, nil) }.to change { VbmsCommunicationPackage.count }.by(0) - # end + + def find_comm_package_via_distribution_id(distro_id) + distribution = VbmsDistribution.find(distro_id) + + VbmsCommunicationPackage.find(distribution.vbms_communication_package_id) + end end From dbbd77878bd4e2b874cfaf168c34087a1d3b09d2 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:21:55 -0400 Subject: [PATCH 240/308] Update comm package factory --- spec/factories/vbms_communication_package.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index 8bf9119bb78..4c68f2c0999 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -2,15 +2,15 @@ FactoryBot.define do factory :vbms_communication_package do - comm_package_name { nil } + association :vbms_uploaded_document, factory: :vbms_uploaded_document + + created_by_id { create(:user).id } + comm_package_name { Faker::Book.title } created_at { Time.zone.now } - created_by_id { nil } - document_referenced { nil } - file_number { nil } + file_number { generate :veteran_file_number } status { nil } updated_at { Time.zone.now } updated_by_id { nil } - vbms_uploaded_document_id { nil } uuid { nil } end end From ca062fa69498e7302afa37302a5d375493682a05 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:28:13 -0400 Subject: [PATCH 241/308] Fix pacman_service_spec tests --- spec/services/external_api/pacman_service_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 7eff71ce866..b0c32d306ca 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -14,7 +14,8 @@ let(:distribution) do { - "id" => 1, + "id" => vbms_distribution.id, + "pacman_id": vbms_distribution.uuid, "recipient" => { "type" => "system", "id" => "a050a21e-23f6-4743-a1ff-aa1e24412eff", @@ -47,7 +48,7 @@ end let(:vbms_distribution) do - create(:vbms_distribution) + create(:vbms_distribution, uuid: SecureRandom.uuid) end let(:distribution_post_request) do @@ -153,9 +154,8 @@ end context "get distribution" do - subject { Fakes::PacmanService.get_distribution_request(vbms_distribution.id) } + subject { Fakes::PacmanService.get_distribution_request(vbms_distribution.uuid) } it "gets correct distribution" do - subject expect(subject.body.as_json).to eq(get_distribution_success_response.body) end context "not found" do @@ -194,7 +194,7 @@ end describe "response failure" do - subject { ExternalApi::PacmanService.get_distribution_request(distribution["id"]) } + subject { ExternalApi::PacmanService.get_distribution_request(vbms_distribution.uuid) } context "400" do it "throws Caseflow::Error::PacmanBadRequestError" do From 0c0437609e0a7c0cbb0a2051787a76c56526139e Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:37:58 -0400 Subject: [PATCH 242/308] Refactor --- app/services/external_api/pacman_service.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 4bcb95bdcc8..9c75c8bad71 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -63,7 +63,7 @@ def get_distribution_request(distribution_uuid) # # Response: package request hash def package_request(file_number, name, document_reference) - request = { + { body: { fileNumber: file_number, name: name, @@ -75,7 +75,6 @@ def package_request(file_number, name, document_reference) headers: HEADERS, endpoint: SEND_PACKAGE_ENDPOINT, method: :post } - request end # Purpose: Builds distribution request @@ -84,7 +83,7 @@ def package_request(file_number, name, document_reference) # # Response: Distribution request hash def distribution_request(package_id, recipient, destination) - request = { + { body: { communicationPackageId: package_id, recipient: recipient_data(recipient), @@ -93,7 +92,6 @@ def distribution_request(package_id, recipient, destination) headers: HEADERS, endpoint: SEND_PACKAGE_ENDPOINT, method: :post }.compact - request end # Purpose: Builds recipient json for distribution request From 505583e5e051a79c729923e6f00a5b1b004f790e Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:52:52 -0400 Subject: [PATCH 243/308] Update comm package and distros with pacman ids as uuids --- app/jobs/mail_request_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index c1be012dd0e..d76517ceb19 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -32,7 +32,7 @@ def perform(vbms_uploaded_document, mail_package) log_error(error) end vbms_comm_package = create_package(vbms_uploaded_document, mail_package) - vbms_comm_package.update!(status: "success") + vbms_comm_package.update!(status: "success", uuid: package_response.body[:id]) create_distribution_request(vbms_comm_package.id, mail_package) end @@ -91,7 +91,7 @@ def create_distribution_request(package_id, mail_package) get_destinations_hash(dist_hash) ) log_info(distribution_response) - distribution.update!(vbms_communication_package_id: package_id) + distribution.update!(vbms_communication_package_id: package_id, uuid: distribution_response.body[:id]) end end From 4953e990204815be8a2329d085cd2c17fb89dcfb Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 23:57:36 -0400 Subject: [PATCH 244/308] Remove UUID from destinations table since those just get lumped with distros in pacman --- db/migrate/20230627203547_add_uuid_to_pacman_tables.rb | 6 ------ db/schema.rb | 1 - ...bms_distribution_destinations_audit_table_function.rb | 9 +++------ ...ms_distribution_destinations_audit_table_function.sql | 9 +++------ .../create_vbms_distribution_destinations_audit.rb | 3 +-- .../create_vbms_distribution_destinations_audit.sql | 3 +-- 6 files changed, 8 insertions(+), 23 deletions(-) diff --git a/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb b/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb index 8d7b2d3478b..743876eeb23 100644 --- a/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb +++ b/db/migrate/20230627203547_add_uuid_to_pacman_tables.rb @@ -5,11 +5,6 @@ def up :string, comment: "UUID of the communication package in Package Manager (Pacman)" - add_column :vbms_distribution_destinations, - :uuid, - :string, - comment: "UUID of the distrubtion destination in Package Manager (Pacman)" - add_column :vbms_distributions, :uuid, :string, @@ -18,7 +13,6 @@ def up def down remove_column :vbms_communication_packages, :uuid - remove_column :vbms_distribution_destinations, :uuid remove_column :vbms_distributions, :uuid end end diff --git a/db/schema.rb b/db/schema.rb index 1a591647766..24dd5a28315 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1823,7 +1823,6 @@ t.boolean "treat_line_3_as_addressee", comment: "If true, treatLine2AsAddressee must also be true" t.datetime "updated_at", null: false t.bigint "updated_by_id" - t.string "uuid", comment: "UUID of the distrubtion destination in Package Manager (Pacman)" t.bigint "vbms_distribution_id" t.index ["created_by_id"], name: "index_vbms_distribution_destinations_on_created_by_id" t.index ["updated_by_id"], name: "index_vbms_distribution_destinations_on_updated_by_id" diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb index f8dda5cbe3f..b84153084ef 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.rb @@ -32,8 +32,7 @@ OLD.updated_at, OLD.vbms_distribution_id, OLD.created_by_id, - OLD.updated_by_id, - OLD.uuid; + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -58,8 +57,7 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id, - NEW.uuid; + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -84,8 +82,7 @@ NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id, - NEW.uuid; + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql index 4432f9d17ec..6c8f9b1aa9e 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_distribution_destinations_audit_table_function.sql @@ -26,8 +26,7 @@ begin OLD.updated_at, OLD.vbms_distribution_id, OLD.created_by_id, - OLD.updated_by_id, - OLD.uuid; + OLD.updated_by_id; elsif (TG_OP = 'UPDATE') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -52,8 +51,7 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id, - NEW.uuid; + NEW.updated_by_id; elsif (TG_OP = 'INSERT') then insert into caseflow_audit.vbms_distribution_destinations_audit select @@ -78,8 +76,7 @@ begin NEW.updated_at, NEW.vbms_distribution_id, NEW.created_by_id, - NEW.updated_by_id, - NEW.uuid; + NEW.updated_by_id; end if; return null; end; diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index a2a6642414d..48664479ef3 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -27,7 +27,6 @@ updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL, - uuid varchar NULL + updated_by_id int8 NULL );") conn.close diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index 4b76407fd72..b36bc275374 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -22,6 +22,5 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, created_by_id int8 NULL, - updated_by_id int8 NULL, - uuid varchar NULL + updated_by_id int8 NULL ); From e1c11f66caef208495ff560c97b8de54eb2584a5 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 08:41:04 -0400 Subject: [PATCH 245/308] Remove uuid from dest factory --- spec/factories/vbms_distribution_destination.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index 6c93bad376f..699bd75ce56 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -21,6 +21,5 @@ updated_at { Time.zone.now } updated_by_id { nil } vbms_distribution_id { nil } - uuid { nil } end end From a2d506d9a698140248cbd700712f79aac97ebfd0 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 09:40:37 -0400 Subject: [PATCH 246/308] More tests --- app/jobs/mail_request_job.rb | 1 - lib/fakes/pacman_service.rb | 16 ++++++------ spec/jobs/mail_request_job_spec.rb | 39 ++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index d76517ceb19..238d4fdac28 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -28,7 +28,6 @@ def perform(vbms_uploaded_document, mail_package) ) log_info(package_response) rescue Caseflow::Error::PacmanApiError => error - vbms_comm_package.update!(status: "error") log_error(error) end vbms_comm_package = create_package(vbms_uploaded_document, mail_package) diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 8ecf09287cc..06b9c137e25 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class Fakes::PacmanService < ExternalApi::PacmanService + COMMUNICATION_PACKAGE_UUID = "24eb6a66-3833-4de6-bea4-4b614e55d5ac" + DISTRIBUTION_UUID = "201cef13-49ba-4f40-8741-97d06cee0270" + class << self def send_communication_package_request(file_number, name, document_references) fake_package_request(file_number, name, document_references) @@ -15,7 +18,7 @@ def get_distribution_request(distribution_uuid) return distribution_not_found_response unless distribution - fake_distribution_response(distribution) + fake_distribution_response(distribution.uuid) end private @@ -59,7 +62,7 @@ def fake_package_request(file_number, name, document_references) 201, {}, OpenStruct.new( - "id": "24eb6a66-3833-4de6-bea4-4b614e55d5ac", + "id": COMMUNICATION_PACKAGE_UUID, "fileNumber": file_number, "name": name, "documentReferences": document_references, @@ -69,14 +72,13 @@ def fake_package_request(file_number, name, document_references) ) end - # rubocop:disable Metrics/MethodLength # POST: /package-manager-service/distribution def fake_distribution_request(package_id, recipient, destinations) HTTPI::Response.new( 201, {}, OpenStruct.new( - "id": "12345", + "id": DISTRIBUTION_UUID, "recipient": recipient, "description": "bad", "communicationPackageId": package_id, @@ -87,13 +89,13 @@ def fake_distribution_request(package_id, recipient, destinations) ) end + # rubocop:disable Metrics/MethodLength # GET: /package-manager-service/distribution/{id} - def fake_distribution_response(distribution) + def fake_distribution_response(_distribution_id) HTTPI::Response.new( 200, {}, - "id": distribution.id, - "pacman_id": distribution.uuid, + "id": DISTRIBUTION_UUID, "recipient": { "type": "system", "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 765b87904d6..c6d9e9cf97d 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -7,8 +7,12 @@ let!(:vbms_file) { create(:vbms_uploaded_document) } let!(:mail_request) { build(:mail_request) } - context "successful " do - it "creates a new VbmsCommunicationPackage" do + let(:comm_package_uuid) { Fakes::PacmanService::COMMUNICATION_PACKAGE_UUID } + let(:distribution_uuid) { Fakes::PacmanService::DISTRIBUTION_UUID } + + context "Successful execution of MailRequestJob" do + it "Creates a new VbmsCommunicationPackage. The communication package and " \ + "distribution are given UUIDs from response" do mail_request.call mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } @@ -16,9 +20,34 @@ perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } end.to change { VbmsCommunicationPackage.count }.by(1) - expect( - find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status - ).to eq("success") + distribution = VbmsDistribution.find(mail_request.vbms_distribution_id) + comm_package = find_comm_package_via_distribution_id(mail_request.vbms_distribution_id) + + expect(comm_package.status).to eq("success") + + expect(comm_package.uuid).to eq(comm_package_uuid) + expect(distribution.uuid).to eq(distribution_uuid) + end + end + + context "Unsuccessful execution of MailRequestJob" do + it "VbmsCommunicationPackage is not created. VbmsDistribution's UUID remains nil." do + mail_request.call + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } + + allow(PacmanService) + .to receive(:send_communication_package_request) + .and_raise(Caseflow::Error::PacmanApiError.new(code: 500, message: "Fake Error")) + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(1) + + distribution = VbmsDistribution.find(mail_request.vbms_distribution_id) + comm_package = find_comm_package_via_distribution_id(mail_request.vbms_distribution_id) + + expect(comm_package).to be_nil + expect(distribution.uuid).to be_nil end end From 501bf39544f2a0137a0d2657829bcab71d763006 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 11:00:54 -0400 Subject: [PATCH 247/308] APPEALS-21118 moved vbms package creation into begin block --- app/jobs/mail_request_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index c1be012dd0e..396a8206a2a 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -27,11 +27,11 @@ def perform(vbms_uploaded_document, mail_package) document_referenced(vbms_uploaded_document.id, mail_package[:copies]) ) log_info(package_response) + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) rescue Caseflow::Error::PacmanApiError => error vbms_comm_package.update!(status: "error") log_error(error) end - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) vbms_comm_package.update!(status: "success") create_distribution_request(vbms_comm_package.id, mail_package) end From 24d8be0c45ce4f2d564ad6a2f0aad9b15fbb8dce Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 12:40:05 -0400 Subject: [PATCH 248/308] APPEALS-21118 initilialized PacmanApiError --- lib/caseflow/error.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index f37911d4214..df77673dd3b 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -450,7 +450,10 @@ class VANotifyRateLimitError < VANotifyApiError; end class EmptyQueueError < StandardError; end # Pacman errors - class PacmanApiError < StandardError; end + class PacmanApiError < StandardError + include Caseflow::Error::ErrorSerializer + attr_accessor :code, :message + end class PacmanBadRequestError < PacmanApiError; end class PacmanForbiddenError < PacmanApiError; end class PacmanNotFoundError < PacmanApiError; end From 66c670dcd50079548456328558b0b7d1c46d6174 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 12:40:31 -0400 Subject: [PATCH 249/308] APPEALS-21118 removed chunk of comments --- spec/jobs/mail_request_job_spec.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index b8a7469e3d3..32c821a01c1 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -13,8 +13,4 @@ expect(VbmsCommunicationPackage.first.status).to eq("success") end end - # context "400 error in package request" do - # it "does not create a new VbmsCommunicationPackage" - # expect { MailRequestJob.perform_now(vbms_file, nil) }.to change { VbmsCommunicationPackage.count }.by(0) - # end end From 15258cd71384bdce6509b9c0f244720b2c1eb28d Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 12:43:28 -0400 Subject: [PATCH 250/308] Fix a spec failure --- spec/services/external_api/pacman_service_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index b0c32d306ca..81409e28efa 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -14,8 +14,7 @@ let(:distribution) do { - "id" => vbms_distribution.id, - "pacman_id": vbms_distribution.uuid, + "id" => Fakes::PacmanService::DISTRIBUTION_UUID, "recipient" => { "type" => "system", "id" => "a050a21e-23f6-4743-a1ff-aa1e24412eff", From db6154f17b5c58a832c419329c71f33c00a505f7 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 12:52:35 -0400 Subject: [PATCH 251/308] APPEALS-21118 fixed vbms comm package factory --- spec/factories/vbms_communication_package.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index c245fdd8bd3..450ad4df740 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -2,14 +2,14 @@ FactoryBot.define do factory :vbms_communication_package do - comm_package_name { nil } + association :vbms_uploaded_document, factory: :vbms_uploaded_document + comm_package_name { "DocumentName_" + Time.zone.now.to_s } + copies { 1 } created_at { Time.zone.now } - created_by_id { nil } - document_referenced { nil } - file_number { nil } + created_by_id { create(:user).id } + file_number { generate :veteran_file_number } status { nil } updated_at { Time.zone.now } updated_by_id { nil } - vbms_uploaded_document_id { nil } end end From 8cc772e97d13eac025fbc983341c36b7450fb6c3 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 15:00:05 -0400 Subject: [PATCH 252/308] APPEALS-21118 changed rspec --- spec/jobs/mail_request_job_spec.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index 32c821a01c1..c3c0f0ae43d 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true describe MailRequestJob do + include ActiveJob::TestHelper let!(:current_user) { User.authenticate! } let!(:vbms_file) { create(:vbms_uploaded_document) } let!(:mail_request) { build(:mail_request) } @@ -10,7 +11,12 @@ mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } MailRequestJob.perform_now(vbms_file, mail_package) expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) - expect(VbmsCommunicationPackage.first.status).to eq("success") + expect(find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status).to eq("success") end end + def find_comm_package_via_distribution_id(distro_id) + distribution = VbmsDistribution.find(distro_id) + + VbmsCommunicationPackage.find(distribution.vbms_communication_package_id) + end end From 3ee30752ce397f6d9c1abf91e32d1b0aa2647cf7 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 15:34:42 -0400 Subject: [PATCH 253/308] APPEALS-21118 added 500 error to error code hash --- app/jobs/mail_request_job.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 396a8206a2a..f963f408451 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -153,7 +153,8 @@ def log_error(error) 403 => "403 PacmanForbiddenError The server cannot create the new communication package" \ "due to insufficient privileges.", 404 => "404 PacmanNotFoundError The communication package could not be found but may be available" \ - "again in the future. Subsequent requests by the client are permissible." + "again in the future. Subsequent requests by the client are permissible.", + 500 => "500 PacmanInternalServerError The request was unable to be completed." }.freeze # Purpose: logs information in Rails logger From a31ae3260c7265876b26384e73c92bea5b225f8b Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 16:11:36 -0400 Subject: [PATCH 254/308] APPEALS-21118 moved package creation outside of begin block --- app/jobs/mail_request_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index f963f408451..3891baab5e4 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -20,6 +20,7 @@ class MailRequestJob < CaseflowJob # # Response: n/a def perform(vbms_uploaded_document, mail_package) + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) begin package_response = PacmanService.send_communication_package_request( vbms_uploaded_document.veteran_file_number, @@ -27,7 +28,6 @@ def perform(vbms_uploaded_document, mail_package) document_referenced(vbms_uploaded_document.id, mail_package[:copies]) ) log_info(package_response) - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) rescue Caseflow::Error::PacmanApiError => error vbms_comm_package.update!(status: "error") log_error(error) From bcfca90bd468dfe2f81016953dd8831bd8df8879 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 16:18:10 -0400 Subject: [PATCH 255/308] APPEALS-21118 package is created only if post request is successful --- app/jobs/mail_request_job.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 3891baab5e4..ae3505bf1d6 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -20,7 +20,6 @@ class MailRequestJob < CaseflowJob # # Response: n/a def perform(vbms_uploaded_document, mail_package) - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) begin package_response = PacmanService.send_communication_package_request( vbms_uploaded_document.veteran_file_number, @@ -29,9 +28,9 @@ def perform(vbms_uploaded_document, mail_package) ) log_info(package_response) rescue Caseflow::Error::PacmanApiError => error - vbms_comm_package.update!(status: "error") log_error(error) end + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) vbms_comm_package.update!(status: "success") create_distribution_request(vbms_comm_package.id, mail_package) end From a55ca9f7567b0c6299eddecec6f43dd9e93c44d4 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 16:32:34 -0400 Subject: [PATCH 256/308] APPEALS-21118 put code outside begin rescue block in else statement and added/updated test for unsuccessful execution of mailrequestjob --- app/jobs/mail_request_job.rb | 24 +++++++++++++----------- spec/jobs/mail_request_job_spec.rb | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index ae3505bf1d6..e6b251e4327 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -29,10 +29,11 @@ def perform(vbms_uploaded_document, mail_package) log_info(package_response) rescue Caseflow::Error::PacmanApiError => error log_error(error) + else + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) + vbms_comm_package.update!(status: "success") + create_distribution_request(vbms_comm_package.id, mail_package) end - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) - vbms_comm_package.update!(status: "success") - create_distribution_request(vbms_comm_package.id, mail_package) end private @@ -82,15 +83,16 @@ def create_distribution_request(package_id, mail_package) dist_hash = JSON.parse(dist) rescue Caseflow::Error::PacmanApiError => error log_error(error) + else + distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) + distribution_response = PacmanService.send_distribution_request( + package_id, + get_recipient_hash(distribution), + get_destinations_hash(dist_hash) + ) + log_info(distribution_response) + distribution.update!(vbms_communication_package_id: package_id) end - distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) - distribution_response = PacmanService.send_distribution_request( - package_id, - get_recipient_hash(distribution), - get_destinations_hash(dist_hash) - ) - log_info(distribution_response) - distribution.update!(vbms_communication_package_id: package_id) end end diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index c3c0f0ae43d..d47d173dfbf 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -8,12 +8,31 @@ context "successful " do it "creates a new VbmsCommunicationPackage" do mail_request.call - mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: 1 } + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: current_user.id } MailRequestJob.perform_now(vbms_file, mail_package) expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) expect(find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status).to eq("success") end end + + context "Unsuccessful execution of MailRequestJob" do + it "VbmsCommunicationPackage is not created. VbmsDistribution's vbms_communication_package_id remains nil." do + mail_request.call + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: current_user.id } + + allow(PacmanService) + .to receive(:send_communication_package_request) + .and_raise(Caseflow::Error::PacmanApiError.new(code: 500, message: "Fake Error")) + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(0) + + distribution = VbmsDistribution.find(mail_request.vbms_distribution_id) + + expect(distribution.vbms_communication_package_id).to be_nil + end + end def find_comm_package_via_distribution_id(distro_id) distribution = VbmsDistribution.find(distro_id) From d8a0e679e28a11b419efa19c09e038b23e8d7cbd Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 16:58:21 -0400 Subject: [PATCH 257/308] Spec test tweaks --- spec/jobs/mail_request_job_spec.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb index d47d173dfbf..d133139a914 100644 --- a/spec/jobs/mail_request_job_spec.rb +++ b/spec/jobs/mail_request_job_spec.rb @@ -5,12 +5,16 @@ let!(:current_user) { User.authenticate! } let!(:vbms_file) { create(:vbms_uploaded_document) } let!(:mail_request) { build(:mail_request) } - context "successful " do + + context "Successful execution of MailRequestJob" do it "creates a new VbmsCommunicationPackage" do mail_request.call mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: current_user.id } - MailRequestJob.perform_now(vbms_file, mail_package) - expect { MailRequestJob.perform_now(vbms_file, mail_package) }.to change { VbmsCommunicationPackage.count }.by(1) + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(1) + expect(find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status).to eq("success") end end From a8cae8daee3596bd214311a3b5b0e7aca7efc56e Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 17:03:25 -0400 Subject: [PATCH 258/308] Use bearer token --- app/services/external_api/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index d0f7b8f4931..5843cb178f8 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -151,7 +151,7 @@ def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) request.read_timeout = 30 request.body = body.to_json unless body.nil? # not sure how user validation will be handled - request.headers = headers.merge(apikey: ENV["PACMAN_API_KEY"]) + request.headers = headers.merge(Bearer: ENV["PACMAN_API_KEY"]) sleep 1 MetricsService.record("pacman service #{method.to_s.upcase} request to #{url}", From f1dfb991c7310832c0774eaec3b00daf4d4a5f04 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 17:04:37 -0400 Subject: [PATCH 259/308] APPEALS-21118 fixed vbms destination factory validations --- spec/factories/vbms_distribution_destination.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb index 699bd75ce56..0dd3b64bd9f 100644 --- a/spec/factories/vbms_distribution_destination.rb +++ b/spec/factories/vbms_distribution_destination.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :vbms_distribution_destination do + association :vbms_distribution, factory: :vbms_distribution address_line_1 { "POSTMASTER GENERAL" } address_line_2 { "UNITED STATES POSTAL SERVICE" } address_line_3 { "475 LENFANT PLZ SW RM 10022" } @@ -9,17 +10,16 @@ address_line_5 { "APO AE 09001-5275" } address_line_6 { nil } city { "WASHINGTON DC" } - country_code { "us" } + country_code { "US" } country_name { "UNITED STATES" } created_at { Time.zone.now } created_by_id { nil } - destination_type { "physicalAddress" } + destination_type { "domesticAddress" } postal_code { "12345" } state { "DC" } treat_line_2_as_addressee { true } treat_line_3_as_addressee { true } updated_at { Time.zone.now } updated_by_id { nil } - vbms_distribution_id { nil } end end From 55f6fcc1683edea952d856c0d4e7063fab22abf0 Mon Sep 17 00:00:00 2001 From: j-n-t-l <611441@bah.com> Date: Wed, 28 Jun 2023 17:10:16 -0400 Subject: [PATCH 260/308] APPEALS-21118 fixed document_referenced document_version_reference_id --- app/jobs/mail_request_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index e6b251e4327..da706991232 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -24,7 +24,7 @@ def perform(vbms_uploaded_document, mail_package) package_response = PacmanService.send_communication_package_request( vbms_uploaded_document.veteran_file_number, get_package_name(vbms_uploaded_document), - document_referenced(vbms_uploaded_document.id, mail_package[:copies]) + document_referenced(vbms_uploaded_document.document_version_reference_id, mail_package[:copies]) ) log_info(package_response) rescue Caseflow::Error::PacmanApiError => error From 30cc5043cb56b43fc2f88e2ffc075474c6aca8c7 Mon Sep 17 00:00:00 2001 From: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Date: Wed, 28 Jun 2023 21:50:10 -0400 Subject: [PATCH 261/308] hearings/APPEALS-21118 and APPEALS-21121 APPEALS-21123 (#18814) * branch init * Appeals-21123 updated create method in upload_vbms_document_controller to utilize distribution/destination params * Appeals-21123 updated error.rb, providing a new error type that can be sent back to IDT client. * linting changes to exiting lines of code. Added new error for use in vbms_document_upload_controller when expected params aren't included * APPEALS-21123 created new mail_request class that will handle object creation and also keep controller thin. * APPEALS-21118 created job file * APPEALS-21118 added pacman calls * APPEALS-21118 updated response * APPEALS-21118 added error handling * APPEALS-21118 extra logging and added rspec file * APPEALS-21118 added fakes for vbms package, dist, and dist dest * APPEALS-21118 updated factories and rspec * APPEALS-21123 included activeModel valitations. provided Logic for validation within mailrequest.rb * added conditional logic for param checking and object creation along with error logging. * cleaned up controller code. leaving majority of logic to the new mail_request.rb workflow. * logic implemented that creates a vbms_distribution and vbms_distribution_destination. currenlty raw JSON is being saved(no parsing of the values). * Passed MailRequest object and VBMS document to MailRequestJob * removed email/phone number param checks and validation logic. * created factory to help with specs for mail_request workflow. * removed the optional attribute on the belongs_to relationship expressed in the beginning of the file. * Passed MailObject to MailObjectJob after successful VBMS document upload: * Undid changes yet to be merged from APPEALS-21123 * Used uploaded_to_vbms_at property instead of processed_at * Added tentative unit tests to UploadDocumentToVbmsJob * Incorporated new recipient_info param * Refactored to reflect change to array of multiple recipients * Simplified workflow in anticipation of changes to AC * inserted conditional logic. providing expected behavior as stated by the AC. * chaged constant array to anticipate nested params. * added test in controller to check for creation of mail req object * factories for valid mail request object and invalid mail request object created. * Refactored mail_request default value * Added logging * Refactored UploadVbmsDocumentController#create to be more DRY * Refactored private methods * Changed variable names * Changed method names to be more descriptive * Changed mail_request back to object instead of array of objects to meet new AC * Completed unit test * APPEALS-21123 provided functionality for multiple recipient_info parameters. * APPEALS-21123 removed frozen array. made adjustments to init method. place create methods under the private keyword. * APPEALS-21123 spec clean-up. * Updated unit tests with instance and class doubles * APPEALS-21118 updated perform method parameters * APPEALS-21123 controller fixed to return distribution_ids along with message as JSON * Fixed spacing in rails log message * APPEALS-21123 made edit to missing_recipient_info error in file. * added begin/ensure blocks. providing functionality that will allow code to continue even if an exception rises. * updated logic in file adding and additional attribute to the accessor block. * APPEALS-21123 added code to handle incomplete params. * APPEALS-21123 added accessors. adjusted call method. * APPEALS-21123 added code to handle incomplete params. * APPEALS-21118 updated create_distribution with recipient and destination hashes * APPEALS-21118 added comments to methods * added comments to new code for possible future dev support. * Refactored controller * Abstracted validations into a shared concern to make available to MailRequest object * APPEALS-21123 controller testing completed. Changes made to mail_request factory. MailRequest spec is created. * Added comments * spec updates, comment change in controller. * method refactor * Updated controller to validate copies and pass to MailRequestJob * validation methods updated * spec changes, All Green, appropriate codecoverage. edit to one of the validations in mail_request file.Update the factory for mail_request as well * Changed name of method * Use concern * Merged APPEALS-21121 and APPEALS-21123 in UploadVbmsDocumentController * Uncommented out arguments * Refactored code in controller and fixed formatting of error messages * Fixed issue of global variable in mail request validator * Fixed so it only checks for recipient errors after mapping through all recipients instead of erroring out at first invalid request * Implemented tap method to consolidate code * Consolidated mail_requests and copies params into one payload to pass through workflow * Condensed number of arguments for upload job into a parameter object * Fixed line too long in distribution destination spec * Removing instance variables to comply with reek * Refactor params to resolve reek issues * Rolled back refactoring changes * Removed unnecessary method * Fixed linting * Reformated instance variables * One last shot at fixing reek parameters issuegit add . * Fixed error and updated spec * Fixed spacing in base controller * APPEALS-21118 added to rspec * changes made to mail_request syntax. * Updated spec to account for MailRequestJob queue * Oops * updated mail_request method to set the created_by_id attribute of a created vbms_distribution at the time of creation. * APPEALS-21118 updated mail_request usage * Created MailPackageConcern and refactored controller to implement concern * Updated spec files to reflect introduction of MailRequestJob * Refactored mail package concern to remove unnecessary included_do black * Added created_by_id to mail package payload * Convert mail requests to json instead of array of mail requests to json * APPEALS-21118 fixed parameters * APPEALS-21118 organized comments * Updated spec file * Changed comment * APPEALS-21118 fakes->externalapi * made rubocop changes in spec file. * Remove deprecated URI.escape method * Key name to camelCase * APPEALS-21118 fixed code based on feedback * provided changes to spec files per PR request. Also Fixed failing tests in MailRequestSpec. * Add some lint ignores to methods that will no need to change * APPEALS-21118 error handling changes * APPEALS-21118 removed fakes * APPEALS-21118 removed unnecessary error handling * APPEALS-21118 updated rspec * APPEALS-21118 PacMan -> Pacman * APPEALS-21118 fixed current_user in rspec * Corrected validation on copies attribute of VbmsCommunicationPackage * Correct unit test for VbmsDistribution to reflect optional communication package * APPEALS-21118 fixed pacman service spec: participant_id to participantId * updated failing tests. Green is Go. * Add early return * Remove mocks * APPEALS-21118 fixed vbms factories * APPEALS-21118 pacman service rspec changes * APPEALS-21118 get_distribution_request in pacmanservice should take in int not string * APPEALS-21118 pacmanservice spec: fixed get distribution tests by changing distribution id and communicationpackageid from string to int * CC Fixes * APPEALS-21118 moved vbms package creation into begin block * APPEALS-21118 initilialized PacmanApiError * APPEALS-21118 removed chunk of comments * APPEALS-21118 fixed vbms comm package factory * APPEALS-21118 changed rspec * APPEALS-21118 added 500 error to error code hash * APPEALS-21118 moved package creation outside of begin block * APPEALS-21118 package is created only if post request is successful * APPEALS-21118 put code outside begin rescue block in else statement and added/updated test for unsuccessful execution of mailrequestjob * Spec test tweaks * Use bearer token * APPEALS-21118 fixed vbms destination factory validations * APPEALS-21118 fixed document_referenced document_version_reference_id --------- Co-authored-by: Jonathan Cohen Co-authored-by: j-n-t-l <611441@bah.com> Co-authored-by: Jeff Marks Co-authored-by: Jonathan Cohen <121630615+JCohDev@users.noreply.github.com> Co-authored-by: Matthew Thornton --- .rubocop.yml | 4 + .../concerns/mail_package_concern.rb | 82 ++++++++ app/controllers/idt/api/v1/base_controller.rb | 18 +- .../api/v1/upload_vbms_document_controller.rb | 79 +++++--- .../idt/api/v2/distributions_controller.rb | 11 +- app/jobs/mail_request_job.rb | 171 +++++++++++++++++ app/jobs/upload_document_to_vbms_job.rb | 39 +++- app/models/vbms_communication_package.rb | 2 +- app/models/vbms_distribution.rb | 15 +- app/models/vbms_distribution_destination.rb | 46 +---- app/services/external_api/pacman_service.rb | 11 +- app/validators/mail_request_validator.rb | 76 ++++++++ app/workflows/mail_request.rb | 177 ++++++++++++++++++ .../prepare_document_upload_to_vbms.rb | 37 ++-- app/workflows/upload_document_to_vbms.rb | 6 + config/environments/test.rb | 2 +- config/initializers/pacman.rb | 2 +- lib/caseflow/error.rb | 6 +- lib/fakes/pacman_service.rb | 4 +- .../upload_vbms_document_controller_spec.rb | 123 +++++++++++- .../api/v2/distributions_controller_spec.rb | 12 +- spec/factories/mail_request.rb | 24 +++ spec/factories/vbms_communication_package.rb | 15 ++ spec/factories/vbms_distribution.rb | 19 ++ .../vbms_distribution_destination.rb | 25 +++ spec/jobs/mail_request_job_spec.rb | 45 +++++ spec/jobs/upload_document_to_vbms_job_spec.rb | 37 +++- .../models/vbms_communication_package_spec.rb | 6 +- .../vbms_distribution_destination_spec.rb | 3 +- spec/models/vbms_distribution_spec.rb | 5 +- .../external_api/pacman_service_spec.rb | 16 +- spec/workflows/mail_request_spec.rb | 74 ++++++++ 32 files changed, 1054 insertions(+), 138 deletions(-) create mode 100644 app/controllers/concerns/mail_package_concern.rb create mode 100644 app/jobs/mail_request_job.rb create mode 100644 app/validators/mail_request_validator.rb create mode 100644 app/workflows/mail_request.rb create mode 100644 spec/factories/mail_request.rb create mode 100644 spec/factories/vbms_communication_package.rb create mode 100644 spec/factories/vbms_distribution.rb create mode 100644 spec/factories/vbms_distribution_destination.rb create mode 100644 spec/jobs/mail_request_job_spec.rb create mode 100644 spec/workflows/mail_request_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 7ef1e76199f..8a486b6dcc0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -72,6 +72,10 @@ Rails/LexicallyScopedActionFilter: Rails/SkipsModelValidations: Enabled: false +Rails/ApplicationController: + Exclude: + - app/controllers/idt/api/v1/base_controller.rb + Rails/FilePath: Enabled: false diff --git a/app/controllers/concerns/mail_package_concern.rb b/app/controllers/concerns/mail_package_concern.rb new file mode 100644 index 00000000000..12461498df3 --- /dev/null +++ b/app/controllers/concerns/mail_package_concern.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +# shared code for building mail packages to submit to Package Manager external service + +module MailPackageConcern + extend ActiveSupport::Concern + + private + + def recipient_info + params[:recipient_info] + end + + def copies + # Default value of 1 for copies + return 1 if params[:copies].blank? + + params[:copies] + end + + def mail_package + return nil if recipient_info.blank? + + { distributions: json_mail_requests, copies: copies, created_by_id: user.id } + end + + # Purpose: - Creates and validates a MailRequest object for each recipient + # - Calls #call method on each MailRequest to save corresponding VbmsDistirbution and + # VbmsDistributionDestination to the db + # - Stores the distribution IDs (to be returned to the IDT user as an immediate means of tracking + # each distribution) + # + def build_mail_package + return if recipient_info.blank? + + throw_error_if_copies_out_of_range + mail_requests.map do |request| + request.call + distribution_ids << request.vbms_distribution_id + end + end + + def mail_requests + @mail_requests ||= create_mail_requests_and_track_errors + end + + def json_mail_requests + mail_requests.map(&:to_json) + end + + def create_mail_requests_and_track_errors + requests = recipient_info.map.with_index do |recipient, idx| + MailRequest.new(recipient).tap do |request| + if request.invalid? + recipient_errors["distribution #{idx + 1}"] = request.errors.full_messages.join(", ") + end + end + end + throw_error_if_recipient_info_invalid + requests + end + + def throw_error_if_copies_out_of_range + unless (1..500).cover?(copies) + fail Caseflow::Error::MissingRecipientInfo, "Copies must be between 1 and 500 (inclusive)".to_json + end + end + + def throw_error_if_recipient_info_invalid + return unless recipient_errors.any? + + fail Caseflow::Error::MissingRecipientInfo, recipient_errors.to_json + end + + def recipient_errors + @recipient_errors ||= {} + end + + def distribution_ids + @distribution_ids ||= [] + end +end diff --git a/app/controllers/idt/api/v1/base_controller.rb b/app/controllers/idt/api/v1/base_controller.rb index 8b2f72cf16f..03fd90fe8d4 100644 --- a/app/controllers/idt/api/v1/base_controller.rb +++ b/app/controllers/idt/api/v1/base_controller.rb @@ -16,7 +16,9 @@ class Idt::Api::V1::BaseController < ActionController::Base if error.class.method_defined?(:serialize_response) render(error.serialize_response) else - render json: { message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" }, status: :internal_server_error + render json: { + message: "IDT Standard Error ID: " + uuid + " Unexpected error: #{error.message}" + }, status: :internal_server_error end end # :nocov: @@ -32,7 +34,19 @@ class Idt::Api::V1::BaseController < ActionController::Base log_error(error) uuid = SecureRandom.uuid Rails.logger.error("IDT Standard Error ID: " + uuid) - render(json: { message: "IDT Standard Error ID: " + uuid + " Please enter a file number in the 'FILENUMBER' header" }, status: :unprocessable_entity) + render(json: + { message: + "IDT Standard Error ID: " + + uuid + + " Please enter a file number in the 'FILENUMBER' header" }, + status: :unprocessable_entity) + end + + rescue_from Caseflow::Error::MissingRecipientInfo do |error| + log_error(error) + uuid = SecureRandom.uuid + render(json: { message: "IDT Exception ID: " + uuid + " Recipient information received was invalid or incomplete.", + errors: JSON.parse(error.message) }, status: :bad_request) end rescue_from Caseflow::Error::VeteranNotFound do |error| diff --git a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb index a0ac88a66a2..a3b6aa80834 100644 --- a/app/controllers/idt/api/v1/upload_vbms_document_controller.rb +++ b/app/controllers/idt/api/v1/upload_vbms_document_controller.rb @@ -2,40 +2,73 @@ class Idt::Api::V1::UploadVbmsDocumentController < Idt::Api::V1::BaseController include ApiRequestLoggingConcern + include MailPackageConcern protect_from_forgery with: :exception skip_before_action :verify_authenticity_token, only: [:create] before_action :verify_access - def bgs - @bgs ||= BGSService.new - end - def create - appeal = nil - # Find veteran from appeal id and check with db - if params["appeal_id"].present? - appeal = LegacyAppeal.find_by_vacols_id(params["appeal_id"]) || Appeal.find_by_uuid(params["appeal_id"]) - if appeal.nil? - fail Caseflow::Error::AppealNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The appeal was unable to be found." - else - params["veteran_file_number"] = appeal.veteran_file_number - end - - else - file_number = bgs.fetch_veteran_info(params["veteran_identifier"])&.dig(:file_number) || bgs.fetch_file_number_by_ssn(params["veteran_identifier"]) - if file_number.nil? - fail Caseflow::Error::VeteranNotFound, "IDT Standard Error ID: " + SecureRandom.uuid + " The veteran was unable to be found." - end + # Create distributions for Package Manager mail service if recipient info present + build_mail_package - params["veteran_file_number"] = file_number - end - result = PrepareDocumentUploadToVbms.new(params, current_user, appeal).call + result = PrepareDocumentUploadToVbms.new(params, current_user, appeal, mail_package).call if result.success? - render json: { message: "Document successfully queued for upload." } + success_message = { message: "Document successfully queued for upload." } + if recipient_info.present? + success_message[:distribution_ids] = distribution_ids + end + render json: success_message else render json: result.errors[0], status: :bad_request end end + + private + + # Find veteran from appeal id and check with db + def appeal + if appeal_id.blank? + find_file_number_by_veteran_identifier + return nil + end + + @appeal ||= find_veteran_by_appeal_id + end + + def appeal_id + params[:appeal_id] + end + + def veteran_identifier + params[:veteran_identifier] + end + + def bgs + @bgs ||= BGSService.new + end + + def find_veteran_by_appeal_id + appeal = LegacyAppeal.find_by_vacols_id(appeal_id) || Appeal.find_by_uuid(appeal_id) + throw_not_found_error(Caseflow::Error::AppealNotFound, "appeal") if appeal.nil? + update_veteran_file_number(appeal.veteran_file_number) + appeal + end + + def find_file_number_by_veteran_identifier + file_number = bgs.fetch_veteran_info(veteran_identifier)&.dig(:file_number) || + bgs.fetch_file_number_by_ssn(veteran_identifier) + throw_not_found_error(Caseflow::Error::VeteranNotFound, "veteran") if file_number.nil? + update_veteran_file_number(file_number) + end + + def update_veteran_file_number(file_number) + params["veteran_file_number"] = file_number + end + + def throw_not_found_error(error, name) + uuid = SecureRandom.uuid + fail error, uuid + " The #{name} was unable to be found." + end end diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index c0d9182974f..384a5fcd416 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -15,8 +15,8 @@ def get_distribution end begin - # Retrieves the distribution package from the PacMan API - distribution = PacManService.get_distribution_request(distribution_id) + # Retrieves the distribution package from the Pacman API + distribution = PacmanService.get_distribution_request(distribution_id) response_code = distribution.code if response_code != 200 fail StandardError @@ -35,6 +35,8 @@ def get_distribution render json: format_response(distribution) end + private + def pending_establishment(distribution_id) render json: { id: distribution_id, status: "PENDING_ESTABLISHMENT" }, status: :ok end @@ -48,14 +50,13 @@ def format_response(response) end end - private - - # Checks if the distribution exists in the database before sending request to PacMan + # Checks if the distribution exists in the database before sending request to Pacman def valid_id?(distribution_id) VbmsDistribution.exists?(id: distribution_id) end # Renders errors and logs and tracks the here within Raven + # :reek:FeatureEnvy def render_error(status, message, distribution_id) error_uuid = SecureRandom.uuid error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb new file mode 100644 index 00000000000..da706991232 --- /dev/null +++ b/app/jobs/mail_request_job.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true + +class MailRequestJob < CaseflowJob + queue_with_priority :low_priority + application_attr :api + + # Purpose: performs job + # + # takes in VbmsUploadedDocument object and JSON payload + # mail_package looks like this: + # { + # "distributions": [ + # { + # "recipient_info": json of MailRequest object + # } + # ] + # "copies": integer value, + # "created_by_id": integer value + # } + # + # Response: n/a + def perform(vbms_uploaded_document, mail_package) + begin + package_response = PacmanService.send_communication_package_request( + vbms_uploaded_document.veteran_file_number, + get_package_name(vbms_uploaded_document), + document_referenced(vbms_uploaded_document.document_version_reference_id, mail_package[:copies]) + ) + log_info(package_response) + rescue Caseflow::Error::PacmanApiError => error + log_error(error) + else + vbms_comm_package = create_package(vbms_uploaded_document, mail_package) + vbms_comm_package.update!(status: "success") + create_distribution_request(vbms_comm_package.id, mail_package) + end + end + + private + + # Purpose: arranges id and copies to pass into package post request + # + # takes in VbmsUploadedDocument id and copies integer + # + # Response: Array of json with document id and copies + def document_referenced(doc_id, copies) + [{ "id": doc_id, "copies": copies }] + end + + # Purpose: Creates new VbmsCommunicationPackage + # + # takes in VbmsUploadedDocument object and MailRequest object + # + # Response: new VbmsCommunicationPackage object + # :reek:FeatureEnvy + def create_package(vbms_uploaded_document, mail_package) + VbmsCommunicationPackage.new( + comm_package_name: get_package_name(vbms_uploaded_document), + created_at: Time.zone.now, + created_by_id: mail_package[:created_by_id], + copies: mail_package[:copies], + file_number: vbms_uploaded_document.veteran_file_number, + status: nil, + updated_at: Time.zone.now, + updated_by_id: mail_package[:created_by_id], + vbms_uploaded_document_id: vbms_uploaded_document.id + ) + end + + def get_package_name(vbms_uploaded_document) + "#{vbms_uploaded_document.document_name}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" + end + + # Purpose: sends distribution POST request to Pacman API + # + # takes in VbmsCommunicationPackage id (string) and MailRequest object + # + # Response: n/a + def create_distribution_request(package_id, mail_package) + distributions = mail_package[:distributions] + distributions.each do |dist| + begin + dist_hash = JSON.parse(dist) + rescue Caseflow::Error::PacmanApiError => error + log_error(error) + else + distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) + distribution_response = PacmanService.send_distribution_request( + package_id, + get_recipient_hash(distribution), + get_destinations_hash(dist_hash) + ) + log_info(distribution_response) + distribution.update!(vbms_communication_package_id: package_id) + end + end + end + + # Purpose: creates recipient hash from VbmsDistribution attributes + # + # takes in VbmsDistribution object + # + # Response: hash that is needed in Pacman API distribution POST requests + def get_recipient_hash(distribution) + { + type: distribution.recipient_type, + name: distribution.name, + firstName: distribution.first_name, + middleName: distribution.middle_name, + lastName: distribution.last_name, + participantId: distribution.participant_id, + poaCode: distribution.poa_code, + claimantStationOfJurisdiction: distribution.claimant_station_of_jurisdiction + } + end + + # Purpose: creates destination hash from VbmsDistributionDestination attributes + # + # takes in VbmsDistributionDestination object + # + # Response: array that holds a hash + def get_destinations_hash(destination) + [{ + "type" => destination["destination_type"], + "addressLine1" => destination["address_line_1"], + "addressLine2" => destination["address_line_2"], + "addressLine3" => destination["address_line_3"], + "addressLine4" => destination["address_line_4"], + "addressLine5" => destination["address_line_5"], + "addressLine6" => destination["address_line_6"], + "treatLine2AsAddressee" => destination["treat_line_2_as_addressee"], + "treatLine3AsAddressee" => destination["treat_line_3_as_addressee"], + "city" => destination["city"], + "state" => destination["state"], + "postalCode" => destination["postal_code"], + "countryName" => destination["country_name"], + "countryCode" => destination["country_code"] + }] + end + + # Purpose: logging error in Rails and in Raven + # + # takes in error message (string) + # + # Response: n/a + def log_error(error) + uuid = SecureRandom.uuid + Rails.logger.error(ERROR_MESSAGES[error.code] + "Error ID: " + uuid) + Raven.capture_exception(error, extra: { error_uuid: uuid }) + end + + ERROR_MESSAGES = { + 400 => "400 PacmanBadRequestError The server cannot create the new communication package due to a client error.", + 403 => "403 PacmanForbiddenError The server cannot create the new communication package" \ + "due to insufficient privileges.", + 404 => "404 PacmanNotFoundError The communication package could not be found but may be available" \ + "again in the future. Subsequent requests by the client are permissible.", + 500 => "500 PacmanInternalServerError The request was unable to be completed." + }.freeze + + # Purpose: logs information in Rails logger + # + # takes in info message (string) + # + # Response: n/a + def log_info(info_message) + uuid = SecureRandom.uuid + info_message.body.uuid = uuid + Rails.logger.info(info_message) + end +end diff --git a/app/jobs/upload_document_to_vbms_job.rb b/app/jobs/upload_document_to_vbms_job.rb index fa66a304c83..e0337e31ad4 100644 --- a/app/jobs/upload_document_to_vbms_job.rb +++ b/app/jobs/upload_document_to_vbms_job.rb @@ -8,21 +8,37 @@ class UploadDocumentToVbmsJob < CaseflowJob # Params: document_id - integer to search for VbmsUploadedDocument # initiator_css_id - string to find a user by css_id # application - string with a default value of "idt" but can be overwritten + # mail_package - Payload with distributions value (array of JSON-formatted MailRequest objects), + # copies value (integer), and created_by_id value (integer) to be submitted to + # Package Manager if optional recipient info is present # # Return: nil - def perform(document_id:, initiator_css_id:, application: "idt") + def perform(params) + @params = params RequestStore.store[:application] = application RequestStore.store[:current_user] = User.system_user - - @document = VbmsUploadedDocument.find_by(id: document_id) - @initiator = User.find_by_css_id(initiator_css_id) + @document = VbmsUploadedDocument.find(params[:document_id]) + @initiator = User.find_by_css_id(params[:initiator_css_id]) add_context_to_sentry UploadDocumentToVbms.new(document: document).call + queue_mail_request_job(mail_package) unless mail_package.nil? end private - attr_reader :document, :initiator + attr_reader :document, :initiator, :params + + def application + return "idt" if params[:application].blank? + + params[:application] + end + + def mail_package + return nil if params[:mail_package].blank? + + params[:mail_package] + end def add_context_to_sentry if initiator.present? @@ -39,4 +55,17 @@ def add_context_to_sentry veteran_file_number: document.veteran_file_number ) end + + def queue_mail_request_job(mail_package) + return unless document.uploaded_to_vbms_at + + MailRequestJob.perform_later(document, mail_package) + info_message = "MailRequestJob for document #{document.id} queued for submission to Package Manager" + log_info(info_message) + end + + def log_info(info_message) + uuid = SecureRandom.uuid + Rails.logger.info(info_message + " ID: " + uuid) + end end diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 5a139dd6600..21d4d4bb290 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -6,5 +6,5 @@ class VbmsCommunicationPackage < CaseflowRecord validates :file_number, :comm_package_name, :copies, presence: true validates :comm_package_name, length: { in: 1..255 }, format: { with: /\A[\w !*+,-.:;=?]{1,255}\Z/ } - validates :copies, length: { in: 1..500 } + validates :copies, numericality: { only_integer: true, greater_than: 0, less_than: 501 } end diff --git a/app/models/vbms_distribution.rb b/app/models/vbms_distribution.rb index 4902b568eac..f7af0f5ef39 100644 --- a/app/models/vbms_distribution.rb +++ b/app/models/vbms_distribution.rb @@ -1,17 +1,8 @@ # frozen_string_literal: true class VbmsDistribution < CaseflowRecord - belongs_to :vbms_communication_package, optional: false - has_many :vbms_distribution_destinations - - with_options presence: true do - validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } - validates :first_name, :last_name, if: -> { recipient_type == "person" } - validates :name, if: :not_a_person? - validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } - end + include MailRequestValidator::Distribution - def not_a_person? - %w[organization system ro-colocated].include?(recipient_type) - end + belongs_to :vbms_communication_package + has_many :vbms_distribution_destinations end diff --git a/app/models/vbms_distribution_destination.rb b/app/models/vbms_distribution_destination.rb index f6fc5c785ad..80bbd6b1730 100644 --- a/app/models/vbms_distribution_destination.rb +++ b/app/models/vbms_distribution_destination.rb @@ -1,49 +1,7 @@ # frozen_string_literal: true class VbmsDistributionDestination < CaseflowRecord - belongs_to :vbms_distribution, optional: false - - with_options presence: true do - validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } - validates :address_line_1, :city, :country_code, if: :physical_mail? - validates :address_line_2, if: :treat_line_2_as_addressee - validates :address_line_3, if: :treat_line_3_as_addressee - validates :state, :postal_code, if: :us_address? - validates :country_name, if: -> { destination_type == "internationalAddress" } - end - - validates :treat_line_2_as_addressee, - inclusion: { in: [true], message: "cannot be false if line 3 is treated as addressee" }, - if: -> { treat_line_3_as_addressee == true } - - validate :valid_country_code?, if: :physical_mail? - validate :valid_us_state_code?, if: :us_address? - - def physical_mail? - %w[domesticAddress internationalAddress militaryAddress].include?(destination_type) - end + include MailRequestValidator::DistributionDestination - def us_address? - %w[domesticAddress militaryAddress].include?(destination_type) - end - - def valid_country_code? - unless iso_country_codes.include?(country_code) - errors.add(:country_code, "is not a valid ISO 3166-2 code") - end - end - - def valid_us_state_code? - unless iso_us_state_codes.include?(state) - errors.add(:state, "is not a valid ISO 3166-2 code") - end - end - - def iso_country_codes - @iso_country_codes ||= ISO3166::Country.codes - end - - def iso_us_state_codes - @iso_us_state_codes ||= ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys - end + belongs_to :vbms_distribution, optional: false end diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 4b6691de208..5843cb178f8 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -44,13 +44,13 @@ def send_distribution_request(package_id, recipient, destinations) # Purpose: Gets distribution from distribution id # POST: /package-manager-service/distribution # - # takes in distribution_id(string) + # takes in distribution_id(int) # # Response: JSON of distribution from Pacman API # Example response can be seen in lib/fakes/pacman_service.rb under 'fake_distribution_response' method def get_distribution_request(distribution_id) request = { - endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id, method: :get + endpoint: GET_DISTRIBUTION_ENDPOINT + distribution_id.to_s, method: :get } send_pacman_request(request) end @@ -108,7 +108,7 @@ def recipient_data(recipient) firstName: recipient[:first_name], middleName: recipient[:middle_name], lastName: recipient[:last_name], - participant_id: recipient[:participant_id], + participantId: recipient[:participant_id], poaCode: recipient[:poa_code], claimantStationOfJurisdiction: recipient[:claimant_station_of_jurisdiction] } @@ -143,14 +143,15 @@ def destinations_data(destination) # Params: general requirements for HTTP request # # Return: service_response: JSON from Pacman or error + # :reek:LongParameterList def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) - url = URI.escape(BASE_URL + endpoint) + url = ERB::Util.url_encode(BASE_URL + endpoint) request = HTTPI::Request.new(url) request.open_timeout = 30 request.read_timeout = 30 request.body = body.to_json unless body.nil? # not sure how user validation will be handled - request.headers = headers.merge(apikey: ENV["PACMAN_API_KEY"]) + request.headers = headers.merge(Bearer: ENV["PACMAN_API_KEY"]) sleep 1 MetricsService.record("pacman service #{method.to_s.upcase} request to #{url}", diff --git a/app/validators/mail_request_validator.rb b/app/validators/mail_request_validator.rb new file mode 100644 index 00000000000..3f3acbcc273 --- /dev/null +++ b/app/validators/mail_request_validator.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module MailRequestValidator + # Validations for VbmsDistribution model and MailRequest object + module Distribution + extend ActiveSupport::Concern + + included do + with_options presence: true do + validates :recipient_type, inclusion: { in: %w[organization person system ro-colocated] } + validates :first_name, :last_name, if: -> { recipient_type == "person" } + validates :name, if: :not_a_person? + validates :poa_code, :claimant_station_of_jurisdiction, if: -> { recipient_type == "ro-colocated" } + end + end + + private + + def not_a_person? + %w[organization system ro-colocated].include?(recipient_type) + end + end + + # Validations for VbmsDistributionDestination model and MailRequest object + module DistributionDestination + extend ActiveSupport::Concern + + included do + with_options presence: true do + validates :destination_type, inclusion: { in: %w[domesticAddress internationalAddress militaryAddress derived] } + validates :address_line_1, :city, :country_code, if: :physical_mail? + validates :address_line_2, if: :treat_line_2_as_addressee + validates :address_line_3, if: :treat_line_3_as_addressee + validates :state, :postal_code, if: :us_address? + validates :country_name, if: -> { destination_type == "internationalAddress" } + end + + validates :treat_line_2_as_addressee, + inclusion: { in: [true], message: "cannot be false if line 3 is treated as addressee" }, + if: -> { treat_line_3_as_addressee == true } + + validate :valid_country_code?, if: :physical_mail? + validate :valid_us_state_code?, if: :us_address? + end + + private + + def physical_mail? + %w[domesticAddress internationalAddress militaryAddress].include?(destination_type) + end + + def us_address? + %w[domesticAddress militaryAddress].include?(destination_type) + end + + def valid_country_code? + unless iso_country_codes.include?(country_code) + errors.add(:country_code, "is not a valid ISO 3166-2 code") + end + end + + def valid_us_state_code? + unless iso_us_state_codes.include?(state) + errors.add(:state, "is not a valid ISO 3166-2 code") + end + end + + def iso_country_codes + ISO3166::Country.codes + end + + def iso_us_state_codes + ISO3166::Country.find_country_by_alpha2("US").subdivisions.keys + end + end +end diff --git a/app/workflows/mail_request.rb b/app/workflows/mail_request.rb new file mode 100644 index 00000000000..81da60840b4 --- /dev/null +++ b/app/workflows/mail_request.rb @@ -0,0 +1,177 @@ +# frozen_string_literal: true + +class MailRequest + include ActiveModel::Model + include ActiveModel::Validations + + include MailRequestValidator::Distribution + include MailRequestValidator::DistributionDestination + + attr_reader :vbms_distribution_id, :comm_package_id + + # Purpose: initializes a mail_request object making use of the passed in hash and also initializing + # the attributes of vbms_distribution_id and a comm_package_id. Both set to nil until set + # otherwise. + # + # Params: recipient_and_destination_hash - expected parameters that that hold information + # that will be used to create a valid VbmsDistribution and valid VbmsDistributionDestination. + # + # Return: nil + def initialize(recipient_and_destination_hash) + @recipient_info = recipient_and_destination_hash + @vbms_distribution_id = nil + @comm_package_id = nil + end + + # Purpose: With the passed in parameters, the call method creates both a valid VBMSDistribution and + # valid VBMSDistributionDestination. If there is an error it will fail and that information will be provided + # to the IDT user. + # + def call + if valid? + distribution = create_a_vbms_distribution + @vbms_distribution_id = distribution.id + create_a_vbms_distribution_destination + else + fail Caseflow::Error::MissingRecipientInfo + end + end + + private + + def create_a_vbms_distribution + VbmsDistribution.create!(recipient_params_parse) + end + + def create_a_vbms_distribution_destination + VbmsDistributionDestination.create!(destination_params_parse) + end + + def destination_params_parse + { + destination_type: destination_type, + address_line_1: address_line_1, + address_line_2: address_line_2, + address_line_3: address_line_3, + address_line_4: address_line_4, + address_line_5: address_line_5, + address_line_6: address_line_6, + city: city, + country_code: country_code, + postal_code: postal_code, + state: state, + treat_line_2_as_addressee: treat_line_2_as_addressee, + treat_line_3_as_addressee: treat_line_3_as_addressee, + country_name: country_name, + vbms_distribution_id: vbms_distribution_id + } + end + + def recipient_params_parse + { + recipient_type: recipient_type, + name: name, + first_name: first_name, + middle_name: middle_name, + last_name: last_name, + participant_id: participant_id, + poa_code: poa_code, + claimant_station_of_jurisdiction: claimant_station_of_jurisdiction, + created_by_id: RequestStore[:current_user].id + } + end + + def recipient_type + @recipient_info[:recipient_type] + end + + def name + @recipient_info[:name] + end + + def first_name + @recipient_info[:first_name] + end + + def middle_name + @recipient_info[:middle_name] + end + + def last_name + @recipient_info[:last_name] + end + + def participant_id + @recipient_info[:participant_id] + end + + def poa_code + @recipient_info[:poa_code] + end + + def claimant_station_of_jurisdiction + @recipient_info[:claimant_station_of_jurisdiction] + end + + def destination_type + @recipient_info[:destination_type] + end + + # :reek:UncommunicativeMethodName + def address_line_1 + @recipient_info[:address_line_1] + end + + # :reek:UncommunicativeMethodName + def address_line_2 + @recipient_info[:address_line_2] + end + + # :reek:UncommunicativeMethodName + def address_line_3 + @recipient_info[:address_line_3] + end + + # :reek:UncommunicativeMethodName + def address_line_4 + @recipient_info[:address_line_4] + end + + # :reek:UncommunicativeMethodName + def address_line_5 + @recipient_info[:address_line_5] + end + + # :reek:UncommunicativeMethodName + def address_line_6 + @recipient_info[:address_line_6] + end + + def city + @recipient_info[:city] + end + + def country_code + @recipient_info[:country_code] + end + + def postal_code + @recipient_info[:postal_code] + end + + def state + @recipient_info[:state] + end + + def treat_line_2_as_addressee + @recipient_info[:treat_line_2_as_addressee] + end + + def treat_line_3_as_addressee + @recipient_info[:treat_line_3_as_addressee] + end + + def country_name + @recipient_info[:country_name] + end +end diff --git a/app/workflows/prepare_document_upload_to_vbms.rb b/app/workflows/prepare_document_upload_to_vbms.rb index f83f59f8ed6..8270e8ca595 100644 --- a/app/workflows/prepare_document_upload_to_vbms.rb +++ b/app/workflows/prepare_document_upload_to_vbms.rb @@ -10,11 +10,15 @@ class PrepareDocumentUploadToVbms # Params: params - hash containing file and document_type at minimum # user - current user that is preparing the document for upload # appeal - Appeal object (optional if ssn or file number are passed into params) - def initialize(params, user, appeal = nil) + # mail_package - Payload with distributions value (array of JSON-formatted MailRequest objects), + # copies value (integer), and created_by_id value (integer) to be submitted to + # Package Manager if optional recipient info is present + # + def initialize(params, user, appeal = nil, mail_package = nil) @params = params.slice(:veteran_file_number, :document_type, :document_subject, :document_name, :file, :application) - @document_type = @params[:document_type] @user = user @appeal = appeal + @mail_package = mail_package end # Purpose: Queues a job to upload a document to vbms @@ -28,11 +32,7 @@ def call @params[:veteran_file_number] = throw_error_if_file_number_not_match_bgs VbmsUploadedDocument.create(document_params).tap do |document| document.cache_file - UploadDocumentToVbmsJob.perform_later( - document_id: document.id, - initiator_css_id: user.css_id, - application: @params[:application] - ) + UploadDocumentToVbmsJob.perform_later(upload_job_params(document)) end end @@ -42,22 +42,26 @@ def call private attr_accessor :success - attr_reader :document_type, :params, :user + attr_reader :params, :user, :mail_package, :document def veteran_file_number - @params[:veteran_file_number] + params[:veteran_file_number] end def document_subject - @params[:document_subject] + params[:document_subject] end def document_name - @params[:document_name] + params[:document_name] end def file - @params[:file] + params[:file] + end + + def document_type + params[:document_type] end def valid_document_type @@ -84,6 +88,15 @@ def document_params } end + def upload_job_params(document) + { + document_id: document.id, + initiator_css_id: user.css_id, + application: params[:application], + mail_package: mail_package + } + end + def response_errors return if success diff --git a/app/workflows/upload_document_to_vbms.rb b/app/workflows/upload_document_to_vbms.rb index dfcda597753..c95b815569d 100644 --- a/app/workflows/upload_document_to_vbms.rb +++ b/app/workflows/upload_document_to_vbms.rb @@ -15,6 +15,7 @@ def call submit_for_processing! upload_to_vbms! set_processed_at_to_current_time + log_info("Document #{document.id} uploaded to VBMS") rescue StandardError => error save_rescued_error!(error.to_s) raise error @@ -88,6 +89,11 @@ 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. # diff --git a/config/environments/test.rb b/config/environments/test.rb index db2c4a78410..f13945cb2ef 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -113,7 +113,7 @@ ENV['TEST_VACOLS_HOST'] ||= "localhost" - # PacMan environment variables + # Pacman environment variables ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov" ENV["PACMAN_API_KEY"] ||= "secret-key" end diff --git a/config/initializers/pacman.rb b/config/initializers/pacman.rb index 9dded20eed5..481795e510d 100644 --- a/config/initializers/pacman.rb +++ b/config/initializers/pacman.rb @@ -1 +1 @@ -PacManService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) +PacmanService = (ApplicationController.dependencies_faked? ? Fakes::PacmanService : ExternalApi::PacmanService) diff --git a/lib/caseflow/error.rb b/lib/caseflow/error.rb index e7601fc7ca3..df77673dd3b 100644 --- a/lib/caseflow/error.rb +++ b/lib/caseflow/error.rb @@ -340,6 +340,7 @@ class MustImplementInSubclass < StandardError; end class AttributeNotLoaded < StandardError; end class VeteranNotFound < StandardError; end class AppealNotFound < StandardError; end + class MissingRecipientInfo < StandardError; end class EstablishClaimFailedInVBMS < StandardError attr_reader :error_code @@ -449,7 +450,10 @@ class VANotifyRateLimitError < VANotifyApiError; end class EmptyQueueError < StandardError; end # Pacman errors - class PacmanApiError < StandardError; end + class PacmanApiError < StandardError + include Caseflow::Error::ErrorSerializer + attr_accessor :code, :message + end class PacmanBadRequestError < PacmanApiError; end class PacmanForbiddenError < PacmanApiError; end class PacmanNotFoundError < PacmanApiError; end diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 395e8090743..a9508ebd393 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -12,7 +12,7 @@ def send_distribution_request(package_id, recipient, destinations) def get_distribution_request(distribution_id) unless VbmsDistribution.exists?(id: distribution_id) - distribution_not_found_response + return distribution_not_found_response end fake_distribution_response(distribution_id) @@ -99,7 +99,7 @@ def fake_distribution_response(distribution_id) "name": "VBMS-C" }, "description": "Staging Mailing Distribution", - "communicationPackageId": "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "communicationPackageId": 1, "destinations": [{ "type": "physicalAddress", "id": "28440040-51a5-4d2a-81a2-28730827be14", diff --git a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb index 0c1b55944e9..33251249622 100644 --- a/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb +++ b/spec/controllers/idt/api/v1/upload_vbms_document_controller_spec.rb @@ -1,18 +1,63 @@ # frozen_string_literal: true RSpec.describe Idt::Api::V1::UploadVbmsDocumentController, :all_dbs, type: :controller do + include ActiveJob::TestHelper + describe "POST /idt/api/v1/appeals/:appeal_id/upload_document" do let(:user) { create(:user) } let(:appeal) { create(:appeal) } let(:veteran) { appeal.veteran } let(:file_number) { appeal.veteran.file_number } + let(:file) { "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW" } let(:valid_document_type) { "BVA Decision" } let(:params) do { appeal_id: appeal.external_id, - file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + file: file, document_type: valid_document_type } end + let(:mail_request_params) do + { veteran_identifier: veteran.file_number, + file: file, + document_type: valid_document_type, + recipient_info: [ + { + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmets", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1235 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "13246", + country_code: "US" + } + ] } + end + + let(:invalid_mail_request_params) do + { veteran_identifier: veteran.file_number, + file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", + document_type: valid_document_type, + recipient_info: [ + { + recipient_type: "person", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + } + ] } + end + let(:params_identifier) do { veteran_identifier: veteran.file_number, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", @@ -115,6 +160,18 @@ end end + context "when the recipient_info parameters are incomplete" do + it "returns a descriptive error to the IDT user" do + expect(Raven).to receive(:capture_exception) + post :create, params: invalid_mail_request_params, as: :json + validation_error_msgs = JSON.parse(response.body)["errors"] + expect(validation_error_msgs).to eq( + "distribution 1" => "First name can't be blank, Last name can't be blank" + ) + expect(response.status).to eq(400) + end + end + context "all parameters are valid" do let(:uploaded_document) { instance_double(VbmsUploadedDocument, id: 1) } let(:document_params) do @@ -123,13 +180,30 @@ appeal_type: appeal.class.name, veteran_file_number: file_number, document_type: params[:document_type], - file: params[:file], + file: file, document_name: nil, document_subject: nil } end shared_examples "success_with_valid_parameters" do + before do + RequestStore.store[:current_user] = User.system_user + end + + it "creates a new Mail Request object when optional params exist" do + expect_any_instance_of(MailRequest).to receive(:call) + post :create, params: mail_request_params, as: :json + end + + it "returns a list of vbms_distribution ids alongside a success message" do + post :create, params: mail_request_params, as: :json + success_message = JSON.parse(response.body)["message"] + success_id = JSON.parse(response.body)["distribution_ids"] + expect(success_message).to eq "Document successfully queued for upload." + expect(success_id).not_to eq([]) + end + it "returns a successful message and creates a new VbmsUploadedDocument" do expect { post :create, params: params }.to change(VbmsUploadedDocument, :count).by(1) @@ -144,7 +218,8 @@ expect(UploadDocumentToVbmsJob).to receive(:perform_later).with( document_id: uploaded_document.id, initiator_css_id: user.css_id, - application: anything + application: anything, + mail_package: nil ) expect(uploaded_document).to receive(:cache_file) @@ -165,6 +240,48 @@ it_behaves_like "success_with_valid_parameters" end end + + context "queues async mail request job" do + let(:recipient_info) { mail_request_params[:recipient_info] } + let(:mail_request) { MailRequest.new(recipient_info[0]) } + let(:mail_package) do + { distributions: [mail_request.to_json], + copies: 1, + created_by_id: user.id } + end + let(:uploaded_document) { create(:vbms_uploaded_document) } + let(:upload_job_params) do + { document_id: uploaded_document.id, + initiator_css_id: user.css_id, + application: nil, + mail_package: mail_package } + end + + context "document is associated with a mail package" do + it "calls #perform_later on MailRequestJob" do + post :create, params: mail_request_params, as: :json + expect(MailRequestJob).to receive(:perform_later) + perform_enqueued_jobs do + UploadDocumentToVbmsJob.perform_later(upload_job_params) + end + end + end + + context "document is not associated with a mail package" do + it "does not call #perform_later on MailRequestJob" do + mail_request_params[:recipient_info] = [] + post :create, params: mail_request_params, as: :json + expect(MailRequestJob).to_not receive(:perform_later) + end + end + + context "recipient info is incorrect" do + it "does not call #perform_later on MailRequestJob" do + post :create, params: invalid_mail_request_params, as: :json + expect(MailRequestJob).to_not receive(:perform_later) + end + end + end end end end diff --git a/spec/controllers/idt/api/v2/distributions_controller_spec.rb b/spec/controllers/idt/api/v2/distributions_controller_spec.rb index e70abf92042..690a6dd06b2 100644 --- a/spec/controllers/idt/api/v2/distributions_controller_spec.rb +++ b/spec/controllers/idt/api/v2/distributions_controller_spec.rb @@ -19,7 +19,7 @@ before do allow(controller).to receive(:params).and_return(distribution_id: distribution_id) allow(VbmsDistribution).to receive(:exists?).with(id: distribution_id).and_return(true) - allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) allow(SecureRandom).to receive(:uuid).and_return(uuid) key, t = Idt::Token.generate_one_time_key_and_proposed_token Idt::Token.activate_proposed_token(key, user.css_id) @@ -43,7 +43,7 @@ end end - context "when PacManService fails with a 404 error" do + context "when PacmanService fails with a 404 error" do let(:distribution_id) { 123_456 } it "renders the expected response with status 200, Pacman api has a 404" do expected_response = { @@ -51,7 +51,7 @@ "status" => "PENDING_ESTABLISHMENT" } - allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do OpenStruct.new(code: 404) end @@ -62,7 +62,7 @@ end end - context "when PacManService fails with a 500 error" do + context "when PacmanService fails with a 500 error" do let(:distribution) { double("Distribution", code: 500) } let(:error_msg) do "[IDT] Http Status Code: 500, Internal Server Error," \ @@ -117,7 +117,7 @@ end before do - allow(PacManService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id).and_return(distribution) end it "returns the expected converted response" do @@ -167,7 +167,7 @@ error_message = "[IDT] Http Status Code: #{status}, #{message}, (Distribution ID: #{distribution_id})" expect(Rails.logger).to receive(:error).with("#{error_message}Error ID: #{uuid}") - allow(PacManService).to receive(:get_distribution_request).with(distribution_id) do + allow(PacmanService).to receive(:get_distribution_request).with(distribution_id) do OpenStruct.new(code: 500) end diff --git a/spec/factories/mail_request.rb b/spec/factories/mail_request.rb new file mode 100644 index 00000000000..256c80ed196 --- /dev/null +++ b/spec/factories/mail_request.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :mail_request do + recipient_type { "person" } + first_name { "Bob" } + last_name { "Smithcole" } + participant_id { "487470002" } + destination_type { "domesticAddress" } + address_line_1 { "1234 Main Street" } + city { "Orlando" } + country_code { "US" } + postal_code { "12345" } + state { "FL" } + treat_line_2_as_addressee { false } + treat_line_3_as_addressee { false } + + trait :nil_recipient_type do + recipient_type { nil } + end + + initialize_with { new(attributes) } + end +end diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb new file mode 100644 index 00000000000..450ad4df740 --- /dev/null +++ b/spec/factories/vbms_communication_package.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_communication_package do + association :vbms_uploaded_document, factory: :vbms_uploaded_document + comm_package_name { "DocumentName_" + Time.zone.now.to_s } + copies { 1 } + created_at { Time.zone.now } + created_by_id { create(:user).id } + file_number { generate :veteran_file_number } + status { nil } + updated_at { Time.zone.now } + updated_by_id { nil } + end +end diff --git a/spec/factories/vbms_distribution.rb b/spec/factories/vbms_distribution.rb new file mode 100644 index 00000000000..b367b6542c3 --- /dev/null +++ b/spec/factories/vbms_distribution.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_distribution do + claimant_station_of_jurisdiction { nil } + created_at { Time.zone.now } + created_by_id { nil } + first_name { "Bob" } + last_name { "Bobjoe" } + middle_name { "Joe" } + name { nil } + participant_id { generate :participant_id } + poa_code { nil } + recipient_type { "person" } + updated_at { Time.zone.now } + updated_by_id { nil } + vbms_communication_package_id { nil } + end +end diff --git a/spec/factories/vbms_distribution_destination.rb b/spec/factories/vbms_distribution_destination.rb new file mode 100644 index 00000000000..0dd3b64bd9f --- /dev/null +++ b/spec/factories/vbms_distribution_destination.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :vbms_distribution_destination do + association :vbms_distribution, factory: :vbms_distribution + address_line_1 { "POSTMASTER GENERAL" } + address_line_2 { "UNITED STATES POSTAL SERVICE" } + address_line_3 { "475 LENFANT PLZ SW RM 10022" } + address_line_4 { "SUITE 123" } + address_line_5 { "APO AE 09001-5275" } + address_line_6 { nil } + city { "WASHINGTON DC" } + country_code { "US" } + country_name { "UNITED STATES" } + created_at { Time.zone.now } + created_by_id { nil } + destination_type { "domesticAddress" } + postal_code { "12345" } + state { "DC" } + treat_line_2_as_addressee { true } + treat_line_3_as_addressee { true } + updated_at { Time.zone.now } + updated_by_id { nil } + end +end diff --git a/spec/jobs/mail_request_job_spec.rb b/spec/jobs/mail_request_job_spec.rb new file mode 100644 index 00000000000..d133139a914 --- /dev/null +++ b/spec/jobs/mail_request_job_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +describe MailRequestJob do + include ActiveJob::TestHelper + let!(:current_user) { User.authenticate! } + let!(:vbms_file) { create(:vbms_uploaded_document) } + let!(:mail_request) { build(:mail_request) } + + context "Successful execution of MailRequestJob" do + it "creates a new VbmsCommunicationPackage" do + mail_request.call + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: current_user.id } + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(1) + + expect(find_comm_package_via_distribution_id(mail_request.vbms_distribution_id).status).to eq("success") + end + end + + context "Unsuccessful execution of MailRequestJob" do + it "VbmsCommunicationPackage is not created. VbmsDistribution's vbms_communication_package_id remains nil." do + mail_request.call + mail_package = { distributions: [mail_request.to_json], copies: 1, created_by_id: current_user.id } + + allow(PacmanService) + .to receive(:send_communication_package_request) + .and_raise(Caseflow::Error::PacmanApiError.new(code: 500, message: "Fake Error")) + + expect do + perform_enqueued_jobs { MailRequestJob.perform_later(vbms_file, mail_package) } + end.to change { VbmsCommunicationPackage.count }.by(0) + + distribution = VbmsDistribution.find(mail_request.vbms_distribution_id) + + expect(distribution.vbms_communication_package_id).to be_nil + end + end + def find_comm_package_via_distribution_id(distro_id) + distribution = VbmsDistribution.find(distro_id) + + VbmsCommunicationPackage.find(distribution.vbms_communication_package_id) + end +end diff --git a/spec/jobs/upload_document_to_vbms_job_spec.rb b/spec/jobs/upload_document_to_vbms_job_spec.rb index 2cb2a50cc67..025b6c18485 100644 --- a/spec/jobs/upload_document_to_vbms_job_spec.rb +++ b/spec/jobs/upload_document_to_vbms_job_spec.rb @@ -5,8 +5,20 @@ let(:document) { create(:vbms_uploaded_document) } let(:service) { instance_double(UploadDocumentToVbms) } let(:user) { create(:user) } + let(:mail_request) { instance_double(MailRequest) } + let(:mail_package) do + { distributions: [mail_request.to_json], + copies: 1, + created_by_id: user.id } + end + + let(:params) do + { document_id: document.id, + initiator_css_id: user.css_id, + mail_package: mail_package } + end - subject { UploadDocumentToVbmsJob.perform_now(document_id: document.id, initiator_css_id: user.css_id) } + subject { UploadDocumentToVbmsJob.perform_now(params) } it "calls #call on UploadDocumentToVbms instance" do expect(UploadDocumentToVbms).to receive(:new).with(document: document).and_return(service) @@ -15,5 +27,28 @@ expect(service).to receive(:call) subject end + + context "document is associated with a mail package" do + it "calls #perform_later on MailRequestJob" do + expect(MailRequestJob).to receive(:perform_later).with(document, mail_package) + subject + end + end + + context "document is not associated with a mail package" do + let(:mail_package) { nil } + it "does not call #perform_later on MailRequestJob" do + expect(MailRequestJob).to_not receive(:perform_later) + subject + end + end + + context "document is not successfully uploaded to vbms" do + it "does not call #perform_later on MailRequestJob" do + allow(VBMSService).to receive(:upload_document_to_vbms_veteran).and_raise(StandardError) + expect(MailRequestJob).to_not receive(:perform_later) + expect { subject }.to raise_error(StandardError) + end + end end end diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index d30f7c30159..182a91e6367 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -47,13 +47,13 @@ it "is not valid without a copies attribute" do package.copies = nil expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["can't be blank", "is too short (minimum is 1 character)"]) + expect(package.errors[:copies]).to eq(["can't be blank", "is not a number"]) end it "is not valid with less than one copy" do package.copies = 0 expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too short (minimum is 1 character)"]) + expect(package.errors[:copies]).to eq(["must be greater than 0"]) end it "is not valid with more than 500 copies" do @@ -62,7 +62,7 @@ package.copies = 501 expect(package).to_not be_valid - expect(package.errors[:copies]).to eq(["is too long (maximum is 500 characters)"]) + expect(package.errors[:copies]).to eq(["must be less than 501"]) end it "is not valid without an associated VbmsUploadedDocument" do diff --git a/spec/models/vbms_distribution_destination_spec.rb b/spec/models/vbms_distribution_destination_spec.rb index f89aed1940a..e23f2f1c18f 100644 --- a/spec/models/vbms_distribution_destination_spec.rb +++ b/spec/models/vbms_distribution_destination_spec.rb @@ -66,7 +66,8 @@ destination.treat_line_3_as_addressee = true destination.treat_line_2_as_addressee = false expect(destination).to_not be_valid - expect(destination.errors[:treat_line_2_as_addressee]).to eq(["cannot be false if line 3 is treated as addressee"]) + expect(destination.errors[:treat_line_2_as_addressee]) + .to eq(["cannot be false if line 3 is treated as addressee"]) end it "is not valid without a city" do diff --git a/spec/models/vbms_distribution_spec.rb b/spec/models/vbms_distribution_spec.rb index da76b6cba2a..7182708ceab 100644 --- a/spec/models/vbms_distribution_spec.rb +++ b/spec/models/vbms_distribution_spec.rb @@ -20,10 +20,9 @@ include_examples "distribution has valid attributes" - it "is not valid without an associated VbmsCommunicationPackage" do + it "is valid without an associated VbmsCommunicationPackage" do distribution.vbms_communication_package = nil - expect(distribution).to_not be_valid - expect(distribution.errors[:vbms_communication_package]).to eq(["must exist"]) + expect(distribution).to be_valid end it "is not valid without a recipient type" do diff --git a/spec/services/external_api/pacman_service_spec.rb b/spec/services/external_api/pacman_service_spec.rb index 76250708375..7eff71ce866 100644 --- a/spec/services/external_api/pacman_service_spec.rb +++ b/spec/services/external_api/pacman_service_spec.rb @@ -14,14 +14,14 @@ let(:distribution) do { - "id" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "id" => 1, "recipient" => { "type" => "system", "id" => "a050a21e-23f6-4743-a1ff-aa1e24412eff", "name" => "VBMS-C" }, "description" => "Staging Mailing Distribution", - "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", + "communicationPackageId" => 1, "destinations" => [{ "type" => "physicalAddress", "id" => "28440040-51a5-4d2a-81a2-28730827be14", @@ -46,6 +46,10 @@ }.as_json end + let(:vbms_distribution) do + create(:vbms_distribution) + end + let(:distribution_post_request) do { "communicationPackageId" => "673c8b4a-cb7d-4fdf-bc4d-998d6d5d7431", @@ -55,7 +59,7 @@ "firstName" => nil, "middleName" => nil, "lastName" => nil, - "participant_id" => nil, + "participantId" => nil, "poaCode" => nil, "claimantStationOfJurisdiction" => nil }, @@ -149,16 +153,14 @@ end context "get distribution" do - subject { Fakes::PacmanService.get_distribution_request(distribution["id"]) } + subject { Fakes::PacmanService.get_distribution_request(vbms_distribution.id) } it "gets correct distribution" do subject - allow(HTTPI).to receive(:get).and_return(get_distribution_success_response) - expect(subject.body.as_json["table"]).to eq(get_distribution_success_response.body) + expect(subject.body.as_json).to eq(get_distribution_success_response.body) end context "not found" do subject { Fakes::PacmanService.get_distribution_request("fake") } it "returns 404 PacmanNotFoundError" do - allow(HTTPI).to receive(:get).and_return(not_found_response) expect(subject.code).to eq(not_found_response.code) end end diff --git a/spec/workflows/mail_request_spec.rb b/spec/workflows/mail_request_spec.rb new file mode 100644 index 00000000000..ef43959f4e7 --- /dev/null +++ b/spec/workflows/mail_request_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +describe MailRequest, :postgres do + let(:mail_request_params) do + ActionController::Parameters.new( + recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" + ) + end + + let(:invalid_mail_request_params) do + ActionController::Parameters.new( + recipient_type: nil, + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: nil, + country_code: "US" + ) + end + + shared_examples "mail request has valid attributes" do + let(:mail_request_spec_object) { build(:mail_request) } + it "is valid with valid attributes" do + expect(mail_request_spec_object).to be_valid + end + end + + let(:mail_request_spec_object_1) { build(:mail_request, :nil_recipient_type) } + include_examples "mail request has valid attributes" + it "is not valid without a recipient type" do + expect(mail_request_spec_object_1).to_not be_valid + end + + describe "#call" do + context "when valid parameters are passed into the mail requests initialize method." do + subject { described_class.new(mail_request_params).call } + + before do + RequestStore.store[:current_user] = User.system_user + end + + it "creates a vbms_distribution" do + expect { subject }.to change(VbmsDistribution, :count).by(1) + end + + it "creates a vbms_distribution_destination" do + expect { subject }.to change(VbmsDistributionDestination, :count).by(1) + end + end + + context "when invalid parameters are passed into the mail requests initialize method." do + subject { described_class.new(invalid_mail_request_params).call } + it "raises an error" do + expect { subject }.to raise_error(Caseflow::Error::MissingRecipientInfo) + end + end + end +end From 38a165aeed6475b97ee497d73fbeaf5539afab69 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 21:57:57 -0400 Subject: [PATCH 262/308] Add back in UUIDs --- app/jobs/mail_request_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index da706991232..d72bb89004d 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -31,7 +31,7 @@ def perform(vbms_uploaded_document, mail_package) log_error(error) else vbms_comm_package = create_package(vbms_uploaded_document, mail_package) - vbms_comm_package.update!(status: "success") + vbms_comm_package.update!(status: "success", uuid: package_response.body[:id]) create_distribution_request(vbms_comm_package.id, mail_package) end end @@ -91,7 +91,7 @@ def create_distribution_request(package_id, mail_package) get_destinations_hash(dist_hash) ) log_info(distribution_response) - distribution.update!(vbms_communication_package_id: package_id) + distribution.update!(vbms_communication_package_id: package_id, uuid: distribution_response.body[:id]) end end end From f0ade18c4411bef9cd16a60468fba5e7ef9cf0a5 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 22:04:57 -0400 Subject: [PATCH 263/308] Handle cases where we get an unforeseen error code --- app/jobs/mail_request_job.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index d72bb89004d..9001f166d37 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -145,7 +145,9 @@ def get_destinations_hash(destination) # Response: n/a def log_error(error) uuid = SecureRandom.uuid - Rails.logger.error(ERROR_MESSAGES[error.code] + "Error ID: " + uuid) + error_msg = ERROR_MESSAGES[error.code] || "#{error.code} Unknown error has occurred." + + Rails.logger.error(error_msg + "Error ID: " + uuid) Raven.capture_exception(error, extra: { error_uuid: uuid }) end From efc3b1686958fb8f734202c6fb3e2efe46e515b6 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 28 Jun 2023 23:15:04 -0400 Subject: [PATCH 264/308] Fix test --- spec/controllers/idt/api/v2/distributions_controller_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/controllers/idt/api/v2/distributions_controller_spec.rb b/spec/controllers/idt/api/v2/distributions_controller_spec.rb index dd0e1d2ef5e..8c60e4c8ed9 100644 --- a/spec/controllers/idt/api/v2/distributions_controller_spec.rb +++ b/spec/controllers/idt/api/v2/distributions_controller_spec.rb @@ -79,8 +79,7 @@ let(:vbms_distribution) { create(:vbms_distribution, uuid: distro_uuid) } let(:expected_response) do { - "id": vbms_distribution.id, - "pacman_id": vbms_distribution.uuid, + "id": Fakes::PacmanService::DISTRIBUTION_UUID, "recipient": { "type": "system", From 25391a1d2301cb22e61f82d8e0329e921213daae Mon Sep 17 00:00:00 2001 From: jefftmarks <106996298+jefftmarks@users.noreply.github.com> Date: Fri, 30 Jun 2023 10:14:39 -0400 Subject: [PATCH 265/308] jefftmarks/APPEALS-21125 (#18702) * Created MailRequest object and passed from control to dispatch workflows: * Changed name of method to create mail request distributions * Condensed calls to params with a method * Mocked up sending back distribution ids * Added comments and logging * Reformatted AmaAppealDispatch spec and added mail request examples * Added comments * Updated comments * Updated workflow to pass multiple mail requests and copies attribute * Refactored to mirror UploadDocumentToVbmsController * Completed unit test for AmaAppealDispatch * Refactored spec for LegacyAppealDisaptch * Completed unit tets for LegacyAppealsDispatch and AmaAppealDispatch * Refactored code to pass unit tests * Completed unit tests for AppealsController * Changed global variable * Refactored with MailPackageConcern * Removed mail package concern and moved to APPEALS-21121 * Updated unit tests after merging in MailRequest object and MailRequestJon * Added check in spec file for invalid recipient info * Reordered examples in spec file * Refactored workflow to pass DecisionDocument into MailRequestJob * Added columns to DecisionDocument and update reference columns after Vbms upload * Updated polymorphic associations between CommPackage, VbmsUploadedDoc, and DecisionDoc * Changed column names and added index for polymorphic document association for VbmsCommPackage * Updated MailRequestJob to fit polymorphic association * Remove byebug * Update columns in audit tables and triggers * Remove defunct columns * Adjust comm package factory * Updated spec for comm package and made polymorphic assoc not optional * Fix a couple spec files * Adjust AmaAppealDispatch spec * Adjust BvaDispatchTask specs * Ignore our new attrs on DecisionDocument * Add all_dbs tag to LegacyAppealDispatch spec * Break out notification type seeds to a before all * Try forcibly cleaning up after legacy dispatch tests * Oops, we're not paralellizing here * Allow outcode items to wrap --------- Co-authored-by: Matthew Thornton Co-authored-by: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> --- .../idt/api/v2/appeals_controller.rb | 26 +++- app/jobs/mail_request_job.rb | 22 ++-- app/jobs/process_decision_document_job.rb | 4 +- app/models/decision_document.rb | 49 ++++++- app/models/etl/decision_document.rb | 5 +- .../va_notify/appeal_decision_mailed.rb | 2 +- app/models/tasks/bva_dispatch_task.rb | 7 +- app/models/vbms_communication_package.rb | 2 +- app/models/vbms_uploaded_document.rb | 2 + app/workflows/ama_appeal_dispatch.rb | 30 +++-- app/workflows/legacy_appeal_dispatch.rb | 30 +++-- ...ce_and_series_ids_to_decision_documents.rb | 27 ++++ ...ument_association_to_comm_package_table.rb | 16 +++ ...ument_association_in_comm_package_table.rb | 10 ++ db/schema.rb | 10 +- ...unication_packages_audit_table_function.rb | 9 +- ...nication_packages_audit_table_function.sql | 9 +- ...reate_vbms_communication_packages_audit.rb | 3 +- ...eate_vbms_communication_packages_audit.sql | 3 +- ...te_vbms_distribution_destinations_audit.rb | 2 - ...e_vbms_distribution_destinations_audit.sql | 2 - .../idt/api/v2/appeals_controller_spec.rb | 61 ++++++++- spec/factories/vbms_communication_package.rb | 2 +- spec/models/tasks/bva_dispatch_task_spec.rb | 6 +- .../models/vbms_communication_package_spec.rb | 8 +- spec/workflows/ama_appeal_dispatch_spec.rb | 93 +++++++++---- spec/workflows/legacy_appeal_dispatch_spec.rb | 123 ++++++++++++------ 27 files changed, 427 insertions(+), 136 deletions(-) create mode 100644 db/migrate/20230629172100_add_doc_reference_and_series_ids_to_decision_documents.rb create mode 100644 db/migrate/20230629183146_add_polymorphic_document_association_to_comm_package_table.rb create mode 100644 db/migrate/20230629184615_add_index_to_polymorphic_document_association_in_comm_package_table.rb diff --git a/app/controllers/idt/api/v2/appeals_controller.rb b/app/controllers/idt/api/v2/appeals_controller.rb index 628dafc81d9..ce1d9526698 100644 --- a/app/controllers/idt/api/v2/appeals_controller.rb +++ b/app/controllers/idt/api/v2/appeals_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Idt::Api::V2::AppealsController < Idt::Api::V1::BaseController + include MailPackageConcern + protect_from_forgery with: :exception before_action :verify_access @@ -23,10 +25,17 @@ def details end def outcode - result = BvaDispatchTask.outcode(appeal, outcode_params, user) + # Create distributions for Package Manager mail service if recipient info present + build_mail_package + + result = BvaDispatchTask.outcode(appeal, outcode_params, user, mail_package) if result.success? - return render json: { message: "Success!" } + success_response = { message: "Successful dispatch!" } + if recipient_info.present? + success_response[:distribution_ids] = distribution_ids + end + return render json: success_response end render json: { message: result.errors[0] }, status: :bad_request @@ -151,4 +160,17 @@ def load_tags_by_doc_id def outcode_params params.permit(:citation_number, :decision_date, :redacted_document_location, :file) end + + def mail_params + params.permit(:copies, recipient_info: recipient_keys) + end + + def recipient_keys + [ + :recipient_type, :name, :first_name, :last_name, :claimant_station_of_jurisdiction, :postal_code, + :destination_type, :address_line_1, :address_line_2, :address_line_3, :address_line_4, :address_line_5, + :address_line_6, :treat_line_2_as_addressee, :treat_line_3_as_addressee, :city, :state, :country_name, + :country_code + ] + end end diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 9001f166d37..7a81dab86b3 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -19,18 +19,18 @@ class MailRequestJob < CaseflowJob # } # # Response: n/a - def perform(vbms_uploaded_document, mail_package) + def perform(document_to_mail, mail_package) begin package_response = PacmanService.send_communication_package_request( - vbms_uploaded_document.veteran_file_number, - get_package_name(vbms_uploaded_document), - document_referenced(vbms_uploaded_document.document_version_reference_id, mail_package[:copies]) + document_to_mail.veteran_file_number, + get_package_name(document_to_mail), + document_referenced(document_to_mail.document_version_reference_id, mail_package[:copies]) ) log_info(package_response) rescue Caseflow::Error::PacmanApiError => error log_error(error) else - vbms_comm_package = create_package(vbms_uploaded_document, mail_package) + vbms_comm_package = create_package(document_to_mail, mail_package) vbms_comm_package.update!(status: "success", uuid: package_response.body[:id]) create_distribution_request(vbms_comm_package.id, mail_package) end @@ -53,22 +53,22 @@ def document_referenced(doc_id, copies) # # Response: new VbmsCommunicationPackage object # :reek:FeatureEnvy - def create_package(vbms_uploaded_document, mail_package) + def create_package(document_to_mail, mail_package) VbmsCommunicationPackage.new( - comm_package_name: get_package_name(vbms_uploaded_document), + comm_package_name: get_package_name(document_to_mail), created_at: Time.zone.now, created_by_id: mail_package[:created_by_id], copies: mail_package[:copies], - file_number: vbms_uploaded_document.veteran_file_number, + file_number: document_to_mail.veteran_file_number, status: nil, updated_at: Time.zone.now, updated_by_id: mail_package[:created_by_id], - vbms_uploaded_document_id: vbms_uploaded_document.id + document_mailable_via_pacman: document_to_mail ) end - def get_package_name(vbms_uploaded_document) - "#{vbms_uploaded_document.document_name}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" + def get_package_name(document_to_mail) + "#{document_to_mail.document_name}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" end # Purpose: sends distribution POST request to Pacman API diff --git a/app/jobs/process_decision_document_job.rb b/app/jobs/process_decision_document_job.rb index 742f42cdd48..e2d0e9f0cee 100644 --- a/app/jobs/process_decision_document_job.rb +++ b/app/jobs/process_decision_document_job.rb @@ -4,10 +4,10 @@ class ProcessDecisionDocumentJob < CaseflowJob queue_with_priority :low_priority application_attr :intake - def perform(decision_document_id) + def perform(decision_document_id, mail_package = nil) RequestStore.store[:application] = "idt" RequestStore.store[:current_user] = User.system_user - DecisionDocument.find(decision_document_id).process! + DecisionDocument.find(decision_document_id).process!(mail_package) end end diff --git a/app/models/decision_document.rb b/app/models/decision_document.rb index 1be7c4c54c8..e81ebc23075 100644 --- a/app/models/decision_document.rb +++ b/app/models/decision_document.rb @@ -19,6 +19,7 @@ class NotYetSubmitted < StandardError; end S3_SUB_BUCKET = "decisions" delegate :veteran, to: :appeal + delegate :file_number, to: :veteran, prefix: true include BelongsToPolymorphicAppealConcern # Sets up belongs_to association with :appeal and provides `ama_appeal` used by `has_many` call @@ -26,6 +27,22 @@ class NotYetSubmitted < StandardError; end has_many :ama_decision_issues, -> { includes(:ama_decision_documents).references(:decision_documents) }, through: :ama_appeal, source: :decision_issues + has_many :vbms_communication_packages, as: :document_mailable_via_pacman + + def self.create_document!(params, mail_package) + create!(params).tap { |document| document.add_mail_package(mail_package) } + end + + def add_mail_package(mail_package) + @mail_package = mail_package + end + + def pdf_name + appeal.external_id + ".pdf" + end + + alias document_name pdf_name + def decision_issues ama_decision_issues if appeal_type == "Appeal" # LegacyAppeals do not have decision_issue records @@ -53,17 +70,18 @@ def submit_for_processing!(delay: processing_delay) super if not_processed_or_decision_date_not_in_the_future? - ProcessDecisionDocumentJob.perform_later(id) + ProcessDecisionDocumentJob.perform_later(id, mail_package) end end - def process! + def process!(mail_package) return if processed? fail NotYetSubmitted unless submitted_and_ready? attempted! upload_to_vbms! + queue_mail_request_job!(mail_package) unless mail_package.nil? if appeal.is_a?(Appeal) create_board_grant_effectuations! @@ -109,6 +127,8 @@ def all_contention_records(epe) private + attr_reader :mail_package + def create_board_grant_effectuations! appeal.decision_issues.granted.each do |granted_decision_issue| BoardGrantEffectuation.find_or_create_by(granted_decision_issue: granted_decision_issue) @@ -134,12 +154,13 @@ def update_decision_issue_decision_dates! def upload_to_vbms! return if uploaded_to_vbms_at - VBMSService.upload_document_to_vbms(appeal, self) - update!(uploaded_to_vbms_at: Time.zone.now) - end + response = VBMSService.upload_document_to_vbms(appeal, self) - def pdf_name - appeal.external_id + ".pdf" + update!( + uploaded_to_vbms_at: Time.zone.now, + document_version_reference_id: response.dig(:upload_document_response, :@new_document_version_ref_id), + document_series_reference_id: response.dig(:upload_document_response, :@document_series_ref_id) + ) end def s3_location @@ -184,4 +205,18 @@ def send_outcode_email(appeal) Rails.logger.warn("BVADispatchEmail #{log}") end end + + # Queues mail request job if recipient info present and dispatch completed + def queue_mail_request_job!(mail_package) + return unless uploaded_to_vbms_at + + MailRequestJob.perform_later(self, mail_package) + info_message = "MailRequestJob for citation #{citation_number} queued for submission to Package Manager" + log_info(info_message) + end + + def log_info(info_message) + uuid = SecureRandom.uuid + Rails.logger.info(info_message + " ID: " + uuid) + end end diff --git a/app/models/etl/decision_document.rb b/app/models/etl/decision_document.rb index 6a6ab0b65d2..3cf81fac966 100644 --- a/app/models/etl/decision_document.rb +++ b/app/models/etl/decision_document.rb @@ -6,6 +6,9 @@ class ETL::DecisionDocument < ETL::Record class << self private + ATTRS_TO_OMIT = %w[created_at updated_at + document_series_reference_id document_version_reference_id].freeze + # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/CyclomaticComplexity @@ -14,7 +17,7 @@ def merge_original_attributes_to_target(original, target) # To-do: ETL legacy appeals; AMA appeals are sufficient for now return unless original.appeal_type == "Appeal" - target.attributes = original.attributes.reject { |key| %w[created_at updated_at].include?(key) } + target.attributes = original.attributes.reject { |key| ATTRS_TO_OMIT.include?(key) } target.decision_document_created_at = original.created_at target.decision_document_updated_at = original.updated_at diff --git a/app/models/prepend/va_notify/appeal_decision_mailed.rb b/app/models/prepend/va_notify/appeal_decision_mailed.rb index 48a8674bfc9..034e4d32acd 100644 --- a/app/models/prepend/va_notify/appeal_decision_mailed.rb +++ b/app/models/prepend/va_notify/appeal_decision_mailed.rb @@ -12,7 +12,7 @@ module AppealDecisionMailed # Params: none # # Response: returns true if successfully processed, returns false if not successfully processed (will not notify) - def process! + def process!(mail_package = nil) super_return_value = super if processed? AppellantNotification.appeal_mapper(appeal.id, appeal.class.to_s, "decision_mailed") diff --git a/app/models/tasks/bva_dispatch_task.rb b/app/models/tasks/bva_dispatch_task.rb index 3d475f407c1..71ddb629232 100644 --- a/app/models/tasks/bva_dispatch_task.rb +++ b/app/models/tasks/bva_dispatch_task.rb @@ -37,11 +37,12 @@ def ready_for_dispatch?(appeal) true end - def outcode(appeal, params, user) + # Passes mail distributions to Package Manager service if recipient info present + def outcode(appeal, params, user, mail_package = nil) if appeal.is_a?(Appeal) - AmaAppealDispatch.new(appeal: appeal, user: user, params: params).call + AmaAppealDispatch.new(appeal: appeal, params: params, user: user, mail_package: mail_package).call elsif appeal.is_a?(LegacyAppeal) - LegacyAppealDispatch.new(appeal: appeal, params: params).call + LegacyAppealDispatch.new(appeal: appeal, params: params, mail_package: mail_package).call end end end diff --git a/app/models/vbms_communication_package.rb b/app/models/vbms_communication_package.rb index 21d4d4bb290..f09be6354b8 100644 --- a/app/models/vbms_communication_package.rb +++ b/app/models/vbms_communication_package.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class VbmsCommunicationPackage < CaseflowRecord - belongs_to :vbms_uploaded_document, optional: false + belongs_to :document_mailable_via_pacman, polymorphic: true, optional: false has_many :vbms_distributions validates :file_number, :comm_package_name, :copies, presence: true diff --git a/app/models/vbms_uploaded_document.rb b/app/models/vbms_uploaded_document.rb index 6a767c13c2f..dc5f9a55c73 100644 --- a/app/models/vbms_uploaded_document.rb +++ b/app/models/vbms_uploaded_document.rb @@ -4,6 +4,8 @@ class VbmsUploadedDocument < CaseflowRecord include BelongsToPolymorphicAppealConcern belongs_to_polymorphic_appeal :appeal + has_many :vbms_communication_packages, as: :document_mailable_via_pacman + validates :document_type, presence: true attribute :file, :string diff --git a/app/workflows/ama_appeal_dispatch.rb b/app/workflows/ama_appeal_dispatch.rb index cd10f06950d..01618ee3627 100644 --- a/app/workflows/ama_appeal_dispatch.rb +++ b/app/workflows/ama_appeal_dispatch.rb @@ -4,14 +4,11 @@ class AmaAppealDispatch include ActiveModel::Model include DecisionDocumentValidator - def initialize(appeal:, params:, user:) - @appeal = appeal + def initialize(appeal:, params:, user:, mail_package: nil) @params = params.merge(appeal_id: appeal.id, appeal_type: "Appeal") + @appeal = appeal @user = user - @citation_number = params[:citation_number] - @decision_date = params[:decision_date] - @redacted_document_location = params[:redacted_document_location] - @file = params[:file] + @mail_package = mail_package end def call @@ -27,8 +24,23 @@ def call private - attr_reader :appeal, :params, :user, :success, :citation_number, - :decision_date, :redacted_document_location, :file + attr_reader :params, :appeal, :user, :mail_package, :success + + def citation_number + params[:citation_number] + end + + def decision_date + params[:decision_date] + end + + def redacted_document_location + params[:redacted_document_location] + end + + def file + params[:file] + end def dispatch_tasks @dispatch_tasks ||= BvaDispatchTask.not_cancelled.where(appeal: appeal, assigned_to: user) @@ -73,7 +85,7 @@ def outcode_appeal end def create_decision_document_and_submit_for_processing!(params) - DecisionDocument.create!(params).tap(&:submit_for_processing!) + DecisionDocument.create_document!(params, mail_package).tap(&:submit_for_processing!) end def complete_dispatch_task! diff --git a/app/workflows/legacy_appeal_dispatch.rb b/app/workflows/legacy_appeal_dispatch.rb index 086d73d6b7e..67d087f6099 100644 --- a/app/workflows/legacy_appeal_dispatch.rb +++ b/app/workflows/legacy_appeal_dispatch.rb @@ -4,13 +4,10 @@ class LegacyAppealDispatch include ActiveModel::Model include DecisionDocumentValidator - def initialize(appeal:, params:) - @appeal = appeal + def initialize(appeal:, params:, mail_package: nil) @params = params.merge(appeal_id: appeal.id, appeal_type: "LegacyAppeal") - @citation_number = params[:citation_number] - @decision_date = params[:decision_date] - @redacted_document_location = params[:redacted_document_location] - @file = params[:file] + @appeal = appeal + @mail_package = mail_package end def call @@ -26,11 +23,26 @@ def call private - attr_reader :appeal, :params, :success, :citation_number, - :decision_date, :redacted_document_location, :file + attr_reader :params, :appeal, :mail_package, :success + + def citation_number + params[:citation_number] + end + + def decision_date + params[:decision_date] + end + + def redacted_document_location + params[:redacted_document_location] + end + + def file + params[:file] + end def create_decision_document_and_submit_for_processing!(params) - DecisionDocument.create!(params).tap(&:submit_for_processing!) + DecisionDocument.create_document!(params, mail_package).tap(&:submit_for_processing!) end def complete_root_task! diff --git a/db/migrate/20230629172100_add_doc_reference_and_series_ids_to_decision_documents.rb b/db/migrate/20230629172100_add_doc_reference_and_series_ids_to_decision_documents.rb new file mode 100644 index 00000000000..b2d0f285f2b --- /dev/null +++ b/db/migrate/20230629172100_add_doc_reference_and_series_ids_to_decision_documents.rb @@ -0,0 +1,27 @@ +# Adds columns to the decision_documents table to retain the +# documentVersionReferenceId and documentSeriesReferenceId values that are +# returned once a document is uploaded to VBMS eFolder. +# +# These values can be used to refer to documents and +# update documents via the eFolder API. +# + +class AddDocReferenceAndSeriesIdsToDecisionDocuments < Caseflow::Migration + def up + add_column :decision_documents, + :document_version_reference_id, + :string, + comment: "UUID that is provided by eFolder that represents the specific version of the document." + + add_column :decision_documents, + :document_series_reference_id, + :string, + comment: "UUID that is provided by eFolder that represents the group of documents" \ + "this document belongs to. Think of a series as a stack of versions." + end + + def down + remove_column :decision_documents, :document_version_reference_id + remove_column :decision_documents, :document_series_reference_id + end +end diff --git a/db/migrate/20230629183146_add_polymorphic_document_association_to_comm_package_table.rb b/db/migrate/20230629183146_add_polymorphic_document_association_to_comm_package_table.rb new file mode 100644 index 00000000000..bb14cc52ea1 --- /dev/null +++ b/db/migrate/20230629183146_add_polymorphic_document_association_to_comm_package_table.rb @@ -0,0 +1,16 @@ +class AddPolymorphicDocumentAssociationToCommPackageTable < ActiveRecord::Migration[5.2] + def change + remove_index :vbms_communication_packages, :vbms_uploaded_document_id + + add_reference :vbms_communication_packages, :document_mailable_via_pacman, polymorphic: true, index: false + + VbmsCommunicationPackage.find_each do |vcp| + unless vcp.vbms_uploaded_document_id.nil? + vcp.update_attribute(:document_mailable_via_pacman_type, "VbmsUploadedDocument") + vcp.document_mailable_via_pacman_id = vcp.vbms_uploaded_document_id + end + end + + safety_assured { remove_column :vbms_communication_packages, :vbms_uploaded_document_id } + end +end diff --git a/db/migrate/20230629184615_add_index_to_polymorphic_document_association_in_comm_package_table.rb b/db/migrate/20230629184615_add_index_to_polymorphic_document_association_in_comm_package_table.rb new file mode 100644 index 00000000000..ca7140946ae --- /dev/null +++ b/db/migrate/20230629184615_add_index_to_polymorphic_document_association_in_comm_package_table.rb @@ -0,0 +1,10 @@ +class AddIndexToPolymorphicDocumentAssociationInCommPackageTable < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def change + add_index :vbms_communication_packages, + [:document_mailable_via_pacman_type, :document_mailable_via_pacman_id], + name: "index_vbms_communication_packages_on_pacman_document_id", + algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index b24d4f838f0..0fa2ef9ac77 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: 2023_06_27_203547) do +ActiveRecord::Schema.define(version: 2023_06_29_184615) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -571,6 +571,8 @@ t.string "citation_number", null: false, comment: "Unique identifier for decision document" t.datetime "created_at", null: false t.date "decision_date", null: false + t.string "document_series_reference_id", comment: "UUID that is provided by eFolder that represents the group of documentsthis document belongs to. Think of a series as a stack of versions." + t.string "document_version_reference_id", comment: "UUID that is provided by eFolder that represents the specific version of the document." t.string "error", comment: "Message captured from a failed attempt" t.datetime "last_submitted_at", comment: "When the job is eligible to run (can be reset to restart the job)" t.datetime "processed_at", comment: "When the job has concluded" @@ -1794,15 +1796,16 @@ t.bigint "copies", default: 1 t.datetime "created_at", null: false t.bigint "created_by_id" + t.bigint "document_mailable_via_pacman_id" + t.string "document_mailable_via_pacman_type" t.string "file_number", comment: "number associated with the documents." t.string "status" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.string "uuid", comment: "UUID of the communication package in Package Manager (Pacman)" - t.bigint "vbms_uploaded_document_id" t.index ["created_by_id"], name: "index_vbms_communication_packages_on_created_by_id" + t.index ["document_mailable_via_pacman_type", "document_mailable_via_pacman_id"], name: "index_vbms_communication_packages_on_pacman_document_id" t.index ["updated_by_id"], name: "index_vbms_communication_packages_on_updated_by_id" - t.index ["vbms_uploaded_document_id"], name: "index_vbms_communication_packages_on_vbms_uploaded_document_id" end create_table "vbms_distribution_destinations", force: :cascade do |t| @@ -2133,7 +2136,6 @@ add_foreign_key "user_quotas", "users" add_foreign_key "vbms_communication_packages", "users", column: "created_by_id" add_foreign_key "vbms_communication_packages", "users", column: "updated_by_id" - add_foreign_key "vbms_communication_packages", "vbms_uploaded_documents" add_foreign_key "vbms_distribution_destinations", "users", column: "created_by_id" add_foreign_key "vbms_distribution_destinations", "users", column: "updated_by_id" add_foreign_key "vbms_distribution_destinations", "vbms_distributions" diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb index 837295f0e20..8a0b5105fa6 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.rb @@ -20,7 +20,8 @@ OLD.comm_package_name, OLD.created_at, OLD.updated_at, - OLD.vbms_uploaded_document_id, + OLD.document_mailable_via_pacman_id, + OLD.document_mailable_via_pacman_type, OLD.created_by_id, OLD.updated_by_id, OLD.uuid; @@ -36,7 +37,8 @@ NEW.comm_package_name, NEW.created_at, NEW.updated_at, - NEW.vbms_uploaded_document_id, + NEW.document_mailable_via_pacman_id, + NEW.document_mailable_via_pacman_type, NEW.created_by_id, NEW.updated_by_id, NEW.uuid; @@ -52,7 +54,8 @@ NEW.comm_package_name, NEW.created_at, NEW.updated_at, - NEW.vbms_uploaded_document_id, + NEW.document_mailable_via_pacman_id, + NEW.document_mailable_via_pacman_type, NEW.created_by_id, NEW.updated_by_id, NEW.uuid; diff --git a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql index 891abc0ed4d..fd8841b5bf9 100644 --- a/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql +++ b/db/scripts/audit/functions/add_row_to_vbms_communication_packages_audit_table_function.sql @@ -14,7 +14,8 @@ begin OLD.comm_package_name, OLD.created_at, OLD.updated_at, - OLD.vbms_uploaded_document_id, + OLD.document_mailable_via_pacman_id, + OLD.document_mailable_via_pacman_type, OLD.created_by_id, OLD.updated_by_id, OLD.uuid; @@ -30,7 +31,8 @@ begin NEW.comm_package_name, NEW.created_at, NEW.updated_at, - NEW.vbms_uploaded_document_id, + NEW.document_mailable_via_pacman_id, + NEW.document_mailable_via_pacman_type, NEW.created_by_id, NEW.updated_by_id, NEW.uuid; @@ -46,7 +48,8 @@ begin NEW.comm_package_name, NEW.created_at, NEW.updated_at, - NEW.vbms_uploaded_document_id, + NEW.document_mailable_via_pacman_id, + NEW.document_mailable_via_pacman_type, NEW.created_by_id, NEW.updated_by_id, NEW.uuid; diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb index 5e79e627024..bf0b979682e 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.rb @@ -13,7 +13,8 @@ comm_package_name varchar NOT NULL, created_at timestamp NOT NULL, updated_at timestamp NOT NULL, - vbms_uploaded_document_id int8 NULL, + document_mailable_via_pacman_id bigint not NULL, + document_mailable_via_pacman_type varchar not NULL, created_by_id int8 NULL, updated_by_id int8 NULL, uuid varchar NULL diff --git a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql index 9e288f69dc5..87a778d05d1 100644 --- a/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql +++ b/db/scripts/audit/tables/create_vbms_communication_packages_audit.sql @@ -8,7 +8,8 @@ create table caseflow_audit.vbms_communication_packages_audit ( comm_package_name varchar NOT NULL, created_at timestamp NOT NULL, updated_at timestamp NOT NULL, - vbms_uploaded_document_id int8 NULL, + document_mailable_via_pacman_id bigint not NULL, + document_mailable_via_pacman_type varchar not NULL, created_by_id int8 NULL, updated_by_id int8 NULL, uuid varchar NULL diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb index 48664479ef3..ec1e1e3973b 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.rb @@ -21,8 +21,6 @@ postal_code varchar NULL, country_name varchar NULL, country_code varchar NULL, - email_address varchar NULL, - phone_number varchar NULL, created_at timestamp NOT NULL, updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, diff --git a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql index b36bc275374..bc27fea7588 100644 --- a/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql +++ b/db/scripts/audit/tables/create_vbms_distribution_destinations_audit.sql @@ -16,8 +16,6 @@ create table caseflow_audit.vbms_distribution_destinations_audit ( postal_code varchar NULL, country_name varchar NULL, country_code varchar NULL, - email_address varchar NULL, - phone_number varchar NULL, created_at timestamp NOT NULL, updated_at timestamp NOT NULL, vbms_distribution_id int8 NULL, diff --git a/spec/controllers/idt/api/v2/appeals_controller_spec.rb b/spec/controllers/idt/api/v2/appeals_controller_spec.rb index 15fe3342605..c8f293f78b8 100644 --- a/spec/controllers/idt/api/v2/appeals_controller_spec.rb +++ b/spec/controllers/idt/api/v2/appeals_controller_spec.rb @@ -510,16 +510,17 @@ citation_number: citation_number, decision_date: Date.new(1989, 12, 13).to_s, file: "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YW", - redacted_document_location: "C://Windows/User/BLOBLAW/Documents/Decision.docx" } + redacted_document_location: "C://Windows/User/BLOBLAW/Documents/Decision.docx", + recipient_info: [] } end before do - allow(controller).to receive(:verify_access).and_return(true) BvaDispatch.singleton.add_user(user) key, t = Idt::Token.generate_one_time_key_and_proposed_token Idt::Token.activate_proposed_token(key, user.css_id) request.headers["TOKEN"] = t + create(:staff, :attorney_role, sdomainid: user.css_id) end context "when some params are missing" do @@ -567,7 +568,6 @@ it "should complete the BvaDispatchTask assigned to the User and the task assigned to the BvaDispatch org" do post :outcode, params: params - expect(response.status).to eq(200) tasks = BvaDispatchTask.where(appeal: root_task.appeal, assigned_to: user) @@ -580,7 +580,60 @@ expect(task.parent.status).to eq("completed") expect(S3Service.files["decisions/" + root_task.appeal.external_id + ".pdf"]).to_not eq nil expect(DecisionDocument.find_by(appeal_id: root_task.appeal.id)&.submitted_at).to_not be_nil - expect(JSON.parse(response.body)["message"]).to eq("Success!") + expect(JSON.parse(response.body)["message"]).to eq("Successful dispatch!") + end + + context "when dispatch is associated with a mail request" do + include ActiveJob::TestHelper + + let(:recipient) do + { recipient_type: "person", + first_name: "Bob", + last_name: "Smithmetz", + participant_id: "487470002", + destination_type: "domesticAddress", + address_line_1: "1234 Main Street", + treat_line_2_as_addressee: false, + treat_line_3_as_addressee: false, + city: "Orlando", + state: "FL", + postal_code: "12345", + country_code: "US" } + end + + before { params[:recipient_info] << recipient } + + it "calls #perform_later on MailRequestJob" do + expect(MailRequestJob).to receive(:perform_later) + + perform_enqueued_jobs { post :outcode, params: params, as: :json } + end + + context "recipient info is incorrect" do + it "returns validation errors and does not call #perform_later on MailRequestJob" do + recipient[:first_name] = nil + expect(MailRequestJob).to_not receive(:perform_later) + perform_enqueued_jobs { post :outcode, params: params, as: :json } + error_message = JSON.parse(response.body)["errors"]["distribution 1"] + expect(error_message).to eq("First name can't be blank") + end + end + + context "when dispatch is not successfully processed" do + let(:citation_number) { "INVALID" } + it "does not call #perform_later on MailRequestJob" do + perform_enqueued_jobs { expect(MailRequestJob).to_not receive(:perform_later) } + post :outcode, params: params + end + end + end + + context "when dispatch is not associated with a mail request" do + it "does not call #perform_later on MailRequestJob" do + params[:recipient_info] = [] + expect(MailRequestJob).to_not receive(:perform_later) + post :outcode, params: params + end end end diff --git a/spec/factories/vbms_communication_package.rb b/spec/factories/vbms_communication_package.rb index 11c3a6f8993..143cce7de44 100644 --- a/spec/factories/vbms_communication_package.rb +++ b/spec/factories/vbms_communication_package.rb @@ -2,7 +2,7 @@ FactoryBot.define do factory :vbms_communication_package do - association :vbms_uploaded_document, factory: :vbms_uploaded_document + association :document_mailable_via_pacman, factory: :vbms_uploaded_document comm_package_name { "DocumentName_" + Time.zone.now.to_s } copies { 1 } created_at { Time.zone.now } diff --git a/spec/models/tasks/bva_dispatch_task_spec.rb b/spec/models/tasks/bva_dispatch_task_spec.rb index cf3d50caba9..9124d11eaf8 100644 --- a/spec/models/tasks/bva_dispatch_task_spec.rb +++ b/spec/models/tasks/bva_dispatch_task_spec.rb @@ -113,7 +113,7 @@ decision_document = DecisionDocument.find_by(appeal_id: root_task.appeal.id) expect(ProcessDecisionDocumentJob).to have_received(:perform_later) - .with(decision_document.id).exactly(:once) + .with(decision_document.id, nil).exactly(:once) expect(decision_document).to_not eq nil expect(decision_document.document_type).to eq "BVA Decision" expect(decision_document.source).to eq "BVA" @@ -144,7 +144,7 @@ decision_document = DecisionDocument.find_by(appeal_id: legacy_appeal.id) expect(ProcessDecisionDocumentJob).to have_received(:perform_later) - .with(decision_document.id).exactly(:once) + .with(decision_document.id, nil).exactly(:once) expect(decision_document).to_not eq nil expect(decision_document.document_type).to eq "BVA Decision" expect(decision_document.source).to eq "BVA" @@ -248,7 +248,7 @@ decision_document = DecisionDocument.find_by(appeal_id: root_task.appeal.id) expect(ProcessDecisionDocumentJob).to have_received(:perform_later) - .with(decision_document.id).exactly(:once) + .with(decision_document.id, nil).exactly(:once) expect(decision_document).to_not eq nil expect(decision_document.document_type).to eq "BVA Decision" expect(decision_document.source).to eq "BVA" diff --git a/spec/models/vbms_communication_package_spec.rb b/spec/models/vbms_communication_package_spec.rb index 182a91e6367..ce427dc7327 100644 --- a/spec/models/vbms_communication_package_spec.rb +++ b/spec/models/vbms_communication_package_spec.rb @@ -6,7 +6,7 @@ file_number: "329780002", comm_package_name: "test package name", copies: 1, - vbms_uploaded_document: VbmsUploadedDocument.new + document_mailable_via_pacman: VbmsUploadedDocument.new ) end @@ -65,9 +65,9 @@ expect(package.errors[:copies]).to eq(["must be less than 501"]) end - it "is not valid without an associated VbmsUploadedDocument" do - package.vbms_uploaded_document = nil + it "is not valid without an associated document mailable via pacman" do + package.document_mailable_via_pacman = nil expect(package).to_not be_valid - expect(package.errors[:vbms_uploaded_document]).to eq(["must exist"]) + expect(package.errors[:document_mailable_via_pacman]).to eq(["must exist"]) end end diff --git a/spec/workflows/ama_appeal_dispatch_spec.rb b/spec/workflows/ama_appeal_dispatch_spec.rb index 05b4231b62a..62a1e336e61 100644 --- a/spec/workflows/ama_appeal_dispatch_spec.rb +++ b/spec/workflows/ama_appeal_dispatch_spec.rb @@ -1,32 +1,77 @@ # frozen_string_literal: true describe AmaAppealDispatch, :postgres do + include ActiveJob::TestHelper + + let(:user) { User.authenticate! } + let(:appeal) { create(:appeal, :advanced_on_docket_due_to_age) } + let(:root_task) { create(:root_task, appeal: appeal) } + let(:poa_participant_id) { "600153863" } + let(:bgs_poa) { instance_double(BgsPowerOfAttorney) } + let(:params) do + { citation_number: "A18123456", + decision_date: Time.zone.now, + redacted_document_location: "C://Windows/User/BLOBLAW/Documents/Decision.docx", + file: "12345678" } + end + let(:mail_package) do + { distributions: [build(:mail_request).call.to_json], + copies: 1, + created_by_id: user.id } + end + + before do + BvaDispatch.singleton.add_user(user) + BvaDispatchTask.create_from_root_task(root_task) + allow(BgsPowerOfAttorney).to receive(:find_or_create_by_file_number) + .with(appeal.veteran_file_number).and_return(bgs_poa) + allow(bgs_poa).to receive(:participant_id).and_return(poa_participant_id) + end + + before(:all) { Seeds::NotificationEvents.new.seed! } + + subject do + perform_enqueued_jobs do + AmaAppealDispatch.new(appeal: appeal, params: params, user: user, mail_package: mail_package).call + end + end + describe "#call" do it "stores current POA participant ID in the Appeals table" do - user = create(:user) - BvaDispatch.singleton.add_user(user) - appeal = create(:appeal, :advanced_on_docket_due_to_age) - root_task = create(:root_task, appeal: appeal) - BvaDispatchTask.create_from_root_task(root_task) - poa_participant_id = "600153863" - - bgs_poa = instance_double(BgsPowerOfAttorney) - allow(BgsPowerOfAttorney).to receive(:find_or_create_by_file_number) - .with(appeal.veteran_file_number).and_return(bgs_poa) - allow(bgs_poa).to receive(:participant_id).and_return(poa_participant_id) - - params = { - appeal_id: appeal.id, - appeal_type: "Appeal", - citation_number: "A18123456", - decision_date: Time.zone.now, - redacted_document_location: "C://Windows/User/BLOBLAW/Documents/Decision.docx", - file: "12345678" - } - - AmaAppealDispatch.new(appeal: appeal, params: params, user: user).call - - expect(appeal.reload.poa_participant_id).to eq poa_participant_id + subject + expect(appeal.poa_participant_id).to eq poa_participant_id + end + + context "document is associated with a mail request" do + it "calls #perform_later on MailRequestJob" do + expect(MailRequestJob).to receive(:perform_later) do |doc, pkg| + expect(doc).to be_a DecisionDocument + expect(doc.appeal_type).to eq "Appeal" + expect(doc.appeal_id).to eq appeal.id + expect(doc.redacted_document_location).to eq params[:redacted_document_location] + expect(doc.citation_number).to eq params[:citation_number] + + expect(pkg).to eq mail_package + end + + subject + end + end + + context "document is not associated with a mail request" do + let(:mail_package) { nil } + it "does not call #perform_later on MailRequestJob" do + expect(MailRequestJob).to_not receive(:perform_later) + subject + end + end + + context "document is not successfully processed" do + it "does not call #perform_later on MailRequestJob" do + allow(ProcessDecisionDocumentJob).to receive(:perform_later).and_raise(StandardError) + expect(MailRequestJob).to_not receive(:perform_later) + expect { subject }.to raise_error(StandardError) + end end end end diff --git a/spec/workflows/legacy_appeal_dispatch_spec.rb b/spec/workflows/legacy_appeal_dispatch_spec.rb index 59b729349b9..81c40e35793 100644 --- a/spec/workflows/legacy_appeal_dispatch_spec.rb +++ b/spec/workflows/legacy_appeal_dispatch_spec.rb @@ -1,61 +1,108 @@ # frozen_string_literal: true -describe LegacyAppealDispatch do +describe LegacyAppealDispatch, :all_dbs do + include ActiveJob::TestHelper + describe "#call" do - context "invalid citation number" do - it "returns an object with validation errors" do - legacy_appeal = build_stubbed(:legacy_appeal) + let(:user) { User.authenticate! } + let(:legacy_appeal) do + create(:legacy_appeal, + :with_veteran, + vacols_case: create(:case, :aod, :type_cavc_remand, bfregoff: "RO13", + folder: create(:folder, tinum: "13 11-265"))) + end + let(:root_task) { create(:root_task, appeal: legacy_appeal) } + let(:params) do + { appeal_id: legacy_appeal.id, + citation_number: "A18123456", + decision_date: Time.zone.today, + redacted_document_location: "some/filepath", + file: "some file" } + end + let(:mail_package) do + { distributions: [build(:mail_request).call.to_json], + copies: 1, + created_by_id: user.id } + end - params = { - appeal_id: legacy_appeal.id, - citation_number: "123", - decision_date: Time.zone.today, - redacted_document_location: "some/filepath", - file: "some file" - } + before(:all) { Seeds::NotificationEvents.new.seed! } - dispatch = LegacyAppealDispatch.new(appeal: legacy_appeal, params: params).call + before do + BvaDispatch.singleton.add_user(user) + BvaDispatchTask.create_from_root_task(root_task) + end - expect(dispatch).to_not be_success - expect(dispatch.errors[0]).to eq "Citation number is invalid" + subject do + perform_enqueued_jobs do + LegacyAppealDispatch.new(appeal: legacy_appeal, params: params, mail_package: mail_package).call end end - context "citation number already exists" do - it "returns an object with validation errors" do - legacy_appeal = build_stubbed(:legacy_appeal) - - params = { - appeal_id: legacy_appeal.id, - citation_number: "A18123456", - decision_date: Time.zone.today, - redacted_document_location: "some/filepath", - file: "some file" - } + context "valid parameters" do + it "successfully outcodes dispatch" do + expect(subject).to be_success + end + end - dispatch = LegacyAppealDispatch.new(appeal: legacy_appeal, params: params) - allow(dispatch).to receive(:unique_citation_number?).and_return(false) + context "invalid citation number" do + it "returns an object with validation errors" do + params[:citation_number] = "123" + expect(subject).to_not be_success + expect(subject.errors[0]).to eq "Citation number is invalid" + end + end - expect(dispatch.call).to_not be_success - expect(dispatch.call.errors[0]).to eq "Citation number already exists" + context "citation number already exists" do + it "returns an object with validation errors" do + allow_any_instance_of(LegacyAppealDispatch).to receive(:unique_citation_number?).and_return(false) + expect(subject).to_not be_success + expect(subject.errors[0]).to eq "Citation number already exists" end end context "missing required parameters" do it "returns an object with validation errors" do - legacy_appeal = build_stubbed(:legacy_appeal) - - params = { - appeal_id: legacy_appeal.id, - citation_number: "A18123456" - } + params[:decision_date] = nil + params[:redacted_document_location] = nil + params[:file] = nil - dispatch = LegacyAppealDispatch.new(appeal: legacy_appeal, params: params).call error_message = "Decision date can't be blank, Redacted document " \ "location can't be blank, File can't be blank" - expect(dispatch).to_not be_success - expect(dispatch.errors[0]).to eq error_message + expect(subject).to_not be_success + expect(subject.errors[0]).to eq error_message + end + end + + context "dispatch is associated with a mail request" do + it "calls #perform_later on MailRequestJob" do + expect(MailRequestJob).to receive(:perform_later) do |doc, pkg| + expect(doc).to be_a DecisionDocument + expect(doc.appeal_type).to eq "LegacyAppeal" + expect(doc.appeal_id).to eq params[:appeal_id] + expect(doc.citation_number).to eq params[:citation_number] + expect(doc.redacted_document_location).to eq params[:redacted_document_location] + + expect(pkg).to eq mail_package + end + + subject + end + end + + context "document is not associated with a mail request" do + let(:mail_package) { nil } + it "does not call #perform_later on MailRequestJob" do + expect(MailRequestJob).to_not receive(:perform_later) + subject + end + end + + context "document is not successfully processed" do + it "does not call #perform_later on MailRequestJob" do + allow(ProcessDecisionDocumentJob).to receive(:perform_later).and_raise(StandardError) + expect(MailRequestJob).to_not receive(:perform_later) + expect { subject }.to raise_error(StandardError) end end end From ef1a1d5a2f9b5629d6349dd59eb8491b243c4627 Mon Sep 17 00:00:00 2001 From: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:15:15 -0400 Subject: [PATCH 266/308] MattT/APPEALS-24860: Add JWT Support to Package Manager Service (#18920) * Remove TOKEN from default header * Add JWT generation to pacman service * Bring over base64url * Tweak env vars * Change comment * Create JwtGenerator conncern * Add concern file * Remove comment * Going to place SAML token into store in non-UTF-8 * Add env vars to Rails env configs --------- Co-authored-by: Matthew Thornton --- app/services/concerns/jwt_generator.rb | 20 +++++++++ app/services/external_api/pacman_service.rb | 45 ++++++++++++++++--- .../external_api/va_notify_service.rb | 15 +------ config/environments/development.rb | 7 ++- config/environments/test.rb | 8 +++- 5 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 app/services/concerns/jwt_generator.rb diff --git a/app/services/concerns/jwt_generator.rb b/app/services/concerns/jwt_generator.rb new file mode 100644 index 00000000000..102ab0fa91f --- /dev/null +++ b/app/services/concerns/jwt_generator.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module JwtGenerator + extend ActiveSupport::Concern + + module ClassMethods + # Purpose: Remove any illegal characters and keeps source at proper format + # + # Params: string + # + # Return: sanitized string + def base64url(source) + encoded_source = Base64.encode64(source) + encoded_source = encoded_source.sub(/=+$/, "") + encoded_source = encoded_source.tr("+", "-") + encoded_source = encoded_source.tr("/", "_") + encoded_source + end + end +end diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 3467757550f..0f3ee8d9816 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -5,13 +5,14 @@ require "digest" class ExternalApi::PacmanService + include JwtGenerator + BASE_URL = ENV["PACMAN_API_URL"] SEND_DISTRIBUTION_ENDPOINT = "/package-manager-service/distribution" SEND_PACKAGE_ENDPOINT = "/package-manager-service/communication-package" GET_DISTRIBUTION_ENDPOINT = "/package-manager-service/distribution/" HEADERS = { - "Content-Type": "application/json", Accept: "application/json", - "TOKEN": ENV["PACMAN_API_KEY"] + "Content-Type": "application/json", Accept: "application/json" }.freeze class << self @@ -136,6 +137,39 @@ def destinations_data(destination) }] end + def jwt_payload + current_epoch_timestamp = DateTime.now.strftime("%Q").to_i / 1000.floor + + { + iat: current_epoch_timestamp, + iss: ENV["PACMAN_API_TOKEN_ISSUER"], + aud: ENV["PACMAN_API_TOKEN_ISSUER"], + samlToken: ENV["PACMAN_API_SAML_TOKEN"]&.encode("UTF-8"), + externalSystemSource: ENV["PACMAN_API_SYS_ACCOUNT"] + } + end + + # Purpose: Generate the JWT token + # + # Params: none + # + # Return: token needed for authentication + def generate_token + header = { + alg: ENV["PACMAN_API_TOKEN_ALG"] + } + + stringified_header = header.to_json.encode("UTF-8") + encoded_header = base64url(stringified_header) + stringified_data = jwt_payload.to_json.encode("UTF-8") + encoded_data = base64url(stringified_data) + token = "#{encoded_header}.#{encoded_data}" + signature = OpenSSL::HMAC.digest("SHA512", ENV["PACMAN_API_TOKEN_SECRET"], token) + + # Signed Token + "#{token}.#{base64url(signature)}" + end + # Purpose: Build and send the request to the server # # Params: general requirements for HTTP request @@ -148,11 +182,12 @@ def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) request.open_timeout = 30 request.read_timeout = 30 request.body = body.to_json unless body.nil? - # not sure how user validation will be handled - request.headers = headers.merge(Bearer: ENV["PACMAN_API_KEY"]) + request.auth.ssl.ssl_version = :TLSv1_2 + request.auth.ssl.ca_cert_file = ENV["SSL_CERT_FILE"] + request.headers = headers.merge("X-Forwarded-User": generate_token) sleep 1 - MetricsService.record("pacman service #{method.to_s.upcase} request to #{url}", + MetricsService.record("Pacman Service #{method.to_s.upcase} request to #{url}", service: :pacman, name: endpoint) do case method diff --git a/app/services/external_api/va_notify_service.rb b/app/services/external_api/va_notify_service.rb index 38a6febf294..5f38a03e0c0 100644 --- a/app/services/external_api/va_notify_service.rb +++ b/app/services/external_api/va_notify_service.rb @@ -4,6 +4,8 @@ require "base64" require "digest" class ExternalApi::VANotifyService + include JwtGenerator + BASE_URL = ENV["VA_NOTIFY_API_URL"] CLIENT_SECRET = ENV["VA_NOTIFY_API_KEY"] SERVICE_ID = ENV["VA_NOTIFY_SERVICE_ID"] @@ -100,19 +102,6 @@ def generate_token signed_token end - # Purpose: Remove any illegal characters and keeps source at proper format - # - # Params: string - # - # Return: sanitized string - def base64url(source) - encoded_source = Base64.encode64(source) - encoded_source = encoded_source.sub(/=+$/, "") - encoded_source = encoded_source.tr("+", "-") - encoded_source = encoded_source.tr("/", "_") - encoded_source - end - # Purpose: Build an email request object # # Params: Details from appeal for notification diff --git a/config/environments/development.rb b/config/environments/development.rb index a47f5d8bf9b..02e591e960e 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -98,7 +98,12 @@ # Notifications page eFolder link ENV["CLAIM_EVIDENCE_EFOLDER_BASE_URL"] ||= "https://vefs-claimevidence-ui-uat.stage.bip.va.gov" - ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov/" + ENV["PACMAN_API_SAML_TOKEN"] ||= "our-saml-token" + ENV["PACMAN_API_TOKEN_SECRET"] ||= "client-secret" + ENV["PACMAN_API_TOKEN_ALG"] ||= "HS512" + ENV["PACMAN_API_TOKEN_ISSUER"] ||= "issuer-of-our-token" + ENV["PACMAN_API_SYS_ACCOUNT"] ||= "CSS_ID_OF_OUR_ACCOUNT" + ENV["PACMAN_API_URL"] ||= "https://pacman-uat.dev.bip.va.gov/" if ENV["WITH_TEST_EMAIL_SERVER"] config.action_mailer.delivery_method = :smtp diff --git a/config/environments/test.rb b/config/environments/test.rb index f13945cb2ef..89a089dabb7 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -114,6 +114,10 @@ ENV['TEST_VACOLS_HOST'] ||= "localhost" # Pacman environment variables - ENV["PACMAN_API_URL"] ||= "https://pacman-uat.stage.bip.va.gov" - ENV["PACMAN_API_KEY"] ||= "secret-key" + ENV["PACMAN_API_TOKEN_ALG"] ||= "HS512" + ENV["PACMAN_API_URL"] ||= "https://pacman-uat.dev.bip.va.gov" + ENV["PACMAN_API_SAML_TOKEN"] ||= "our-saml-token" + ENV["PACMAN_API_TOKEN_SECRET"] ||= "client-secret" + ENV["PACMAN_API_TOKEN_ISSUER"] ||= "issuer-of-our-token" + ENV["PACMAN_API_SYS_ACCOUNT"] ||= "CSS_ID_OF_OUR_ACCOUNT" end From 49bc01213adaa6d004d601920de6a497780c57e0 Mon Sep 17 00:00:00 2001 From: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Date: Mon, 3 Jul 2023 19:28:54 -0400 Subject: [PATCH 267/308] Remove use of ERB::Util.url_encode (#18930) Co-authored-by: Matthew Thornton --- app/services/external_api/pacman_service.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 0f3ee8d9816..b6bd1a3b0e6 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -177,8 +177,7 @@ def generate_token # Return: service_response: JSON from Pacman or error # :reek:LongParameterList def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) - url = ERB::Util.url_encode(BASE_URL + endpoint) - request = HTTPI::Request.new(url) + request = HTTPI::Request.new(BASE_URL + endpoint) request.open_timeout = 30 request.read_timeout = 30 request.body = body.to_json unless body.nil? From 56f2e4ba9425a6380ea77215fbd5fc21c332c7ad Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Mon, 3 Jul 2023 23:38:30 -0400 Subject: [PATCH 268/308] Add back url var --- app/services/external_api/pacman_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index b6bd1a3b0e6..c10c80f44bb 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -177,7 +177,8 @@ def generate_token # Return: service_response: JSON from Pacman or error # :reek:LongParameterList def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) - request = HTTPI::Request.new(BASE_URL + endpoint) + url= BASE_URL + endpoint + request = HTTPI::Request.new(url) request.open_timeout = 30 request.read_timeout = 30 request.body = body.to_json unless body.nil? From e38bea3a41e2cb112d55ede8ee4321bf846c8603 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Mon, 3 Jul 2023 23:46:37 -0400 Subject: [PATCH 269/308] Fix spacing --- app/services/external_api/pacman_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index c10c80f44bb..08ee00feafd 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -177,7 +177,7 @@ def generate_token # Return: service_response: JSON from Pacman or error # :reek:LongParameterList def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) - url= BASE_URL + endpoint + url = BASE_URL + endpoint request = HTTPI::Request.new(url) request.open_timeout = 30 request.read_timeout = 30 From 8c60d044639fd392cdefd72e58d24af957a094d1 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 5 Jul 2023 14:22:38 -0400 Subject: [PATCH 270/308] Fix uuid not being an attribute of string --- app/jobs/mail_request_job.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 7a81dab86b3..599a6d8372f 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -167,7 +167,6 @@ def log_error(error) # Response: n/a def log_info(info_message) uuid = SecureRandom.uuid - info_message.body.uuid = uuid - Rails.logger.info(info_message) + Rails.logger.info("#{info_message} - ID: #{uuid}") end end From 532b537ec664fa1833a4c71ef719eb918b81bd7c Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 5 Jul 2023 17:37:36 -0400 Subject: [PATCH 271/308] Incremental fixes --- app/jobs/mail_request_job.rb | 11 +++++++++-- app/services/external_api/pacman_service.rb | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 599a6d8372f..d8023b465a1 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -27,17 +27,23 @@ def perform(document_to_mail, mail_package) document_referenced(document_to_mail.document_version_reference_id, mail_package[:copies]) ) log_info(package_response) + + fail Caseflow::Error::PacmanApiError if package_response.error? rescue Caseflow::Error::PacmanApiError => error log_error(error) else vbms_comm_package = create_package(document_to_mail, mail_package) - vbms_comm_package.update!(status: "success", uuid: package_response.body[:id]) + vbms_comm_package.update!(status: "success", uuid: parse_comm_package_pacman_id(package_response)) create_distribution_request(vbms_comm_package.id, mail_package) end end private + def parse_comm_package_pacman_id(package_response) + JSON.parse(package_response.body)["id"] + end + # Purpose: arranges id and copies to pass into package post request # # takes in VbmsUploadedDocument id and copies integer @@ -167,6 +173,7 @@ def log_error(error) # Response: n/a def log_info(info_message) uuid = SecureRandom.uuid - Rails.logger.info("#{info_message} - ID: #{uuid}") + + Rails.logger.info("#{info_message.body} - ID: #{uuid}") end end diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 08ee00feafd..9bcc854b009 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -184,7 +184,7 @@ def send_pacman_request(headers: {}, endpoint:, method: :get, body: nil) request.body = body.to_json unless body.nil? request.auth.ssl.ssl_version = :TLSv1_2 request.auth.ssl.ca_cert_file = ENV["SSL_CERT_FILE"] - request.headers = headers.merge("X-Forwarded-User": generate_token) + request.headers = headers.merge("X-Forwarded-User": ENV["PACMAN_API_JWT"]) sleep 1 MetricsService.record("Pacman Service #{method.to_s.upcase} request to #{url}", From 8bf6512373ac9180eae7e7168d016014d85d1b5d Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 5 Jul 2023 19:05:04 -0400 Subject: [PATCH 272/308] More tweaks --- app/jobs/mail_request_job.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index d8023b465a1..551e562c48a 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -33,15 +33,15 @@ def perform(document_to_mail, mail_package) log_error(error) else vbms_comm_package = create_package(document_to_mail, mail_package) - vbms_comm_package.update!(status: "success", uuid: parse_comm_package_pacman_id(package_response)) + vbms_comm_package.update!(status: "success", uuid: parse_pacman_id(package_response)) create_distribution_request(vbms_comm_package.id, mail_package) end end private - def parse_comm_package_pacman_id(package_response) - JSON.parse(package_response.body)["id"] + def parse_pacman_id(pacman_response) + JSON.parse(pacman_response.body)["id"] end # Purpose: arranges id and copies to pass into package post request @@ -86,18 +86,16 @@ def create_distribution_request(package_id, mail_package) distributions = mail_package[:distributions] distributions.each do |dist| begin - dist_hash = JSON.parse(dist) - rescue Caseflow::Error::PacmanApiError => error - log_error(error) - else - distribution = VbmsDistribution.find(dist_hash["vbms_distribution_id"]) + distribution = VbmsDistribution.find(dist[:vbms_distribution_id]) distribution_response = PacmanService.send_distribution_request( package_id, get_recipient_hash(distribution), - get_destinations_hash(dist_hash) + get_destinations_hash(dist) ) log_info(distribution_response) - distribution.update!(vbms_communication_package_id: package_id, uuid: distribution_response.body[:id]) + distribution.update!(vbms_communication_package_id: package_id, uuid: parse_pacman_id(distribution_response)) + rescue Caseflow::Error::PacmanApiError => error + log_error(error) end end end From 7d9631dce7976c89cfad32ebc1a6544fd117664e Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 5 Jul 2023 19:09:39 -0400 Subject: [PATCH 273/308] Loop over distros in response --- app/jobs/mail_request_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 551e562c48a..77dd7a9a4ed 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -92,7 +92,7 @@ def create_distribution_request(package_id, mail_package) get_recipient_hash(distribution), get_destinations_hash(dist) ) - log_info(distribution_response) + distribution_response.each { |response| log_info(response) } distribution.update!(vbms_communication_package_id: package_id, uuid: parse_pacman_id(distribution_response)) rescue Caseflow::Error::PacmanApiError => error log_error(error) From 3e124bdc0e5ed49b80466a566db5efb147f93561 Mon Sep 17 00:00:00 2001 From: Matthew Thornton <99351305+ThorntonMatthew@users.noreply.github.com> Date: Thu, 6 Jul 2023 00:14:32 -0400 Subject: [PATCH 274/308] MattT/19983-fixes (#18947) * Adjust destination hash creation * Alter get_recipient_hash * Change hash syntax * Pass in comm package uuid as ID * Fix endpoint * Fix transaction * Add comment * Paranoia mode * Another backup plan * Comments * More paranoia --------- Co-authored-by: Matthew Thornton --- app/jobs/mail_request_job.rb | 104 +++++++++++++----- app/services/external_api/pacman_service.rb | 2 +- .../external_api/pacman_service/response.rb | 2 +- lib/fakes/pacman_service.rb | 82 +++++++------- 4 files changed, 119 insertions(+), 71 deletions(-) diff --git a/app/jobs/mail_request_job.rb b/app/jobs/mail_request_job.rb index 77dd7a9a4ed..962cc47bcea 100644 --- a/app/jobs/mail_request_job.rb +++ b/app/jobs/mail_request_job.rb @@ -32,16 +32,31 @@ def perform(document_to_mail, mail_package) rescue Caseflow::Error::PacmanApiError => error log_error(error) else - vbms_comm_package = create_package(document_to_mail, mail_package) - vbms_comm_package.update!(status: "success", uuid: parse_pacman_id(package_response)) - create_distribution_request(vbms_comm_package.id, mail_package) + ActiveRecord::Base.transaction do + vbms_comm_package = create_package(document_to_mail, mail_package) + vbms_comm_package.update!(status: "success", uuid: parse_pacman_id(package_response)) + create_distribution_request(vbms_comm_package.id, mail_package) + end end end private + # Purpose: Parses responses from the PacMan API and pulls out the + # + # ID (UUID) of the entity created in the request. + # + # Response: The UUID of the communication package or distribution just created def parse_pacman_id(pacman_response) - JSON.parse(pacman_response.body)["id"] + response_body = pacman_response.body + + parsed_body = if response_body.is_a?(ActiveSupport::HashWithIndifferentAccess) + response_body + else + JSON.parse(response_body) + end + + parsed_body.with_indifferent_access[:id] end # Purpose: arranges id and copies to pass into package post request @@ -77,6 +92,19 @@ def get_package_name(document_to_mail) "#{document_to_mail.document_name}_#{Time.now.utc.strftime('%Y%m%d%k%M%S')}" end + # Purpose: Find a VbmsDistribution from various input formats + # + # Response: The corresponding VbmsDistribution record + def find_associated_vbms_distribution_record(distribution_info) + parsed_distro = if [ActiveSupport::HashWithIndifferentAccess, Hash].include?(distribution_info.class) + distribution_info + else + JSON.parse(distribution_info) + end + + VbmsDistribution.find(parsed_distro.with_indifferent_access[:vbms_distribution_id]) + end + # Purpose: sends distribution POST request to Pacman API # # takes in VbmsCommunicationPackage id (string) and MailRequest object @@ -84,16 +112,19 @@ def get_package_name(document_to_mail) # Response: n/a def create_distribution_request(package_id, mail_package) distributions = mail_package[:distributions] + distributions.each do |dist| begin - distribution = VbmsDistribution.find(dist[:vbms_distribution_id]) - distribution_response = PacmanService.send_distribution_request( - package_id, + distribution = find_associated_vbms_distribution_record(dist) + distribution_responses = PacmanService.send_distribution_request( + VbmsCommunicationPackage.find(package_id).uuid, get_recipient_hash(distribution), get_destinations_hash(dist) ) - distribution_response.each { |response| log_info(response) } - distribution.update!(vbms_communication_package_id: package_id, uuid: parse_pacman_id(distribution_response)) + distribution_responses.each do |response| + log_info(response) + distribution.update!(vbms_communication_package_id: package_id, uuid: parse_pacman_id(response)) + end rescue Caseflow::Error::PacmanApiError => error log_error(error) end @@ -109,36 +140,51 @@ def get_recipient_hash(distribution) { type: distribution.recipient_type, name: distribution.name, - firstName: distribution.first_name, - middleName: distribution.middle_name, - lastName: distribution.last_name, - participantId: distribution.participant_id, - poaCode: distribution.poa_code, - claimantStationOfJurisdiction: distribution.claimant_station_of_jurisdiction + first_name: distribution.first_name, + middle_name: distribution.middle_name, + last_name: distribution.last_name, + participant_id: distribution.participant_id, + poa_code: distribution.poa_code, + claimant_station_of_jurisdiction: distribution.claimant_station_of_jurisdiction } end + # Purpose: Find root of available destination information + # + # Response: Hash containing the root of available destination information + def parse_recipient_info_from_destinaton(destination_info) + parsed_destination = if [ActiveSupport::HashWithIndifferentAccess, Hash].include?(destination_info.class) + destination_info + else + JSON.parse(destination_info).with_indifferent_access + end + + parsed_destination[:recipient_info] || parsed_destination["recipient_info"] || parsed_destination + end + # Purpose: creates destination hash from VbmsDistributionDestination attributes # # takes in VbmsDistributionDestination object # # Response: array that holds a hash def get_destinations_hash(destination) + recipient_info = parse_recipient_info_from_destinaton(destination) + [{ - "type" => destination["destination_type"], - "addressLine1" => destination["address_line_1"], - "addressLine2" => destination["address_line_2"], - "addressLine3" => destination["address_line_3"], - "addressLine4" => destination["address_line_4"], - "addressLine5" => destination["address_line_5"], - "addressLine6" => destination["address_line_6"], - "treatLine2AsAddressee" => destination["treat_line_2_as_addressee"], - "treatLine3AsAddressee" => destination["treat_line_3_as_addressee"], - "city" => destination["city"], - "state" => destination["state"], - "postalCode" => destination["postal_code"], - "countryName" => destination["country_name"], - "countryCode" => destination["country_code"] + type: recipient_info[:destination_type], + addressLine1: recipient_info[:address_line_1], + addressLine2: recipient_info[:address_line_2], + addressLine3: recipient_info[:address_line_3], + addressLine4: recipient_info[:address_line_4], + addressLine5: recipient_info[:address_line_5], + addressLine6: recipient_info[:address_line_6], + treatLine2AsAddressee: recipient_info[:treat_line_2_as_addressee], + treatLine3AsAddressee: recipient_info[:treat_line_3_as_addressee], + city: recipient_info[:city], + state: recipient_info[:state], + postalCode: recipient_info[:postal_code], + countryName: recipient_info[:country_name], + countryCode: recipient_info[:country_code] }] end diff --git a/app/services/external_api/pacman_service.rb b/app/services/external_api/pacman_service.rb index 9bcc854b009..b309d4a8b2f 100644 --- a/app/services/external_api/pacman_service.rb +++ b/app/services/external_api/pacman_service.rb @@ -91,7 +91,7 @@ def distribution_request(package_id, recipient, destination) destinations: destinations_data(destination) }, headers: HEADERS, - endpoint: SEND_PACKAGE_ENDPOINT, method: :post + endpoint: SEND_DISTRIBUTION_ENDPOINT, method: :post }.compact end diff --git a/app/services/external_api/pacman_service/response.rb b/app/services/external_api/pacman_service/response.rb index 8c5412e448b..1e491e5c836 100644 --- a/app/services/external_api/pacman_service/response.rb +++ b/app/services/external_api/pacman_service/response.rb @@ -23,7 +23,7 @@ def success? # Parses response body to an object def body @body ||= begin - JSON.parse(resp.body) + JSON.parse(resp.body).with_indifferent_access rescue JSON::ParserError log(JSON::ParserError) {} diff --git a/lib/fakes/pacman_service.rb b/lib/fakes/pacman_service.rb index 06b9c137e25..9da83eedef7 100644 --- a/lib/fakes/pacman_service.rb +++ b/lib/fakes/pacman_service.rb @@ -10,7 +10,7 @@ def send_communication_package_request(file_number, name, document_references) end def send_distribution_request(package_id, recipient, destinations) - fake_distribution_request(package_id, recipient, destinations) + [fake_distribution_request(package_id, recipient, destinations)] end def get_distribution_request(distribution_uuid) @@ -27,10 +27,10 @@ def bad_request_response HTTPI::Response.new( 400, {}, - OpenStruct.new( + { "error": "BadRequestError", "message": "participant id is not valid" - ) + }.with_indifferent_access ) end @@ -38,10 +38,10 @@ def bad_access_response HTTPI::Response.new( 403, {}, - OpenStruct.new( + { "error": "BadRequestError", "message": "package cannot be created because of insufficient privileges" - ) + }.with_indifferent_access ) end @@ -49,10 +49,10 @@ def distribution_not_found_response HTTPI::Response.new( 404, {}, - OpenStruct.new( + { "error": "BadRequestError", "message": "distribution does not exist at this time" - ) + }.with_indifferent_access ) end @@ -61,14 +61,14 @@ def fake_package_request(file_number, name, document_references) HTTPI::Response.new( 201, {}, - OpenStruct.new( - "id": COMMUNICATION_PACKAGE_UUID, + { + "id" => COMMUNICATION_PACKAGE_UUID, "fileNumber": file_number, "name": name, "documentReferences": document_references, "status": "NEW", "createDate": "" - ) + }.with_indifferent_access ) end @@ -77,7 +77,7 @@ def fake_distribution_request(package_id, recipient, destinations) HTTPI::Response.new( 201, {}, - OpenStruct.new( + { "id": DISTRIBUTION_UUID, "recipient": recipient, "description": "bad", @@ -85,7 +85,7 @@ def fake_distribution_request(package_id, recipient, destinations) "destinations": destinations, "status": "", "sentToCbcmDate": "" - ) + }.with_indifferent_access ) end @@ -95,35 +95,37 @@ def fake_distribution_response(_distribution_id) HTTPI::Response.new( 200, {}, - "id": DISTRIBUTION_UUID, - "recipient": { - "type": "system", - "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", - "name": "VBMS-C" - }, - "description": "Staging Mailing Distribution", - "communicationPackageId": 1, - "destinations": [{ - "type": "physicalAddress", - "id": "28440040-51a5-4d2a-81a2-28730827be14", + { + "id": DISTRIBUTION_UUID, + "recipient": { + "type": "system", + "id": "a050a21e-23f6-4743-a1ff-aa1e24412eff", + "name": "VBMS-C" + }, + "description": "Staging Mailing Distribution", + "communicationPackageId": 1, + "destinations": [{ + "type": "physicalAddress", + "id": "28440040-51a5-4d2a-81a2-28730827be14", + "status": "", + "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", + "addressLine1": "POSTMASTER GENERAL", + "addressLine2": "UNITED STATES POSTAL SERVICE", + "addressLine3": "475 LENFANT PLZ SW RM 10022", + "addressLine4": "SUITE 123", + "addressLine5": "APO AE 09001-5275", + "addressLine6": "", + "treatLine2AsAddressee": true, + "treatLine3AsAddressee": true, + "city": "WASHINGTON DC", + "state": "DC", + "postalCode": "12345", + "countryName": "UNITED STATES", + "countryCode": "us" + }], "status": "", - "cbcmSendAttemptDate": "2022-06-06T16:35:27.996", - "addressLine1": "POSTMASTER GENERAL", - "addressLine2": "UNITED STATES POSTAL SERVICE", - "addressLine3": "475 LENFANT PLZ SW RM 10022", - "addressLine4": "SUITE 123", - "addressLine5": "APO AE 09001-5275", - "addressLine6": "", - "treatLine2AsAddressee": true, - "treatLine3AsAddressee": true, - "city": "WASHINGTON DC", - "state": "DC", - "postalCode": "12345", - "countryName": "UNITED STATES", - "countryCode": "us" - }], - "status": "", - "sentToCbcmDate": "" + "sentToCbcmDate": "" + }.with_indifferent_access ) end # rubocop:enable Metrics/MethodLength From 4e1ee8f08e278ca8852a90fe37fd49b7fd04456c Mon Sep 17 00:00:00 2001 From: Prajwal Amatya <122557351+pamatyatake2@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:31:30 -0600 Subject: [PATCH 275/308] removing skip and making test work (#18943) --- spec/controllers/organizations/users_controller_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/controllers/organizations/users_controller_spec.rb b/spec/controllers/organizations/users_controller_spec.rb index 132826bf5af..11cee50f66e 100644 --- a/spec/controllers/organizations/users_controller_spec.rb +++ b/spec/controllers/organizations/users_controller_spec.rb @@ -274,7 +274,7 @@ let!(:params) { { organization_url: org.url, id: user.id } } let(:org) { create(:judge_team, :has_judge_team_lead_as_admin) } - let!(:user) do + let(:user) do create(:user).tap do |user| org.add_user(user) end @@ -300,7 +300,9 @@ end end - context "when user is the judge in the organization", skip: "Flake" do + context "when user is the judge in the organization" do + let(:user) { org.admin } + it "returns an error" do subject From 247dc97f2c3dec33d4fc55453870a148dbc91da5 Mon Sep 17 00:00:00 2001 From: Prajwal Amatya <122557351+pamatyatake2@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:42:04 -0600 Subject: [PATCH 276/308] Fixing the flaky test (#18944) --- spec/feature/hearings/daily_docket/build_hearsched_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/feature/hearings/daily_docket/build_hearsched_spec.rb b/spec/feature/hearings/daily_docket/build_hearsched_spec.rb index 0d64bb1f58b..e02dcfac20b 100644 --- a/spec/feature/hearings/daily_docket/build_hearsched_spec.rb +++ b/spec/feature/hearings/daily_docket/build_hearsched_spec.rb @@ -72,10 +72,10 @@ let!(:hearing) { create(:hearing, :with_tasks) } let!(:postponed_hearing_day) { create(:hearing_day, scheduled_for: Date.new(2019, 3, 3)) } - scenario "User can update fields", skip: "flake" do + scenario "User can update fields" do visit "hearings/schedule/docket/" + hearing.hearing_day.id.to_s find("textarea", id: "#{hearing.external_id}-notes").click.send_keys("This is a note about the hearing!") - find("label", text: "9:00 am").click + find("label", text: "9:00 AM Eastern Time (US & Canada)").click find("label", text: "Transcript Requested").click click_button("Save") expect(page).to have_content("You have successfully updated") @@ -87,7 +87,7 @@ expect(page).to have_content("No Show") expect(page).to have_content("This is a note about the hearing!", wait: 10) # flake expect(find_field("Transcript Requested", visible: false)).to be_checked - expect(find_field("9:00 am", visible: false)).to be_checked + expect(find_field("9:00 AM", visible: false)).to be_checked end end From 454d558a1ca9f3d978bb2166e4be490f0614cdeb Mon Sep 17 00:00:00 2001 From: Brandon Lee Dorner Date: Thu, 6 Jul 2023 11:17:29 -0500 Subject: [PATCH 277/308] Remove rspec skip: "flake" (#18928) In the process of maintaining a better testing suite we are attempting to remove all rspec tests that are skipped. This specific instance there was a skip that is no longer needed as the test does not fail. We can also remove supplemental claims being created as they aren't relevant to the test. --- spec/controllers/appeals_controller_spec.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/spec/controllers/appeals_controller_spec.rb b/spec/controllers/appeals_controller_spec.rb index d8c685e64b9..616680c5549 100644 --- a/spec/controllers/appeals_controller_spec.rb +++ b/spec/controllers/appeals_controller_spec.rb @@ -218,11 +218,8 @@ end context "when request header contains nonexistent Veteran file number" do - it "returns 404 error", skip: "flake" do - appeal = create(:appeal, claimants: [build(:claimant, participant_id: "CLAIMANT_WITH_PVA_AS_VSO")]) - create(:supplemental_claim, veteran_file_number: appeal.veteran_file_number) - - request.headers["HTTP_CASE_SEARCH"] = "123" + it "returns 404 error" do + request.headers["HTTP_CASE_SEARCH"] = "123456789" expect_any_instance_of(Fakes::BGSService).to_not receive(:fetch_poas_by_participant_id) From d9967c6eba24546eeec5d743c1496677bfdff726 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Thu, 6 Jul 2023 13:21:11 -0400 Subject: [PATCH 278/308] Fix format_response --- .../idt/api/v2/distributions_controller.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 477178d9a3d..8476d2d06b5 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -37,11 +37,17 @@ def pending_establishment(distribution_id) end def format_response(response) - new_response = response.raw_body.to_json - parsed_response = JSON.parse(new_response) - # Convert keys from camelCase to snake_case - parsed_response.deep_transform_keys do |key| - key.to_s.underscore.gsub(/e(\d)/, 'e_\1') + response_body = response.raw_body + + begin + parsed_response = JSON.parse(response_body) + + # Convert keys from camelCase to snake_case + parsed_response.deep_transform_keys do |key| + key.to_s.underscore.gsub(/e(\d)/, 'e_\1') + end + rescue JSON::ParseError => _error + response_body end end From 2a2bd693b53862aee59ae0ea022efc696bc55ce5 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Thu, 6 Jul 2023 13:36:14 -0400 Subject: [PATCH 279/308] Log error if response body isn't able to be parsed as JSON --- app/controllers/idt/api/v2/distributions_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 8476d2d06b5..9637d1cae9a 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -46,7 +46,9 @@ def format_response(response) parsed_response.deep_transform_keys do |key| key.to_s.underscore.gsub(/e(\d)/, 'e_\1') end - rescue JSON::ParseError => _error + rescue JSON::ParseError => error + log_error(error) + response_body end end From e9ccd94956c44c0b57283d62d7c84d6dd48f6b80 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Thu, 6 Jul 2023 13:46:11 -0400 Subject: [PATCH 280/308] Add distro id to error log --- app/controllers/idt/api/v2/distributions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/idt/api/v2/distributions_controller.rb b/app/controllers/idt/api/v2/distributions_controller.rb index 9637d1cae9a..2b35a8435ff 100644 --- a/app/controllers/idt/api/v2/distributions_controller.rb +++ b/app/controllers/idt/api/v2/distributions_controller.rb @@ -47,7 +47,7 @@ def format_response(response) key.to_s.underscore.gsub(/e(\d)/, 'e_\1') end rescue JSON::ParseError => error - log_error(error) + log_error(error + " Distribution ID: #{params[:distribution_id]}") response_body end From 832f0b7d01cef33070639f52c46aff897ccaeebe Mon Sep 17 00:00:00 2001 From: Tyler Broyles <109369527+TylerBroyles@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:05:14 -0400 Subject: [PATCH 281/308] TYLERB/APPEALS-24082: Remove task_filter_spec.rb flakey test tag (#18935) * Removed flakey tag from a test in task_filter_spec and a test in hearings_controller_spec. * Updated the appeal_series_issue_spec. * Changed expect to properly match the subject for one test. * Removed an expect statement that was no longer valid. --- spec/controllers/hearings_controller_spec.rb | 2 +- spec/models/appeal_series_issues_spec.rb | 61 +++++++++++++------- spec/models/task_filter_spec.rb | 2 +- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/spec/controllers/hearings_controller_spec.rb b/spec/controllers/hearings_controller_spec.rb index a863d585317..3b17bbde7f8 100644 --- a/spec/controllers/hearings_controller_spec.rb +++ b/spec/controllers/hearings_controller_spec.rb @@ -453,7 +453,7 @@ expect(response.status).to eq 200 end - it "should return a 200 and update aod if provided", :aggregate_failures, skip: "flake AOD present" do + it "should return a 200 and update aod if provided", :aggregate_failures do params = { id: ama_hearing.external_id, advance_on_docket_motion: { diff --git a/spec/models/appeal_series_issues_spec.rb b/spec/models/appeal_series_issues_spec.rb index 9e40ca71516..b9215160f0b 100644 --- a/spec/models/appeal_series_issues_spec.rb +++ b/spec/models/appeal_series_issues_spec.rb @@ -68,7 +68,27 @@ end let(:combined_issues) do - AppealSeriesIssues.new(appeal_series: series).all.sort_by { |issue_hash| issue_hash[:diagnostic_code] } + AppealSeriesIssues.new(appeal_series: series).all + end + + let(:combined_issues_array) do + [ + { + description: "Service connection, limitation of thigh motion (flexion)", + diagnosticCode: "5252", + active: true, + lastAction: :remand, + date: 6.months.ago.to_date + }, + { + description: "New and material evidence to reopen claim for service connection,"\ + " shoulder or arm muscle injury", + diagnosticCode: "5301", + active: false, + lastAction: :allowed, + date: 6.months.ago.to_date + } + ] end context "#all" do @@ -77,18 +97,7 @@ context "when an issue spans a remand" do it "combines issues together" do expect(subject.length).to eq(2) - expect(subject.first[:description]).to eq( - "Service connection, limitation of thigh motion (flexion)" - ) - expect(subject.first[:active]).to be_truthy - expect(subject.first[:lastAction]).to eq(:remand) - expect(subject.first[:date]).to eq(6.months.ago.to_date) - expect(subject.last[:description]).to eq( - "New and material evidence to reopen claim for service connection, shoulder or arm muscle injury" - ) - expect(subject.last[:active]).to be_falsey - expect(subject.last[:lastAction]).to eq(:allowed) - expect(subject.last[:date]).to eq(6.months.ago.to_date) + expect(subject).to match_array(combined_issues_array) end context "when there is a draft decision" do @@ -105,9 +114,7 @@ it "does not show the draft disposition" do expect(subject.length).to eq(2) - expect(subject.first[:active]).to be_truthy - expect(subject.first[:date]).to eq(6.months.ago.to_date) - expect(subject.first[:lastAction]).to eq(:remand) + expect(subject).to match_array(combined_issues_array) end end end @@ -116,7 +123,7 @@ let(:appeals) { [original] } it "is marked as active" do - expect(subject.first[:active]).to be_truthy + expect(subject).to match_array(combined_issues_array) end end @@ -124,6 +131,7 @@ let(:original_issues) { [] } it "returns issues" do + expect(subject.length).to eq(1) expect(subject.first[:description]).to eq("Service connection, limitation of thigh motion (flexion)") end end @@ -151,7 +159,15 @@ end it "does not show as a last_action" do - expect(subject.first[:lastAction]).to eq(:remand) + expect(subject.length).to eq(3) + other_hash = { + description: "Other", + diagnosticCode: nil, + active: false, + lastAction: nil, + date: nil + } + expect(subject).to match_array(combined_issues_array.push(other_hash)) end end @@ -161,8 +177,13 @@ end it "appears as the last action" do - expect(subject.first[:lastAction]).to eq(:cavc_remand) - expect(subject.first[:date]).to eq(1.month.ago.to_date) + expect(subject.length).to eq(2) + expect(subject).to include( + a_hash_including( + lastAction: :cavc_remand, + date: 1.month.ago.to_date + ) + ) end end end diff --git a/spec/models/task_filter_spec.rb b/spec/models/task_filter_spec.rb index 4204ffecc2c..98e7036659b 100644 --- a/spec/models/task_filter_spec.rb +++ b/spec/models/task_filter_spec.rb @@ -381,7 +381,7 @@ def create_cached_appeals_for_tasks(tasks, case_type) ["col=#{Constants.QUEUE_CONFIG.COLUMNS.APPEAL_TYPE.name}&val=#{case_types['1']}|#{case_types['2']}"] end - it "returns tasks with Original or Supplemental case types", skip: "flakey" do + it "returns tasks with Original or Supplemental case types" do expect(subject.map(&:id)).to match_array(tasks_type_original.map(&:id) + tasks_type_supplemental.map(&:id)) end end From 04b61b90a7c946c8846059c0713d0bc534bedc22 Mon Sep 17 00:00:00 2001 From: Brandon Dorner Date: Thu, 6 Jul 2023 12:21:38 -0500 Subject: [PATCH 282/308] Remove flake test skip for case_details_spec.rb In the process of maintaining a better testing suite we are attempting to remove all rspec tests that are skipped. This specific instance there was a skip that is no longer needed as the test does not fail when ran. Upon further research it looks like the pagination has been fixed and now allows the test to work correctly. --- spec/feature/queue/case_details_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/feature/queue/case_details_spec.rb b/spec/feature/queue/case_details_spec.rb index 9688f477954..ad4ac936d3a 100644 --- a/spec/feature/queue/case_details_spec.rb +++ b/spec/feature/queue/case_details_spec.rb @@ -153,7 +153,7 @@ def wait_for_page_render expect(details_link.text).to eq(COPY::CASE_DETAILS_HEARING_DETAILS_LINK_COPY) end - context "the user has a VSO role", skip: "re-enable when pagination is fixed" do + context "the user has a VSO role" do let!(:vso) { create(:vso, name: "VSO", role: "VSO", url: "vso-url", participant_id: "8054") } let!(:vso_user) { create(:user, :vso_role) } let!(:vso_task) { create(:ama_vso_task, :in_progress, assigned_to: vso, appeal: appeal) } From c99cc68fb14080abc4641b5792bdd6d1fa030e8e Mon Sep 17 00:00:00 2001 From: Prajwal Amatya <122557351+pamatyatake2@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:22:51 -0600 Subject: [PATCH 283/308] Pamatya/appeals 24085 (#18966) * APPEALS-24085: removing skip * APPEALS-24150: flaky has seems to fix by itself --- spec/feature/out_of_service_spec.rb | 9 ++++++--- spec/models/validators/intake_start_validator_spec.rb | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/spec/feature/out_of_service_spec.rb b/spec/feature/out_of_service_spec.rb index 9ebeaf5be29..ae38d2b836a 100644 --- a/spec/feature/out_of_service_spec.rb +++ b/spec/feature/out_of_service_spec.rb @@ -11,10 +11,13 @@ User.unauthenticate! end - scenario "When out of service is disabled, it shows Caseflow Home page", - skip: "This test is failing because of a bad feature toggle set somewhere" do + scenario "When out of service is disabled, it shows Caseflow Home page", :aggregate_failures do visit "/" - expect(page).to have_content("Caseflow Help") + expect(page).to have_current_path("/") + expect(page).to have_content("BVAAABSHIRE (DSUSER)") + expect(page).to have_link("Queue") + expect(page).to have_content("Search case") + expect(page).to have_content("Send feedback") expect(page.has_no_content?("Technical Difficulties")).to eq(true) end diff --git a/spec/models/validators/intake_start_validator_spec.rb b/spec/models/validators/intake_start_validator_spec.rb index fc8fba85b9c..45c0056b69c 100644 --- a/spec/models/validators/intake_start_validator_spec.rb +++ b/spec/models/validators/intake_start_validator_spec.rb @@ -21,7 +21,7 @@ context "when BGS shows a station conflict" do let(:station_conflict) { true } - it "sets error_code \"veteran_not_modifiable\" when BGS shows a station conflict", skip: "Flake" do + it "sets error_code \"veteran_not_modifiable\" when BGS shows a station conflict" do subject expect(intake.error_code).to eq "veteran_not_modifiable" @@ -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: "Flake" do + it "sets a veteran_not_modifiable error code" do subject expect(intake.error_code).to eq "veteran_not_modifiable" From 87ad81205318589abccfa86200c4cba7137601f9 Mon Sep 17 00:00:00 2001 From: Clay Sheppard Date: Mon, 10 Jul 2023 15:40:48 -0500 Subject: [PATCH 284/308] fix certification model flaky test (#18977) --- spec/models/certification_spec.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/models/certification_spec.rb b/spec/models/certification_spec.rb index 08b6942717b..7329f8f16e9 100644 --- a/spec/models/certification_spec.rb +++ b/spec/models/certification_spec.rb @@ -6,7 +6,7 @@ end let(:vacols_case) do - create(:case_with_ssoc) + create(:case_with_ssoc, :representative_american_legion) end let(:certification) do @@ -356,9 +356,7 @@ context "#fetch_power_of_attorney!" do subject { certification } - - it "returns true when bgs address is found", - skip: "VACOLS rep test fails sometimes, will be changed with #5185 so ignoring it for now" do + it "fetches the power of attorney from bgs and vacols" do certification.async_start! expect(subject.bgs_rep_city).to eq "SAN FRANCISCO" expect(subject.bgs_representative_type).to eq "Attorney" From 121eab9f3a394a469c5afe1ef8bedaa4a67db821 Mon Sep 17 00:00:00 2001 From: Craig Reese <109101548+craigrva@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:53:59 -0500 Subject: [PATCH 285/308] Craig/appeals 24754 (#18976) * refactor test to use factories instead of Model.create, fix associations * remove hardcoded CSS IDs * fix lint * tweaks to tests with failures in GHA --- spec/controllers/hearings_controller_spec.rb | 2 +- .../queue/colocated_task_queue_spec.rb | 5 +- spec/models/judge_case_review_spec.rb | 103 ++++++++---------- 3 files changed, 47 insertions(+), 63 deletions(-) diff --git a/spec/controllers/hearings_controller_spec.rb b/spec/controllers/hearings_controller_spec.rb index 3b17bbde7f8..00753efa88d 100644 --- a/spec/controllers/hearings_controller_spec.rb +++ b/spec/controllers/hearings_controller_spec.rb @@ -458,7 +458,7 @@ id: ama_hearing.external_id, advance_on_docket_motion: { user_id: user.id, - person_id: ama_hearing.appeal.appellant.id, + person_id: ama_hearing.appeal.appellant.person.id, reason: Constants.AOD_REASONS.age, granted: true }, diff --git a/spec/feature/queue/colocated_task_queue_spec.rb b/spec/feature/queue/colocated_task_queue_spec.rb index d0f15e562a7..88a5af39375 100644 --- a/spec/feature/queue/colocated_task_queue_spec.rb +++ b/spec/feature/queue/colocated_task_queue_spec.rb @@ -56,6 +56,7 @@ find(".cf-form-dropdown", text: "Select number of tasks to assign").click find("option", text: "1 (all available tasks)").click find("button", id: "Bulk-Assign-Tasks-button-id-1").click # going by text is an ambiguous match + expect(page).to have_content("You have bulk assigned 1 Poa Clarification Colocated Task tasks") # Visit case details page for VLJ support staff. User.authenticate!(user: vlj_support_staff) @@ -84,8 +85,8 @@ # verify that the instructions from the VLJ appear on the case timeline expect(page).to have_css("h2", text: "Case Timeline") scroll_to(find("h2", text: "Case Timeline")) - poa_task = PoaClarificationColocatedTask.find_by(assigned_to_type: User.name) - click_button(COPY::TASK_SNAPSHOT_VIEW_TASK_INSTRUCTIONS_LABEL, id: poa_task.id) + poa_task = PoaClarificationColocatedTask.last + click_button(text: COPY::TASK_SNAPSHOT_VIEW_TASK_INSTRUCTIONS_LABEL, id: poa_task.id) expect(page).to have_content(return_instructions) # Expect to see draft decision option. find(".cf-select__control", text: "Select an action…").click diff --git a/spec/models/judge_case_review_spec.rb b/spec/models/judge_case_review_spec.rb index 9e9f79e57e4..5d8131d4308 100644 --- a/spec/models/judge_case_review_spec.rb +++ b/spec/models/judge_case_review_spec.rb @@ -23,7 +23,7 @@ def complete_params(judge:, attorney:, location:, vacols_issue1:, vacols_issue2: # rubocop:disable Metrics/AbcSize def expect_decass_to_be_up_to_date(decass) decass.reload - expect(decass.demdusr).to eq "CFS456" + expect(decass.demdusr).to eq vacols_judge.slogid expect(decass.defdiff).to eq "3" expect(decass.deoq).to eq "1" expect(decass.deqr2).to eq "Y" @@ -35,7 +35,6 @@ def expect_decass_to_be_up_to_date(decass) expect(decass.decomp).to eq VacolsHelper.local_date_with_utc_timezone expect(decass.detrem).to eq "N" end -# rubocop:enable Metrics/AbcSize def expect_case_to_be_update_to_date(vacols_case, decass) expect(vacols_case.bfmemid).to eq(decass.dememid) @@ -43,6 +42,20 @@ def expect_case_to_be_update_to_date(vacols_case, decass) expect(vacols_case.bfboard).to eq(decass.deteam) end +def expect_case_review_to_match_params(case_review) + expect(case_review.valid?).to eq true + expect(case_review.complexity).to eq "hard" + expect(case_review.quality).to eq "does_not_meet_expectations" + expect(case_review.comment).to eq "do this" + expect(case_review.factors_not_considered).to match_array %w[theory_contention relevant_records] + expect(case_review.areas_for_improvement).to match_array ["process_violations"] + expect(case_review.judge).to eq judge + expect(case_review.attorney).to eq attorney + expect(case_review.appeal_type).to eq "LegacyAppeal" + expect(case_review.appeal_id).to eq LegacyAppeal.find_by_vacols_id(vacols_case.bfkey).id +end +# rubocop:enable Metrics/AbcSize + describe JudgeCaseReview, :all_dbs do before do Timecop.freeze(Time.utc(2019, 1, 1, 12, 0, 0)) @@ -84,8 +97,10 @@ def expect_case_to_be_update_to_date(vacols_case, decass) end context ".create" do - let(:judge) { User.create(css_id: "CFS123", station_id: User::BOARD_STATION_ID) } - let(:attorney) { User.create(css_id: "CFS456", station_id: "317") } + let(:judge) { create(:user, :judge) } + let!(:vacols_judge) { create(:staff, :judge_role, user: judge) } + let(:attorney) { create(:user, station_id: "317") } + let!(:vacols_attorney) { create(:staff, :attorney_role, user: attorney) } let(:probability) { JudgeCaseReview::QUALITY_REVIEW_SELECTION_PROBABILITY } subject { JudgeCaseReview.complete(params) } @@ -129,7 +144,7 @@ def expect_case_to_be_update_to_date(vacols_case, decass) let!(:decass) do create(:decass, deadtim: "2013-12-06".to_date, - defolder: "123456", + defolder: vacols_case.bfkey, deprod: work_product, deatty: "102", deteam: "BB", @@ -137,9 +152,8 @@ def expect_case_to_be_update_to_date(vacols_case, decass) dedeadline: 6.days.ago) end let!(:vacols_case) { create(:case, bfkey: "123456") } - let(:vacols_issue1) { create(:case_issue, isskey: "123456") } - let(:vacols_issue2) { create(:case_issue, isskey: "123456") } - let!(:judge_staff) { create(:staff, :judge_role, slogid: "CFS456", sdomainid: judge.css_id, sattyid: "AA") } + let(:vacols_issue1) { create(:case_issue, isskey: vacols_case.bfkey) } + let(:vacols_issue2) { create(:case_issue, isskey: vacols_case.bfkey) } context "when all parameters are present to sign a decision and VACOLS update is successful" do before do @@ -173,63 +187,42 @@ def expect_case_to_be_update_to_date(vacols_case, decass) it "should create judge case review and change the location to quality review" do allow_any_instance_of(JudgeCaseReview).to receive(:rand).and_return(probability / 2) - expect(subject.valid?).to eq true expect(subject.location).to eq "quality_review" - expect(subject.complexity).to eq "hard" - expect(subject.quality).to eq "does_not_meet_expectations" - expect(subject.comment).to eq "do this" - expect(subject.factors_not_considered).to eq %w[theory_contention relevant_records] - expect(subject.areas_for_improvement).to eq ["process_violations"] - expect(subject.judge).to eq judge - expect(subject.attorney).to eq attorney - - expect(subject.appeal_type).to eq "LegacyAppeal" - expect(subject.appeal_id).to eq LegacyAppeal.find_by_vacols_id(vacols_case.bfkey).id + expect_case_review_to_match_params(subject) - expect(decass.reload.demdusr).to eq "CFS456" - expect(decass.defdiff).to eq "3" - expect(decass.deoq).to eq "1" - expect(decass.deqr2).to eq "Y" - expect(decass.deqr6).to eq "Y" - expect(decass.deqr9).to eq "Y" - expect(decass.deqr1).to eq nil - expect(decass.deqr3).to eq nil - expect(decass.deqr4).to eq nil - expect(decass.dememid).to eq "AA" - expect(decass.decomp).to eq VacolsHelper.local_date_with_utc_timezone - expect(decass.detrem).to eq "N" + expect_decass_to_be_up_to_date(decass) expect(vacols_case.reload.bfcurloc).to eq "48" - expect(vacols_case.bfmemid).to eq "AA" + expect(vacols_case.bfmemid).to eq vacols_judge.sattyid expect(vacols_case.bfattid).to eq "102" expect(vacols_case.bfboard).to eq "BB" - vacols_issues = VACOLS::CaseIssue.where(isskey: "123456") + vacols_issues = VACOLS::CaseIssue.where(isskey: vacols_case.bfkey) # 1 vacated, 1 remanded and 1 blank issue created because of vacated disposition expect(vacols_issues.size).to eq 3 vacols_issue = vacols_issues.find_by(issseq: 1) expect(vacols_issue.issdc).to eq "5" expect(vacols_issue.issseq).to eq vacols_issue1.issseq - expect(vacols_issue.issmduser).to eq "CFS456" + expect(vacols_issue.issmduser).to eq vacols_judge.slogid vacols_issue = vacols_issues.find_by(issseq: 2) expect(vacols_issue.issdc).to eq "3" expect(vacols_issue.issseq).to eq vacols_issue2.issseq - expect(vacols_issue.issmduser).to eq "CFS456" + expect(vacols_issue.issmduser).to eq vacols_judge.slogid vacols_issue = vacols_issues.find_by(issseq: 3) expect(vacols_issue.issdc).to eq nil expect(vacols_issue.issseq).to eq(vacols_issue2.issseq + 1) - expect(vacols_issue.issaduser).to eq "CFS456" + expect(vacols_issue.issaduser).to eq vacols_judge.slogid remand_reasons = VACOLS::RemandReason.where(rmdkey: "123456", rmdissseq: vacols_issue2.issseq) expect(remand_reasons.size).to eq 1 expect(remand_reasons.first.rmdissseq).to eq vacols_issue2.issseq - expect(remand_reasons.first.rmdmdusr).to eq "CFS456" + expect(remand_reasons.first.rmdmdusr).to eq vacols_judge.slogid quality_review_record = VACOLS::DecisionQualityReview.find_by(qrfolder: vacols_case.bfkey) - expect(quality_review_record.qrsmem).to eq "AA" + expect(quality_review_record.qrsmem).to eq vacols_judge.sattyid expect(quality_review_record.qrteam).to eq "BB" expect(quality_review_record.qrseldate).to eq VacolsHelper.local_date_with_utc_timezone expect(quality_review_record.qryymm).to eq "1901" @@ -250,18 +243,8 @@ def expect_case_to_be_update_to_date(vacols_case, decass) it "should create Judge Case Review" do allow_any_instance_of(JudgeCaseReview).to receive(:rand).and_return(probability + probability) - expect(subject.valid?).to eq true expect(subject.location).to eq "bva_dispatch" - expect(subject.judge).to eq judge - expect(subject.attorney).to eq attorney - expect(subject.complexity).to eq "hard" - expect(subject.quality).to eq "does_not_meet_expectations" - expect(subject.comment).to eq "do this" - expect(subject.factors_not_considered).to eq %w[theory_contention relevant_records] - expect(subject.areas_for_improvement).to eq ["process_violations"] - - expect(subject.appeal_type).to eq "LegacyAppeal" - expect(subject.appeal_id).to eq LegacyAppeal.find_by_vacols_id(vacols_case.bfkey).id + expect_case_review_to_match_params(subject) expect_decass_to_be_up_to_date(decass) @@ -269,26 +252,26 @@ def expect_case_to_be_update_to_date(vacols_case, decass) expect(vacols_case.bfcurloc).to eq "4E" expect_case_to_be_update_to_date(vacols_case, decass) - vacols_issues = VACOLS::CaseIssue.where(isskey: "123456") + vacols_issues = VACOLS::CaseIssue.where(isskey: vacols_case.bfkey) # 1 vacated, 1 remanded and 1 blank issue created because of vacated disposition expect(vacols_issues.size).to eq 3 - expect(vacols_issues.first.issdc).to eq "5" - expect(vacols_issues.first.issseq).to eq vacols_issue1.issseq - expect(vacols_issues.first.issmduser).to eq "CFS456" + vacols_issue = vacols_issues.find_by(issseq: vacols_issue1.issseq) + expect(vacols_issue.issdc).to eq "5" + expect(vacols_issue.issmduser).to eq vacols_judge.slogid - expect(vacols_issues.second.issdc).to eq "3" - expect(vacols_issues.second.issseq).to eq vacols_issue2.issseq - expect(vacols_issues.second.issmduser).to eq "CFS456" + vacols_issue = vacols_issues.find_by(issseq: vacols_issue2.issseq) + expect(vacols_issue.issdc).to eq "3" + expect(vacols_issue.issmduser).to eq vacols_judge.slogid - expect(vacols_issues.third.issdc).to eq nil - expect(vacols_issues.third.issseq).to eq(vacols_issue2.issseq + 1) - expect(vacols_issues.third.issaduser).to eq "CFS456" + vacols_issue = vacols_issues.find_by(issseq: vacols_issue2.issseq + 1) + expect(vacols_issue.issdc).to eq nil + expect(vacols_issue.issaduser).to eq vacols_judge.slogid remand_reasons = VACOLS::RemandReason.where(rmdkey: "123456", rmdissseq: vacols_issue2.issseq) expect(remand_reasons.size).to eq 1 expect(remand_reasons.first.rmdissseq).to eq vacols_issue2.issseq - expect(remand_reasons.first.rmdmdusr).to eq "CFS456" + expect(remand_reasons.first.rmdmdusr).to eq vacols_judge.slogid expect(VACOLS::DecisionQualityReview.find_by(qrfolder: vacols_case.bfkey)).to eq nil end From 2ca80920089b11bca7d8d7bbc51f02c41fd41cc5 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 13:46:06 -0400 Subject: [PATCH 286/308] Add openapi spec for pacman --- .../api/docs/pacman/idt-pacman-spec.yml | 907 ++++++++++++++++++ 1 file changed, 907 insertions(+) create mode 100644 app/controllers/api/docs/pacman/idt-pacman-spec.yml diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml new file mode 100644 index 00000000000..4bb81dad248 --- /dev/null +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -0,0 +1,907 @@ +openapi: 3.0.2 +info: + title: IDT-Caseflow-Package Manager Bridge API + description: >- + # [Caseflow Wiki Article](https://github.com/department-of-veterans-affairs/caseflow/wiki/Lighthouse-API-Implementation) + + The document outlines a number of endpoints that can be utilized within a IDT-Caseflow-Package Manager workflow. + termsOfService: https://developer.va.gov/terms-of-service + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + version: 1.0.0 +servers: +- url: https://appeals.cf.uat.ds.va.gov + description: UAT/Staging server +- url: http://localhost:3000 + description: Local Development server +paths: + /idt/api/v1/addresses/validate: + post: + tags: + - Address Validation + summary: A passthrough to the Lighthouse Address Validation API - Validates Mailing Addresses + description: >- + This route is largely a passthrough to the Lighthouse Address Validation API. In most cases, any messages Caseflow receives from its upstream source will simply be forwarded back to the requestor (IDT). + + The upstream Lighthouse Address Validation API adheres to [USPS Publication 28](https://pe.usps.com/text/pub28/welcome.htm) standards for domestic, military, and US territory address. + +

Data Definitions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataDescription
request_address.address_line_1Solely the first line of the requested address without city, state, or zip. Cannot be null if addressLine2 and addressLine3 are null.
request_address.address_line_2Solely the second line of the requested address without city, state, or zip. Cannot be null if addressLine1 and addressLine3 are null.
request_address.address_line_3Solely the third line of the requested address without city, state, or zip. Cannot be null if addressLine1 and addressLine2 are null.
request_address.cityThe name of the city of the requested address. Must only contain letters.
request_address.zip_code_5The five digit postal code of the requested address. Must only contain five digits and only used for domestic or military addresses.
request_address.zip_code_4The four digit postal code of the requested address. Must only contain four digits and only used for domestic or military addresses.
request_address.international_postal_codeThe postal code for an international address. This can contain numbers and letters and used for international addresses.
request_address.state_province.codeThe two digit code for state/province of the requested address. Must only contain two digits.
request_address.state_province.nameThe name of the state/province of the requested address.
request_address.country_nameThe name of the country of the requested address.
request_address.country_codeThe ISO2, ISO3, or FIPS country code of the requested address. Must only contain two or three letters.
request_address.address_pouShould be either RESIDENCE, CHOICE, or CORRESPONDENCE. Optional
+
+

Upstream Data Input Requirements

+ One of: +
    +
  • Address Line 1
  • +
  • Address Line 2
  • +
  • Address Line 3
  • +
+ AND: +
    +
  • country
  • +
+ + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AddressValidationRequest' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CandidateAddressResponseV2' + '400': + description: An error occurred either between IDT and Caseflow, or Caseflow and the Lighthouse API. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/LighthouseGenericError' + - $ref: '#/components/schemas/CaseflowMissingTokenError' + examples: + LighthouseGenericError: + summary: Whenever Caseflow experiences an error while communicating with the Lighthouse API. + value: + errors: + - status: 400 + title: 'An unexpected error occurred.' + message: 'An unexpected error occurred.' + CaseflowMissingTokenError: + summary: Whenever a token is not provided to the Caseflow IDT endpoint. + value: + message: Missing token + '403': + description: The token used for authorization with the Caseflow IDT API is invalid. + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: + message: Invalid token + '429': + description: Caseflow is being rate-limited by the Lighthouse API. + content: + application/json: + schema: + type: object + properties: + errors: + type: array + items: + type: object + properties: + status: + type: number + format: int32 + example: 429 + title: + type: string + example: Service is temporarily unavailable, please try again later. + detail: + type: string + example: Service is temporarily unavailable, please try again later. + '500': + description: There was an error encountered processing the request. This will mean that Caseflow ran into an issue while contacting the Lighthouse Address Validation API. + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: + message: 'Lighthouse API Error ID: 322483ae-7953-4d3c-9738-e108506d52c2 An unexpected error occurred, please try again.' + /idt/api/v1/appeals/{appeal_id}/upload_document: + post: + tags: + - Document Posting + summary: Used for uploading documents to eFolder for specific appeals/veterans + parameters: + - in: path + name: appeal_id + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/UploadDocumentRequestWithRecipientInformation' + - $ref: '#/components/schemas/UploadDocumentRequest' + examples: + "With recipient information for Package Manager": + $ref: '#/components/schemas/UploadDocumentRequestWithRecipientInformation' + "Without recipient information for Package Manager": + value: + veteran_identifier: '555555555' + document_type: 'BVA Decision' + document_subject: 'Test' + document_name: 'Test Doc' + file: 'VGhpcyBpcyBhIHRlc3QuIERvIG5vdCBiZSBhbGFybWVkLgo=' + responses: + '200': + description: 'Document was successfully placed into an S3 bucket and queued for uploading to eFolder.' + content: + application/json: + schema: + allOf: + - type: object + properties: + message: + type: string + example: "Document successfully queued for upload." + - $ref: '#/components/schemas/DistributionUUIDList' + '400': + description: 'An unknown, blank, or invalid required parameter was provided.' + content: + application/json: + schema: + oneOf: + - type: object + properties: + message: + type: string + example: "Document type is not recognized" + - type: object + properties: + message: + type: string + example: "File can't be blank" + - type: object + properties: + message: + type: string + example: "The appeal was unable to be found." + - type: object + properties: + message: + type: string + example: "The veteran was unable to be found." + '500': + description: 'A server error occurred.' + content: + application/json: + schema: + oneOf: + - type: object + properties: + message: + type: string + example: "Unexpected error: job error" + /idt/api/v1/upload_document: + post: + tags: + - Document Posting + summary: Used for uploading documents to eFolder for specific appeals/veterans + requestBody: + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/UploadDocumentRequestWithRecipientInformation' + - $ref: '#/components/schemas/UploadDocumentRequest' + examples: + "With recipient information for Package Manager": + $ref: '#/components/schemas/UploadDocumentRequestWithRecipientInformation' + "Without recipient information for Package Manager": + value: + veteran_identifier: '555555555' + document_type: 'BVA Decision' + document_subject: 'Test' + document_name: 'Test Doc' + file: 'VGhpcyBpcyBhIHRlc3QuIERvIG5vdCBiZSBhbGFybWVkLgo=' + responses: + '200': + description: 'Document was successfully placed into an S3 bucket and queued for uploading to eFolder.' + content: + application/json: + schema: + allOf: + - type: object + properties: + message: + type: string + example: "Document successfully queued for upload." + - $ref: '#/components/schemas/DistributionUUIDList' + examples: + WithRecipientInformationPresent: + summary: "With recipient information for Package Manager" + value: + message: "Document successfully queued for upload." + distribution_ids: + - "1234" + - "1235" + - "1236" + WithoutRecipientInformationPresent: + summary: "Without recipient information for Package Manager" + value: + message: "Document successfully queued for upload." + '400': + description: 'An unknown, blank, or invalid required parameter was provided.' + content: + application/json: + schema: + oneOf: + - type: object + properties: + message: + type: string + example: "Document type is not recognized" + - type: object + properties: + message: + type: string + example: "File can't be blank" + - type: object + properties: + message: + type: string + example: "The appeal was unable to be found." + - type: object + properties: + message: + type: string + example: "The veteran was unable to be found." + /idt/api/v2/appeals/{appeal_id}/outcode: + post: + tags: + - Document Posting + summary: Route used for outcoding decision reviews + parameters: + - in: path + name: appeal_id + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/OutcodeRequestWithRecipientInformation' + - $ref: '#/components/schemas/OutcodeRequest' + examples: + "With recipient information for Package Manager": + $ref: '#/components/schemas/OutcodeRequestWithRecipientInformation' + "Without recipient information for Package Manager": + value: + citation_number: "A19062122" + decision_date: "December 21, 2022" + redacted_document_location: "\\path.va.gov\\archdata$\\some-file.pdf" + file: "VGVzdGluZyAxMjMK" + responses: + '200': + description: 'Decision review has been successfully outcoded.' + content: + application/json: + schema: + allOf: + - type: object + properties: + message: + type: string + example: "Success!" + - $ref: '#/components/schemas/DistributionUUIDList' + examples: + WithRecipientInformationPresent: + summary: "With recipient information for Package Manager" + value: + message: "Success!" + distribution_ids: + - "1234" + - "1235" + - "1236" + WithoutRecipientInformationPresent: + summary: "Without recipient information for Package Manager" + value: + message: "Success!" + + '400': + description: 'Occurs if a valid decision review-BVA Dispatch Task combination cannot be located given the params provided.' + content: + application/json: + schema: + oneOf: + - type: array + items: + type: object + properties: + title: + type: string + example: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + detail: + type: string + example: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + - type: array + items: + type: object + properties: + title: + type: string + example: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + detail: + type: string + example: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + - type: array + items: + type: object + properties: + title: + type: string + example: "Citation number already exists" + detail: + type: string + example: "Citation number already exists" + examples: + AlreadyOutcodedExample: + summary: "Whenever a decision review has already been outcoded." + value: + - title: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + detail: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + IncorrectBvaDispatchTasksExample: + summary: "User has either more or fewer than 1 BvaDispatchTask assigned to them for the decision review being outcoded." + value: + - title: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + detail: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + CitationNumberExistsExample: + summary: "Citation number provided is already associated with another outcoded appeal." + value: + - title: "Citation number already exists" + detail: "Citation number already exists" + CitationNumberInvalidExample: + summary: "Thrown whenever citation number provided fails to match with a set regular expression." + value: + message: "Citation number is invalid" + MissingParamsExample: + summary: Whenever one or more required parameters are + value: + message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" + '500': + description: 'The server encountered an error.' + content: + application/json: + schema: + oneOf: + - type: array + items: + type: object + properties: + title: + type: string + example: "VBMS::FilenumberDoesNotExist" + detail: + type: string + example: "The veteran file number does not match the file number in VBMS" + /idt/api/v2/distributions/{distribution_id}: + get: + tags: + - Distribution Tracking + summary: Queries Package Manager for information on a specified distribution. + parameters: + - in: path + name: distribution_id + schema: + type: string + required: true + responses: + '200': + description: 'Distribution information has been successfully obtained.' + content: + application/json: + schema: + $ref: '#/components/schemas/DistributionStatusResponse' + examples: + DistributionIsEstablishedExample: + summary: Distribution is established + $ref: '#/components/schemas/DistributionStatusResponse' + DistributionIsPendingEstablishmentInPacManExample: + summary: Distribution is pending establishment + value: + id: 1234 + status: "PENDING_ESTABLISHMENT" + '403': + description: 'IDT token provided is invalid.' + '400': + description: 'Distribution ID provided is of an invalid format.' + '404': + description: 'A distribution could not be located given the ID provided.' + '500': + description: 'An error has occurred while trying to process the request.' + content: + application/json: + examples: + ServerError: + summary: Server Error + value: + message: 'An error has occurred while trying to process the request. Sentry ID: 02658f1e-31f1-4162-8903-63e70b81364d' + DistributionEstablishmentFailed: + summary: Distribution establishment failed + value: + id: 1234 + status: "ESTABLISHMENT_FAILED" + message: "The error message given to us by Package Manager." +components: + schemas: + DistributionUUIDList: + type: object + properties: + distribution_ids: + type: array + items: + type: string + format: number + DistributionStatusResponse: + $ref: '#/components/schemas/Distribution' + Distribution: + type: object + properties: + id: + type: integer + example: 1234 + description: The primary key of the distribution in our database. There is an initial delay while we establish \ + the distribution in Package Manager where its UUID is unavailable. This is why we utilize our primary key instead. + distribution_uuid: + type: string + format: uuid + recipient: + $ref: '#/components/schemas/DistributionRecipient' + destinations: + type: array + items: + $ref: '#/components/schemas/DistributionDestination' + status: + type: string + enum: ['IN_PROGRESS', 'SUCCESS', 'DRAFT', 'FAIL', 'ELECTRONIC_NOTIFICATION'] + sent_to_cbcm_date: + type: string + DistributionRecipient: + type: object + properties: + type: + type: string + enum: ['organization', 'person', 'system', 'ro-colocated'] + id: + type: string + format: uuid + name: + type: string + DistributionDestination: + type: object + properties: + type: + type: string + address_line_1: + type: string + address_line_2: + type: string + address_line_3: + type: string + address_line_4: + type: string + address_line_5: + type: string + address_line_6: + type: string + treat_line_2_as_addressee: + type: boolean + treat_line_3_as_addressee: + type: boolean + city: + type: string + state: + type: string + postal_code: + type: string + country_name: + type: string + country_code: + type: string + UploadDocumentRequestWithRecipientInformation: + allOf: + - $ref: '#/components/schemas/UploadDocumentRequest' + - type: object + properties: + recipient_info: + type: array + items: + type: object + $ref: '#/components/schemas/RecipientRequestInformation' + UploadDocumentRequest: + type: object + properties: + veteran_identifier: + type: string + example: '555555555' + document_type: + type: string + example: 'BVA Decision' + document_subject: + type: string + example: 'Test' + document_name: + type: string + example: 'Test Doc' + file: + type: string + format: base64 + example: 'VGhpcyBpcyBhIHRlc3QuIERvIG5vdCBiZSBhbGFybWVkLgo=' + required: + - document_type + - file + OutcodeRequestWithRecipientInformation: + allOf: + - $ref: '#/components/schemas/OutcodeRequest' + - type: object + properties: + recipient_info: + type: array + items: + type: object + $ref: '#/components/schemas/RecipientRequestInformation' + RecipientRequestInformation: + type: object + properties: + recipient_type: + type: string + enum: ['organization', 'person', 'system', 'ro-colocated'] + name: + description: 'Required if recipient_type is organization, system, or ro-colocated. Unused for people.' + type: string + first_name: + type: string + middle_name: + type: string + last_name: + type: string + claimant_station_of_jurisdiction: + type: string + description: 'Required if recipient_type is ro-colocated.' + postal_code: + type: string + description: 'Required if recipient_type is ro-colocated.' + destination_type: + type: string + enum: ['domesticAddress', 'internationalAddress', 'militaryAddress'] + address_line_1: + type: string + address_line_2: + type: string + address_line_3: + type: string + address_line_4: + type: string + address_line_5: + type: string + address_line_6: + type: string + treat_line_2_as_addressee: + type: boolean + treat_line_3_as_addressee: + type: boolean + city: + type: string + state: + type: string + country_name: + type: string + country_code: + type: string + copies: + type: integer + example: 1 + OutcodeRequest: + type: object + properties: + citation_number: + type: string + format: /\AA?\d{8}\Z/i + decision_date: + type: string + example: "December 21, 2022" + file: + type: string + format: base64 + redacted_document_location: + type: string + LighthouseGenericError: + type: object + properties: + errors: + type: array + items: + type: object + properties: + status: + type: number + format: int32 + title: + type: string + detail: + type: string + CaseflowMissingTokenError: + type: object + properties: + message: + type: string + example: Missing token + Message: + required: + - code + - key + - severity + type: object + properties: + code: + type: string + key: + type: string + text: + type: string + severity: + type: string + enum: + - INFO + - WARN + - ERROR + - FATAL + potentiallySelfCorrectingOnRetry: + type: boolean + ServiceResponse: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/Message' + AddressValidationRequest: + required: + - request_address + type: object + properties: + request_address: + $ref: '#/components/schemas/RequestAddress' + description: Request format to describe the address to correct and validate. + RequestAddress: + type: object + properties: + address_line_1: + type: string + address_line_2: + type: string + address_line_3: + type: string + city: + type: string + zip_code_5: + type: string + zip_code_4: + type: string + international_post_code: + type: string + state_province: + $ref: '#/components/schemas/StateProvince' + request_country: + $ref: '#/components/schemas/RequestCountry' + address_pou: + type: string + enum: + - RESIDENCE/CHOICE + - CORRESPONDENCE + RequestCountry: + type: object + properties: + country_code: + type: string + StateProvince: + type: object + properties: + code: + type: string + Address: + required: + - country + - county + - state_province + type: object + properties: + address_line_1: + type: string + address_line_2: + type: string + address_line_3: + type: string + city: + type: string + zip_code_5: + type: string + zip_code_4: + type: string + international_post_code: + type: string + county: + $ref: '#/components/schemas/County' + state_province: + $ref: '#/components/schemas/StateProvince' + country: + $ref: '#/components/schemas/Country' + AddressMetaData: + type: object + properties: + confidence_score: + type: number + format: double + address_type: + type: string + delivery_point_validation: + type: string + enum: + - CONFIRMED + - STREET_NUMBER_VALIDATED_BUT_MISSING_UNIT_NUMBER + - STREET_NUMBER_VALIDATED_BUT_BAD_UNIT_NUMBER + - MULTIPLE_MATCHES_FOUND + - UNDELIVERABLE + - MISSING_ZIP + - FALSE_POSITIVE + residential_delivery_indicator: + type: string + enum: + - RESIDENTIAL + - BUSINESS + - MIXED + non_postal_input_data: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + validation_key: + type: integer + format: int32 + AddressValidationResponse: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/Message' + address: + $ref: '#/components/schemas/Address' + geocode: + $ref: '#/components/schemas/Geocode' + us_congressional_district: + type: string + address_metadata: + $ref: '#/components/schemas/AddressMetaData' + CandidateAddressResponseV2: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/Message' + candidate_addresses: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/AddressValidationResponse' + Country: + type: object + properties: + name: + type: string + code: + type: string + fips_code: + type: string + iso2_code: + type: string + iso3_code: + type: string + County: + type: object + properties: + name: + type: string + county_fips_code: + type: string + Geocode: + type: object + properties: + calc_date: + type: string + format: date-time + location_precision: + type: number + format: double + latitude: + type: number + format: double + longitude: + type: number + format: double + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: TOKEN From b0281722e5f8ff1f559ff2030e48c8ca451b8069 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:26:43 -0400 Subject: [PATCH 287/308] init upload examples --- .../api/docs/pacman/idt-pacman-spec.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 4bb81dad248..63e7a227fdf 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -322,6 +322,35 @@ paths: message: type: string example: "The veteran was unable to be found." + examples: + AlreadyOutcodedExample: + summary: "Whenever a decision review has already been outcoded." + value: + - title: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + detail: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + IncorrectBvaDispatchTasksExample: + summary: "User has either more or fewer than 1 BvaDispatchTask assigned to them for the decision review being outcoded." + value: + - title: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + detail: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + CitationNumberExistsExample: + summary: "Citation number provided is already associated with another outcoded appeal." + value: + - title: "Citation number already exists" + detail: "Citation number already exists" + CitationNumberInvalidExample: + summary: "Thrown whenever citation number provided fails to match with a set regular expression." + value: + message: "Citation number is invalid" + MissingParamsExample: + summary: Whenever one or more required parameters are + value: + message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" + InvalidCopiesValid: + summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" + value: + message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." + errors: "Copies must be between 1 and 500 (inclusive)" /idt/api/v2/appeals/{appeal_id}/outcode: post: tags: @@ -436,6 +465,12 @@ paths: summary: Whenever one or more required parameters are value: message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" + InvalidCopiesValid: + summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" + value: + message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." + errors: "Copies must be between 1 and 500 (inclusive)" + '500': description: 'The server encountered an error.' content: From 9836541d3afb715284984466b78402dbe400e022 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:33:09 -0400 Subject: [PATCH 288/308] recipient type is absent --- app/controllers/api/docs/pacman/idt-pacman-spec.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 63e7a227fdf..4612d3dbd24 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -351,6 +351,13 @@ paths: value: message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." errors: "Copies must be between 1 and 500 (inclusive)" + RecipientTypeIsAbsent: + summary: 'Scenario: recipient_type is not included in the list: ["organization", "person", "system", "ro-colocated"]' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Recipient type is not included in the list" + /idt/api/v2/appeals/{appeal_id}/outcode: post: tags: From e4b942026bfe79ec018eb17e185248b501f21d3c Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:34:25 -0400 Subject: [PATCH 289/308] First name --- app/controllers/api/docs/pacman/idt-pacman-spec.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 4612d3dbd24..4d15916b6a3 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -357,6 +357,12 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Recipient type is not included in the list" + PersonRecipientMissingFirstName: + summary: 'Scenario: recipient_type is "person" and first_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "First name can't be blank" /idt/api/v2/appeals/{appeal_id}/outcode: post: From f27303b6bdbc6fb06be190d4c07c354acfd12efb Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:34:56 -0400 Subject: [PATCH 290/308] Last name --- app/controllers/api/docs/pacman/idt-pacman-spec.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 4d15916b6a3..cb4280bf682 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -363,6 +363,12 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "First name can't be blank" + PersonRecipientMissingLastName: + summary: 'Scenario: recipient_type is "person" and last_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Last name can't be blank" /idt/api/v2/appeals/{appeal_id}/outcode: post: From 5e035ce2f1cc7eb04903885d967929c974b66c6a Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:40:46 -0400 Subject: [PATCH 291/308] Treat lines as errors --- .../api/docs/pacman/idt-pacman-spec.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index cb4280bf682..6e15f18c5fd 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -369,6 +369,24 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Last name can't be blank" + TreatLine2AsAddresseeTrueMissingAddressLine2: + summary: 'Scenario: treat_line_2_as_addressee is true and address_line_2 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 2 can't be blank" + TreatLine3AsAddresseeTrueMissingAddressLine3: + summary: 'Scenario: treat_line_3_as_addressee is true and address_line_3 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Treat line 2 as addressee cannot be false if line 3 is treated as addressee" + TreatLine3AsAddresseeDependentValueMissing: + summary: 'Scenario: treat_line_3_as_addressee is true and treat_line_2_as_addressee is false' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 3 can't be blank" /idt/api/v2/appeals/{appeal_id}/outcode: post: From b3a51425bc233461b92d2898767bfef3de887537 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:49:36 -0400 Subject: [PATCH 292/308] addresses --- .../api/docs/pacman/idt-pacman-spec.yml | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 6e15f18c5fd..c3c510e78f2 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -369,6 +369,48 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Last name can't be blank" + CityIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and city is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "City can't be blank" + CountryCodeIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code can't be blank, Country code is not a valid ISO 3166-2 code" + ProvidedCountryCodeIsInvalid: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsNonBlankState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State can't be blank, State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsValidState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsPostalCode: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and postal_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Postal code can't be blank" + InternationalAddressNeedsCountryName: + summary: 'Scenario: destination_type is "internationalAddress" and country_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country name can't be blank" TreatLine2AsAddresseeTrueMissingAddressLine2: summary: 'Scenario: treat_line_2_as_addressee is true and address_line_2 is blank' value: From 36010b01131aba01114305b040cf3986764bb4ac Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:51:29 -0400 Subject: [PATCH 293/308] Add to other upload --- .../api/docs/pacman/idt-pacman-spec.yml | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index c3c510e78f2..ed1d677b699 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -549,6 +549,84 @@ paths: value: message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." errors: "Copies must be between 1 and 500 (inclusive)" + RecipientTypeIsAbsent: + summary: 'Scenario: recipient_type is not included in the list: ["organization", "person", "system", "ro-colocated"]' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Recipient type is not included in the list" + PersonRecipientMissingFirstName: + summary: 'Scenario: recipient_type is "person" and first_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "First name can't be blank" + PersonRecipientMissingLastName: + summary: 'Scenario: recipient_type is "person" and last_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Last name can't be blank" + CityIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and city is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "City can't be blank" + CountryCodeIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code can't be blank, Country code is not a valid ISO 3166-2 code" + ProvidedCountryCodeIsInvalid: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsNonBlankState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State can't be blank, State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsValidState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsPostalCode: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and postal_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Postal code can't be blank" + InternationalAddressNeedsCountryName: + summary: 'Scenario: destination_type is "internationalAddress" and country_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country name can't be blank" + TreatLine2AsAddresseeTrueMissingAddressLine2: + summary: 'Scenario: treat_line_2_as_addressee is true and address_line_2 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 2 can't be blank" + TreatLine3AsAddresseeTrueMissingAddressLine3: + summary: 'Scenario: treat_line_3_as_addressee is true and address_line_3 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Treat line 2 as addressee cannot be false if line 3 is treated as addressee" + TreatLine3AsAddresseeDependentValueMissing: + summary: 'Scenario: treat_line_3_as_addressee is true and treat_line_2_as_addressee is false' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 3 can't be blank" '500': description: 'The server encountered an error.' From 36865ff5fad61f52b7ad26cb7514477546e894d6 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 16:53:22 -0400 Subject: [PATCH 294/308] Other upload --- .../api/docs/pacman/idt-pacman-spec.yml | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index ed1d677b699..1b50548ac7d 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -237,6 +237,115 @@ paths: message: type: string example: "The veteran was unable to be found." + examples: + AlreadyOutcodedExample: + summary: "Whenever a decision review has already been outcoded." + value: + - title: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + detail: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" + IncorrectBvaDispatchTasksExample: + summary: "User has either more or fewer than 1 BvaDispatchTask assigned to them for the decision review being outcoded." + value: + - title: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + detail: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" + CitationNumberExistsExample: + summary: "Citation number provided is already associated with another outcoded appeal." + value: + - title: "Citation number already exists" + detail: "Citation number already exists" + CitationNumberInvalidExample: + summary: "Thrown whenever citation number provided fails to match with a set regular expression." + value: + message: "Citation number is invalid" + MissingParamsExample: + summary: Whenever one or more required parameters are + value: + message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" + InvalidCopiesValid: + summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" + value: + message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." + errors: "Copies must be between 1 and 500 (inclusive)" + RecipientTypeIsAbsent: + summary: 'Scenario: recipient_type is not included in the list: ["organization", "person", "system", "ro-colocated"]' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Recipient type is not included in the list" + PersonRecipientMissingFirstName: + summary: 'Scenario: recipient_type is "person" and first_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "First name can't be blank" + PersonRecipientMissingLastName: + summary: 'Scenario: recipient_type is "person" and last_name is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Last name can't be blank" + CityIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and city is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "City can't be blank" + CountryCodeIsMissing: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code can't be blank, Country code is not a valid ISO 3166-2 code" + ProvidedCountryCodeIsInvalid: + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and county_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country code is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsNonBlankState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State can't be blank, State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsValidState: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and state_code is not a valid ISO 3166-code' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "State is not a valid ISO 3166-2 code" + DomesticOrMilitaryNeedsPostalCode: + summary: 'Scenario: destination_type is "domesticAddress" or "militaryAddress" and postal_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Postal code can't be blank" + InternationalAddressNeedsCountryName: + summary: 'Scenario: destination_type is "internationalAddress" and country_code is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Country name can't be blank" + TreatLine2AsAddresseeTrueMissingAddressLine2: + summary: 'Scenario: treat_line_2_as_addressee is true and address_line_2 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 2 can't be blank" + TreatLine3AsAddresseeTrueMissingAddressLine3: + summary: 'Scenario: treat_line_3_as_addressee is true and address_line_3 is blank' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Treat line 2 as addressee cannot be false if line 3 is treated as addressee" + TreatLine3AsAddresseeDependentValueMissing: + summary: 'Scenario: treat_line_3_as_addressee is true and treat_line_2_as_addressee is false' + value: + message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Address line 3 can't be blank" + + '500': description: 'A server error occurred.' content: From 8e36f8a742245d33a673cfad9c6eea796641d739 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 11 Jul 2023 16:54:17 -0400 Subject: [PATCH 295/308] half of error scenarios --- .../api/docs/pacman/idt-pacman-spec.yml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 4612d3dbd24..31bd55ff9a9 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -357,6 +357,36 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Recipient type is not included in the list" + NameBlank: + summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + value: + message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Name can't be blank" + PoaCodeBlank: + summary: 'recipient_type is "ro-colocated" and poa_code is blank' + value: + message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Poa code can't be blank" + ClaimantStationOfJurisdictionBlank: + summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + value: + message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Claimant station of jurisdiction can't be blank" + DestinationTypeInvalid: + summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + value: + message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." + errors": + "distribution 1": "Destination type is not included in the list" + AddressLine1Blank: + summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + value: + message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." + "errors": + "distribution 1": "Address line 1 can't be blank" /idt/api/v2/appeals/{appeal_id}/outcode: post: From ed3b207b06597beccee2fcf2fc99eb11c6effea7 Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 11 Jul 2023 16:58:10 -0400 Subject: [PATCH 296/308] Added routes to outcode --- .../api/docs/pacman/idt-pacman-spec.yml | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 188fbf50d24..f096d9c98e0 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -346,7 +346,7 @@ paths: summary: Whenever one or more required parameters are value: message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" - InvalidCopiesValid: + InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." @@ -574,7 +574,7 @@ paths: summary: Whenever one or more required parameters are value: message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" - InvalidCopiesValid: + InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." @@ -585,6 +585,36 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Recipient type is not included in the list" + NameBlank: + summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + value: + message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Name can't be blank" + PoaCodeBlank: + summary: 'recipient_type is "ro-colocated" and poa_code is blank' + value: + message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Poa code can't be blank" + ClaimantStationOfJurisdictionBlank: + summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + value: + message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Claimant station of jurisdiction can't be blank" + DestinationTypeInvalid: + summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + value: + message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." + errors": + "distribution 1": "Destination type is not included in the list" + AddressLine1Blank: + summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + value: + message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." + "errors": + "distribution 1": "Address line 1 can't be blank" PersonRecipientMissingFirstName: summary: 'Scenario: recipient_type is "person" and first_name is blank' value: @@ -657,7 +687,6 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Address line 3 can't be blank" - '500': description: 'The server encountered an error.' content: From add8a3f5d58219ec037bf4c9fe9c4982f3187a0d Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Tue, 11 Jul 2023 17:01:15 -0400 Subject: [PATCH 297/308] error cleanup --- .../api/docs/pacman/idt-pacman-spec.yml | 80 +++++++------------ 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 9bd2c957a00..67476334684 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -238,30 +238,7 @@ paths: type: string example: "The veteran was unable to be found." examples: - AlreadyOutcodedExample: - summary: "Whenever a decision review has already been outcoded." - value: - - title: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" - detail: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" - IncorrectBvaDispatchTasksExample: - summary: "User has either more or fewer than 1 BvaDispatchTask assigned to them for the decision review being outcoded." - value: - - title: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" - detail: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" - CitationNumberExistsExample: - summary: "Citation number provided is already associated with another outcoded appeal." - value: - - title: "Citation number already exists" - detail: "Citation number already exists" - CitationNumberInvalidExample: - summary: "Thrown whenever citation number provided fails to match with a set regular expression." - value: - message: "Citation number is invalid" - MissingParamsExample: - summary: Whenever one or more required parameters are - value: - message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" - InvalidCopiesValid: + InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: message: "IDT Exception ID: 67ce1137-4d94-43ec-ba0a-1daf43fc6a65 Recipient information received was invalid or incomplete." @@ -272,6 +249,36 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Recipient type is not included in the list" + NameBlank: + summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + value: + message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Name can't be blank" + PoaCodeBlank: + summary: 'recipient_type is "ro-colocated" and poa_code is blank' + value: + message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Poa code can't be blank" + ClaimantStationOfJurisdictionBlank: + summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + value: + message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." + errors: + "distribution 1": "Claimant station of jurisdiction can't be blank" + DestinationTypeInvalid: + summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + value: + message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." + errors": + "distribution 1": "Destination type is not included in the list" + AddressLine1Blank: + summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + value: + message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." + "errors": + "distribution 1": "Address line 1 can't be blank" PersonRecipientMissingFirstName: summary: 'Scenario: recipient_type is "person" and first_name is blank' value: @@ -344,8 +351,6 @@ paths: message: "IDT Exception ID: 2b26f07f-b742-4056-8781-be2a8ccb5d35 Recipient information received was invalid or incomplete." errors: "distribution 1": "Address line 3 can't be blank" - - '500': description: 'A server error occurred.' content: @@ -432,29 +437,6 @@ paths: type: string example: "The veteran was unable to be found." examples: - AlreadyOutcodedExample: - summary: "Whenever a decision review has already been outcoded." - value: - - title: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" - detail: "Appeal 12345, task ID 54321 has already been outcoded. Cannot outcode the same appeal and task combination more than once" - IncorrectBvaDispatchTasksExample: - summary: "User has either more or fewer than 1 BvaDispatchTask assigned to them for the decision review being outcoded." - value: - - title: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" - detail: "Expected 1 BvaDispatchTask received 0 tasks for appeal 12345, user 1" - CitationNumberExistsExample: - summary: "Citation number provided is already associated with another outcoded appeal." - value: - - title: "Citation number already exists" - detail: "Citation number already exists" - CitationNumberInvalidExample: - summary: "Thrown whenever citation number provided fails to match with a set regular expression." - value: - message: "Citation number is invalid" - MissingParamsExample: - summary: Whenever one or more required parameters are - value: - message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: From 6675237bcf46b3d198376775d30de6bbca356bf7 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 17:26:34 -0400 Subject: [PATCH 298/308] Tweaks --- .../api/docs/pacman/idt-pacman-spec.yml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index 67476334684..d8d60ed22f3 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -250,31 +250,31 @@ paths: errors: "distribution 1": "Recipient type is not included in the list" NameBlank: - summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + summary: 'Scenario: recipient_type is "system", "organization", or "ro-colocated" and name is blank' value: message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." errors: "distribution 1": "Name can't be blank" PoaCodeBlank: - summary: 'recipient_type is "ro-colocated" and poa_code is blank' + summary: 'Scenario: recipient_type is "ro-colocated" and poa_code is blank' value: message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." errors: "distribution 1": "Poa code can't be blank" ClaimantStationOfJurisdictionBlank: - summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + summary: 'Scenario: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank' value: message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." errors: "distribution 1": "Claimant station of jurisdiction can't be blank" DestinationTypeInvalid: - summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + summary: 'Scenario: destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' value: message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." errors": "distribution 1": "Destination type is not included in the list" AddressLine1Blank: - summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank"' value: message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." "errors": @@ -449,31 +449,31 @@ paths: errors: "distribution 1": "Recipient type is not included in the list" NameBlank: - summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + summary: 'Scenario: recipient_type is "system", "organization", or "ro-colocated" and name is blank' value: message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." errors: "distribution 1": "Name can't be blank" PoaCodeBlank: - summary: 'recipient_type is "ro-colocated" and poa_code is blank' + summary: 'Scenario: recipient_type is "ro-colocated" and poa_code is blank' value: message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." errors: "distribution 1": "Poa code can't be blank" ClaimantStationOfJurisdictionBlank: - summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + summary: 'Scenario: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank' value: message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." errors: "distribution 1": "Claimant station of jurisdiction can't be blank" DestinationTypeInvalid: - summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + summary: 'Scenario: destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' value: message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." errors": "distribution 1": "Destination type is not included in the list" AddressLine1Blank: - summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank"' value: message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." "errors": @@ -662,7 +662,7 @@ paths: value: message: "Citation number is invalid" MissingParamsExample: - summary: Whenever one or more required parameters are + summary: Whenever one or more required parameters are absent. value: message: "Decision date can't be blank, Redacted document location can't be blank, File can't be blank" InvalidCopiesValue: @@ -677,31 +677,31 @@ paths: errors: "distribution 1": "Recipient type is not included in the list" NameBlank: - summary: 'recipient_type is "system", "organization", or "ro-colocated" and name is blank' + summary: 'Scenario: recipient_type is "system", "organization", or "ro-colocated" and name is blank' value: message: "IDT Exception ID: d8cecfbd-c664-440e-919b-bb1d91e77f1d Recipient information received was invalid or incomplete." errors: "distribution 1": "Name can't be blank" PoaCodeBlank: - summary: 'recipient_type is "ro-colocated" and poa_code is blank' + summary: 'Scenario: recipient_type is "ro-colocated" and poa_code is blank' value: message: "IDT Exception ID: 8af4913f-1e96-4437-9294-0c31b0f545df Recipient information received was invalid or incomplete." errors: "distribution 1": "Poa code can't be blank" ClaimantStationOfJurisdictionBlank: - summary: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank + summary: 'Scenario: recipient_type is "ro-colocated" and claimant_station_of_jurisdiction is blank' value: message: "IDT Exception ID: cf9e0208-e5de-4fb6-9dd5-2e182acdb8c3 Recipient information received was invalid or incomplete." errors: "distribution 1": "Claimant station of jurisdiction can't be blank" DestinationTypeInvalid: - summary: 'destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' + summary: 'Scenario: destination_type is not included in the list: ["domesticAddress", "internationalAddress", "militaryAddress", "derived"]' value: message: "IDT Exception ID: d7d581fa-4e31-445c-a513-ff40c49a3b95 Recipient information received was invalid or incomplete." errors": "distribution 1": "Destination type is not included in the list" AddressLine1Blank: - summary: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank" + summary: 'Scenario: destination_type is "domesticAddress", "internationalAddress", or "militaryAddress" and address_line_1 is blank"' value: message: "IDT Exception ID: 578abf44-0292-49b6-a77f-27878d734145 Recipient information received was invalid or incomplete." "errors": From 551ced7a124cd07f2be7ac5ef99146ad99ced925 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 22:49:30 -0400 Subject: [PATCH 299/308] --- app/jobs/ama_notification_efolder_sync_job.rb | 2 +- app/jobs/legacy_notification_efolder_sync_job.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/ama_notification_efolder_sync_job.rb b/app/jobs/ama_notification_efolder_sync_job.rb index 99813809bc2..27ec96b7da7 100644 --- a/app/jobs/ama_notification_efolder_sync_job.rb +++ b/app/jobs/ama_notification_efolder_sync_job.rb @@ -17,7 +17,7 @@ def perform all_active_ama_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync - sync_notification_reports(all_active_ama_appeals.first(BATCH_LIMIT.to_i)) + sync_notification_reports(all_active_ama_appeals.uniq.first(BATCH_LIMIT.to_i)) end private diff --git a/app/jobs/legacy_notification_efolder_sync_job.rb b/app/jobs/legacy_notification_efolder_sync_job.rb index d37847a8dbc..a833af6c477 100644 --- a/app/jobs/legacy_notification_efolder_sync_job.rb +++ b/app/jobs/legacy_notification_efolder_sync_job.rb @@ -17,7 +17,7 @@ def perform all_active_legacy_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync - sync_notification_reports(all_active_legacy_appeals.first(BATCH_LIMIT.to_i)) + sync_notification_reports(all_active_legacy_appeals.uniq.first(BATCH_LIMIT.to_i)) end private From 42cabe276cd6b67fc75d093e572cfb7d1b2dc175 Mon Sep 17 00:00:00 2001 From: Prajwal Amatya <122557351+pamatyatake2@users.noreply.github.com> Date: Wed, 12 Jul 2023 07:21:10 -0600 Subject: [PATCH 300/308] removing flake test (#18982) * removing flake test * removing commented code * removing typo and nocov * removing commented code --- spec/factories/vacols/case.rb | 13 +++++++++ spec/feature/dispatch/establish_claim_spec.rb | 29 +++++++++---------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/spec/factories/vacols/case.rb b/spec/factories/vacols/case.rb index 101e71ad02b..9fc01dfe2b5 100644 --- a/spec/factories/vacols/case.rb +++ b/spec/factories/vacols/case.rb @@ -175,6 +175,19 @@ end end + factory :case_with_multi_decision do + bfddec { 1.day.ago } + + transient do + decision_document do + [ + create(:document, type: "BVA Decision", received_at: 1.day.ago), + create(:document, type: "BVA Decision", received_at: 1.day.ago) + ] + end + end + end + factory :case_with_old_decision do bfddec { 1.day.ago } diff --git a/spec/feature/dispatch/establish_claim_spec.rb b/spec/feature/dispatch/establish_claim_spec.rb index 085afb747a5..15442585c9a 100644 --- a/spec/feature/dispatch/establish_claim_spec.rb +++ b/spec/feature/dispatch/establish_claim_spec.rb @@ -27,7 +27,7 @@ let(:folder) { build(:folder, tioctime: 23.days.ago.midnight) } let(:case_remand) do - create(:case_with_decision, :status_remand, folder: folder) + create(:case_with_multi_decision, :status_remand, folder: folder) end let(:appeal_remand) do @@ -491,9 +491,8 @@ Generators::Document.build(type: "BVA Decision", received_at: 6.days.ago) ] end - # :nocov: - scenario "Review page lets users choose which document to use", - skip: "This test is failing because of a stale element reference" do + + scenario "Review page lets users choose which document to use" do visit "/dispatch/establish-claim" click_on "Establish next claim" @@ -508,8 +507,7 @@ expect(page).to have_content("Benefit Type") end - scenario "the EP creation page has a link back to decision review", - skip: "This test is failing because of a stale element reference" do + scenario "the EP creation page has a link back to decision review" do visit "/dispatch/establish-claim" click_on "Establish next claim" @@ -518,7 +516,6 @@ click_on "< Back to Review Decision" expect(page).to have_content("Multiple Decision Documents") end - # :nocov: end context "For a full grant" do @@ -629,10 +626,11 @@ scenario "Assigning it to complete the claims establishment", skip: "flakey hang" do visit "/dispatch/establish-claim" click_on "Establish next claim" - expect(page).to have_current_path("/dispatch/establish-claim/#{task.id}") click_on "Route claim" expect(page).to have_current_path("/dispatch/establish-claim/#{task.id}") + expect(page).to have_content("Route Claim") + expect(page).to have_selector(:link_or_button, "Assign to Claim") click_on "Assign to Claim" # unknown reason sometimes hangs here expect(page).to have_content("Success!") @@ -652,8 +650,7 @@ aasm_state: "unassigned") end - scenario "Establish a new claim routed to ARC", - skip: "This test is failing because of a stale element reference" do + scenario "Establish a new claim routed to ARC", :aggregate_failure do # Mock the claim_id returned by VBMS's create end product Fakes::VBMSService.end_product_claim_id = "CLAIM_ID_123" @@ -700,9 +697,11 @@ suppress_acknowledgement_letter: true, claimant_participant_id: nil, limited_poa_code: nil, - limited_poa_access: nil + limited_poa_access: nil, + status_type_code: nil }, - veteran_hash: task.appeal.veteran.to_vbms_hash + veteran_hash: task.appeal.veteran.to_vbms_hash, + user: RequestStore[:current_user] ) expect(AppealRepository).to have_received(:update_vacols_after_dispatch!) @@ -713,11 +712,11 @@ expect(task.appeal.reload.dispatched_to_station).to eq("397") - click_on "Caseflow Dispatch" - expect(page).to have_current_path("/dispatch/establish-claim") + expect(page).to have_current_path("/dispatch/establish-claim/#{task.id}") # No tasks left - expect(page).to have_content("Way to go! You have completed all the claims assigned to you.") + expect(page).to have_content("Way to go!") + expect(page).to have_content("You have completed all of the total cases assigned to you today") expect(page).to have_css(".usa-button-disabled") end From 257a0a1560d28986bc6ff0f369efb1ff9598f23b Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Wed, 12 Jul 2023 12:38:34 -0400 Subject: [PATCH 301/308] Ensured original responses show in dropdown for swagger ui --- .../api/docs/pacman/idt-pacman-spec.yml | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/app/controllers/api/docs/pacman/idt-pacman-spec.yml b/app/controllers/api/docs/pacman/idt-pacman-spec.yml index d8d60ed22f3..0d094879c00 100644 --- a/app/controllers/api/docs/pacman/idt-pacman-spec.yml +++ b/app/controllers/api/docs/pacman/idt-pacman-spec.yml @@ -238,6 +238,22 @@ paths: type: string example: "The veteran was unable to be found." examples: + DocumentTypeNotRecognized: + summary: Document type not recognized + value: + message: Document type is not recognized + FileBlank: + summary: File is blank + value: + message: File can't be blank + AppealNotFound: + summary: Appeal does not exist + value: + message: The appeal was unable to be found. + VeteranNotFound: + summary: Veteran does not exist + value: + message: The veteran was unable to be found. InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: @@ -437,6 +453,22 @@ paths: type: string example: "The veteran was unable to be found." examples: + DocumentTypeNotRecognized: + summary: Document type not recognized + value: + message: Document type is not recognized + FileBlank: + summary: File is blank + value: + message: File can't be blank + AppealNotFound: + summary: Appeal does not exist + value: + message: The appeal was unable to be found. + VeteranNotFound: + summary: Veteran does not exist + value: + message: The veteran was unable to be found. InvalidCopiesValue: summary: "Scenario: Copies out of range (1-500 inclusive, default value of 1)" value: From 2e5abadc6fb9edf1fd36f9110e4a34ef079cd47c Mon Sep 17 00:00:00 2001 From: Brandon Dorner Date: Wed, 12 Jul 2023 12:24:55 -0500 Subject: [PATCH 302/308] Fix spelling error VLJs are reporting that their Unassigned tabs are misspelled as "Unassgined" --- client/app/queue/QueueApp.jsx | 2 +- client/app/queue/constants.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/app/queue/QueueApp.jsx b/client/app/queue/QueueApp.jsx index f78d4574909..f1b6d83a52c 100644 --- a/client/app/queue/QueueApp.jsx +++ b/client/app/queue/QueueApp.jsx @@ -719,7 +719,7 @@ class QueueApp extends React.PureComponent { /> diff --git a/client/app/queue/constants.js b/client/app/queue/constants.js index 7fa63f479e9..f02c465abb3 100644 --- a/client/app/queue/constants.js +++ b/client/app/queue/constants.js @@ -179,7 +179,7 @@ export const PAGE_TITLES = { ATTORNEY: 'Select Remand Reasons' }, REVIEW_CASES: 'Review Cases', - UNASSIGED_CASES: 'Unassgined Cases', + UNASSIGNED_CASES: 'Unassigned Cases', CASE_DETAILS: 'Case Details', DRAFT_DECISION: 'Draft Decision', EVALUATE_DECISION: 'Evaluate Decision', From 29e3405aec406757f2a86d87abed737b996d3a96 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 12 Jul 2023 14:17:34 -0400 Subject: [PATCH 303/308] Reinstate MTV changes --- app/views/queue/index.html.erb | 3 +- client/COPY.json | 6 + .../queue/mtv/AddressMotionToVacateView.jsx | 4 + client/app/queue/mtv/MTVJudgeDisposition.jsx | 44 +- client/constants/MOTION_TO_VACATE.json | 8 + .../app/queue/mtv/MTVJudgeDisposition.test.js | 334 +++++++++++++- .../MTVJudgeDisposition.test.js.snap | 407 ++++++++++++++---- scripts/enable_features_dev.rb | 11 +- spec/feature/queue/motion_to_vacate_spec.rb | 1 + spec/support/queue_helpers.rb | 32 +- 10 files changed, 727 insertions(+), 123 deletions(-) diff --git a/app/views/queue/index.html.erb b/app/views/queue/index.html.erb index 88b5f34ca42..e0ba7a1038a 100644 --- a/app/views/queue/index.html.erb +++ b/app/views/queue/index.html.erb @@ -52,7 +52,8 @@ split_appeal_workflow: FeatureToggle.enabled?(:split_appeal_workflow, user: current_user), cavc_remand_granted_substitute_appellant: FeatureToggle.enabled?(:cavc_remand_granted_substitute_appellant, user: current_user), cavc_dashboard_workflow: FeatureToggle.enabled?(:cavc_dashboard_workflow, user: current_user), - cc_appeal_workflow: FeatureToggle.enabled?(:cc_appeal_workflow, user: current_user) + cc_appeal_workflow: FeatureToggle.enabled?(:cc_appeal_workflow, user: current_user), + cc_vacatur_visibility: FeatureToggle.enabled?(:cc_vacatur_visibility, user: current_user) } }) %> <% end %> diff --git a/client/COPY.json b/client/COPY.json index dafc32b9699..9bd85705be1 100644 --- a/client/COPY.json +++ b/client/COPY.json @@ -386,6 +386,12 @@ "MTV_CHECKOUT_RETURN_TO_JUDGE_MODAL_INSTRUCTIONS_LABEL": "Provide instructions and context for this action", "MTV_CHECKOUT_RETURN_TO_JUDGE_SUCCESS_TITLE": "%s's Motion to Vacate has been returned to %s", "MTV_CHECKOUT_RETURN_TO_JUDGE_SUCCESS_DETAILS": "If you made a mistake, please email your judge to resolve the issue.", + + "MTV_TASK_INSTRUCTIONS": "**Motion To Vacate:** \n", + "MTV_TASK_INSTRUCTIONS_TYPE": "**Type:** ", + "MTV_TASK_INSTRUCTIONS_DETAIL": "**Detail:** ", + "MTV_TASK_INSTRUCTIONS_HYPERLINK": "**Hyperlink:** ", + "VACATE_AND_DE_NOVO_TASK_LABEL": "Vacate and De Novo", "VACATE_AND_READJUDICATION_TASK_LABEL": "Vacate and Readjudication", "STRAIGHT_VACATE_TASK_LABEL": "Straight Vacate", diff --git a/client/app/queue/mtv/AddressMotionToVacateView.jsx b/client/app/queue/mtv/AddressMotionToVacateView.jsx index 825fd14c2d5..8cf14c6e30a 100644 --- a/client/app/queue/mtv/AddressMotionToVacateView.jsx +++ b/client/app/queue/mtv/AddressMotionToVacateView.jsx @@ -18,6 +18,9 @@ export const AddressMotionToVacateView = () => { const task = useSelector((state) => taskById(state, { taskId })); const appeal = useSelector((state) => appealWithDetailSelector(state, { appealId })); + const vacateTypeFeatureToggle = useSelector( + (state) => state.ui.featureToggles.cc_vacatur_visibility + ); const { selected, options } = taskActionData({ task, match }); @@ -42,6 +45,7 @@ export const AddressMotionToVacateView = () => { task={task} attorneys={attyOptions} selectedAttorney={selected} + vacateTypeFeatureToggle = {vacateTypeFeatureToggle} appeal={appeal} onSubmit={handleSubmit} returnToLitSupportLink={`${match.url}/${JUDGE_RETURN_TO_LIT_SUPPORT.value}`} diff --git a/client/app/queue/mtv/MTVJudgeDisposition.jsx b/client/app/queue/mtv/MTVJudgeDisposition.jsx index eddde279cc9..ec89ec4d81a 100644 --- a/client/app/queue/mtv/MTVJudgeDisposition.jsx +++ b/client/app/queue/mtv/MTVJudgeDisposition.jsx @@ -13,9 +13,13 @@ import { JUDGE_ADDRESS_MTV_VACATE_TYPE_LABEL, JUDGE_ADDRESS_MTV_HYPERLINK_LABEL, JUDGE_ADDRESS_MTV_DISPOSITION_NOTES_LABEL, - JUDGE_ADDRESS_MTV_ASSIGN_ATTORNEY_LABEL + JUDGE_ADDRESS_MTV_ASSIGN_ATTORNEY_LABEL, + MTV_TASK_INSTRUCTIONS, + MTV_TASK_INSTRUCTIONS_TYPE, + MTV_TASK_INSTRUCTIONS_DETAIL, + MTV_TASK_INSTRUCTIONS_HYPERLINK } from '../../../COPY'; -import { DISPOSITION_TEXT, VACATE_TYPE_OPTIONS } from '../../../constants/MOTION_TO_VACATE'; +import { DISPOSITION_TIMELINE_TEXT, VACATE_TYPE_OPTIONS } from '../../../constants/MOTION_TO_VACATE'; import { JUDGE_RETURN_TO_LIT_SUPPORT } from '../../../constants/TASK_ACTIONS'; import SearchableDropdown from '../../components/SearchableDropdown'; import AppSegment from '@department-of-veterans-affairs/caseflow-frontend-toolkit/components/AppSegment'; @@ -28,6 +32,7 @@ import StringUtil from '../../util/StringUtil'; import { ReturnToLitSupportAlert } from './ReturnToLitSupportAlert'; import { grantTypes, dispositionStrings } from './mtvConstants'; import { sprintf } from 'sprintf-js'; +import { isEmpty } from 'lodash'; const vacateTypeText = (val) => { const opt = VACATE_TYPE_OPTIONS.find((i) => i.value === val); @@ -35,19 +40,33 @@ const vacateTypeText = (val) => { return opt && opt.displayText; }; -const formatInstructions = ({ disposition, vacateType, hyperlink, instructions }) => { - const parts = [`I am proceeding with a ${DISPOSITION_TEXT[disposition]}.`]; +const formatInstructions = ({ vacateTypeFeatureToggle, disposition, vacateType, hyperlink, instructions }) => { + const parts = [`${MTV_TASK_INSTRUCTIONS}${DISPOSITION_TIMELINE_TEXT[disposition]}\n`]; switch (disposition) { case 'granted': case 'partially_granted': - parts.push(`This will be a ${vacateTypeText(vacateType)}`); - parts.push(instructions); + if (!vacateTypeFeatureToggle) { + parts.push(MTV_TASK_INSTRUCTIONS_TYPE); + parts.push(`${vacateTypeText(vacateType)}\n`); + + } + if (isEmpty(instructions) === false) { + parts.push(MTV_TASK_INSTRUCTIONS_DETAIL); + parts.push(`${instructions}\n`); + } break; + case 'denied': + case 'dismissed': default: - parts.push(instructions); - parts.push('\nHere is the hyperlink to the signed denial document'); - parts.push(hyperlink); + if (isEmpty(instructions) === false) { + parts.push(MTV_TASK_INSTRUCTIONS_DETAIL); + parts.push(`${instructions}\n`); + } + if (hyperlink !== null) { + parts.push(MTV_TASK_INSTRUCTIONS_HYPERLINK); + parts.push(`${hyperlink}\n`); + } break; } @@ -62,10 +81,12 @@ const styles = { }; export const MTVJudgeDisposition = ({ + attorneys, selectedAttorney, task, appeal, + vacateTypeFeatureToggle, onSubmit = () => null, submitting = false, returnToLitSupportLink = JUDGE_RETURN_TO_LIT_SUPPORT.value @@ -81,6 +102,7 @@ export const MTVJudgeDisposition = ({ const handleSubmit = () => { const formattedInstructions = formatInstructions({ + vacateTypeFeatureToggle, disposition, vacateType, hyperlink, @@ -180,7 +202,8 @@ export const MTVJudgeDisposition = ({ setInstructions(val)} value={instructions} className={['mtv-decision-instructions']} @@ -227,6 +250,7 @@ MTVJudgeDisposition.propTypes = { onSubmit: PropTypes.func.isRequired, submitting: PropTypes.bool, task: PropTypes.object.isRequired, + vacateTypeFeatureToggle: PropTypes.bool, appeal: PropTypes.object.isRequired, attorneys: PropTypes.array.isRequired, selectedAttorney: PropTypes.object, diff --git a/client/constants/MOTION_TO_VACATE.json b/client/constants/MOTION_TO_VACATE.json index eb7d4c76893..e5b1d8e44c0 100644 --- a/client/constants/MOTION_TO_VACATE.json +++ b/client/constants/MOTION_TO_VACATE.json @@ -39,6 +39,14 @@ "denied": "denial of all issues for vacatur", "dismissed": "dismissal" }, + + "DISPOSITION_TIMELINE_TEXT": { + "granted": "Full vacatur", + "partially_granted": "Partial vacatur", + "denied": "Deny all issues for vacatur", + "dismissed": "Dismiss all issues for vacatur" + }, + "DISPOSITION_RECOMMENDATIONS": { "granted": "I recommend granting a vacatur.", "partially_granted": "I recommend granting a partial vacatur.", diff --git a/client/test/app/queue/mtv/MTVJudgeDisposition.test.js b/client/test/app/queue/mtv/MTVJudgeDisposition.test.js index 42025286c26..306965c3da0 100644 --- a/client/test/app/queue/mtv/MTVJudgeDisposition.test.js +++ b/client/test/app/queue/mtv/MTVJudgeDisposition.test.js @@ -15,40 +15,99 @@ const task = generateAmaTask({ type: 'VacateMotionMailTask', instructions: ['Lorem ipsum dolor sit amet, consectetur adipiscing'], }); +let linkField = /Insert Caseflow Reader document hyperlink to/; +let instructionsField = /Provide context and instructions on which issues should be/; + +const selectRadioField = (radioSelection) => { + const radioFieldToSelect = screen.getByLabelText(radioSelection); + + userEvent.click(radioFieldToSelect); +}; + +const enterAdditionalContext = (text, selectedField) => { + const textField = screen.getByText(selectedField); + + userEvent.type(textField, text); +}; + +const selectDisposition = async (disposition = 'grant all') => { + userEvent.click( + screen.getByLabelText(new RegExp(disposition, 'i')) + ); + + if ((/grant/i).test(disposition)) { + await waitFor(() => { + expect( + screen.getByText(/what type of vacate/i) + ).toBeInTheDocument(); + }); + } else { + await waitFor(() => { + expect( + screen.getByLabelText(/insert caseflow reader document hyperlink/i) + ).toBeInTheDocument(); + }); + } +}; + +const fillForm = async (disposition, vacateType, vacateIssues, hyperlink, instructions) => { + userEvent.click( + screen.getByLabelText(new RegExp(disposition, 'i')) + ); + + if ((/grant all/i).test(disposition)) { + await waitFor(() => { + expect( + screen.getByText(/what type of vacate/i) + ).toBeInTheDocument(); + }); + + selectRadioField(vacateType); + + } else if ((/grant partial/i).test(disposition)) { + await waitFor(() => { + expect( + screen.getByText(/which issues would you like to vacate/i) + ).toBeInTheDocument(); + }); + + selectRadioField(vacateType); + selectRadioField(vacateIssues); + + } else { + await waitFor(() => { + expect( + screen.getByLabelText(/insert caseflow reader document hyperlink/i) + ).toBeInTheDocument(); + }); + + enterAdditionalContext(hyperlink, linkField); + + } + + enterAdditionalContext(instructions, instructionsField); + + await userEvent.click( + screen.getByText('Submit') + ); +}; describe('MTVJudgeDisposition', () => { + const onSubmit = jest.fn(); + const defaults = { appeal: amaAppeal, attorneys: generateAttorneys(5), task, onSubmit, }; + const setup = (props) => render(, { wrapper: BrowserRouter, }); - const selectDisposition = async (disposition = 'grant all') => { - await userEvent.click( - screen.getByLabelText(new RegExp(disposition, 'i')) - ); - - if ((/grant/i).test(disposition)) { - await waitFor(() => { - expect( - screen.getByText(/what type of vacate/i) - ).toBeInTheDocument(); - }); - } else { - await waitFor(() => { - expect( - screen.getByLabelText(/insert caseflow reader document hyperlink/i) - ).toBeInTheDocument(); - }); - } - }; - describe('default view', () => { it('renders correctly', () => { const { container } = setup(); @@ -67,7 +126,7 @@ describe('MTVJudgeDisposition', () => { describe.each(DISPOSITION_OPTIONS.map((item) => [item.value, item]))( 'with %s disposition selected', - (disposition, { displayText: label }) => { + ({ displayText: label }) => { it('renders correctly', async () => { const { container } = setup(); @@ -87,4 +146,237 @@ describe('MTVJudgeDisposition', () => { }); } ); + + describe('Case timeline instructions, feature toggle enabled', () => { + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('grant or partial grant instructions sent', () => { + it('sends the correct instructions based on grant all disposition', async () => { + const disposition = 'grant all'; + let vacateType = 'Vacate and De Novo (2 documents)'; + let vacateIssues; + let hyperlink; + const instructions = 'instructions from judge'; + + setup({ vacateTypeFeatureToggle: false }); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** ' + + '\nFull vacatur' + + '\n' + + '\n**Type:** ' + + '\nVacate and De Novo (2 documents)' + + '\n' + + '\n**Detail:** ' + + '\ninstructions from judge' + + '\n' + ); + }); + + it('sends the correct instructions based on partially granted disposition', async () => { + const disposition = 'Grant partial vacatur'; + const vacateType = 'Straight Vacate (1 document)'; + const vacateIssues = '1. This is a description of the decision'; + let hyperlink; + const instructions = 'some instructions from judge'; + + setup({ vacateTypeFeatureToggle: false }); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch('**Motion To Vacate:** ' + + '\nPartial vacatur' + + '\n' + + '\n**Type:** ' + + '\nStraight Vacate (1 document)' + + '\n' + + '\n**Detail:** ' + + '\nsome instructions from judge' + + '\n' + ); + }); + }); + + describe('deny or dismiss instructions sent', () => { + it('sends the correct instructions based on denied disposition', async () => { + const disposition = 'deny'; + let vacateType; + let vacateIssues; + const hyperlink = 'www.caseflow.com'; + const instructions = 'testing'; + + setup(); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** \n' + + 'Deny all issues for vacatur\n\n' + + '**Detail:** \ntesting\n\n' + + '**Hyperlink:** \nwww.caseflow.com\n' + ); + }); + + it('sends the correct instructions based on dismissed disposition', async () => { + const disposition = 'dismiss'; + let vacateType; + let vacateIssues; + const hyperlink = 'www.google.com'; + const instructions = 'new instructions from judge'; + + setup(); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** \n' + + 'Dismiss all issues for vacatur\n\n**Detail:** \nnew instructions from judge\n\n' + + '**Hyperlink:** \nwww.google.com\n' + ); + }); + }); + }); + + describe('Case timeline instructions, feature toggle disabled', () => { + + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('grant or partial grant instructions sent', () => { + it('sends the correct instructions based on grant all disposition', async () => { + + const disposition = 'grant all'; + let vacateType = 'Vacate and De Novo (2 documents)'; + let vacateIssues; + let hyperlink; + const instructions = 'instructions from judge'; + + setup({ vacateTypeFeatureToggle: true }); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** ' + + '\nFull vacatur' + + '\n' + + '\n**Detail:** ' + + '\ninstructions from judge' + + '\n' + ); + + }); + + it('sends the correct instructions based on partially granted disposition', async () => { + const disposition = 'Grant partial vacatur'; + let vacateType = 'Vacate and De Novo (2 documents)'; + let vacateIssues = '1. This is a description of the decision'; + let hyperlink; + const instructions = 'some instructions from judge'; + + setup({ vacateTypeFeatureToggle: true }); + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** ' + + '\nPartial vacatur' + + '\n' + + '\n**Detail:** ' + + '\nsome instructions from judge' + + '\n' + ); + }); + }); + + describe('deny or dismiss instructions sent', () => { + it('sends the correct instructions based on denied disposition', async () => { + const disposition = 'deny'; + let vacateType; + let vacateIssues; + const hyperlink = 'www.caseflow.com'; + const instructions = 'testing'; + + setup({ vacateTypeFeatureToggle: true }); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** \n' + + 'Deny all issues for vacatur\n\n' + + '**Detail:** \ntesting\n\n' + + '**Hyperlink:** \nwww.caseflow.com\n' + ); + }); + + it('sends the correct instructions based on dismissed disposition', async () => { + const disposition = 'dismiss'; + let vacateType; + let vacateIssues; + const hyperlink = 'www.google.com'; + const instructions = 'new instructions from judge'; + + setup({ vacateTypeFeatureToggle: true }); + + await fillForm( + disposition, + vacateType, + vacateIssues, + hyperlink, + instructions + ); + + expect(onSubmit.mock.calls[0][0].instructions).toMatch( + '**Motion To Vacate:** \n' + + 'Dismiss all issues for vacatur\n\n**Detail:** \nnew instructions from judge\n\n' + + '**Hyperlink:** \nwww.google.com\n' + ); + }); + }); + }); }); diff --git a/client/test/app/queue/mtv/__snapshots__/MTVJudgeDisposition.test.js.snap b/client/test/app/queue/mtv/__snapshots__/MTVJudgeDisposition.test.js.snap index 94920f806ba..01fe1fb42f9 100644 --- a/client/test/app/queue/mtv/__snapshots__/MTVJudgeDisposition.test.js.snap +++ b/client/test/app/queue/mtv/__snapshots__/MTVJudgeDisposition.test.js.snap @@ -422,31 +422,77 @@ exports[`MTVJudgeDisposition with denied disposition selected renders correctly - + +
+
+ + +
+
+ + +
+
+ + +
+
+
@@ -456,7 +502,7 @@ exports[`MTVJudgeDisposition with denied disposition selected renders correctly > - Provide context and instructions on which issues should be denied + Provide context and instructions on which issues should be granted @@ -470,14 +516,114 @@ exports[`MTVJudgeDisposition with denied disposition selected renders correctly name="instructions" />
+
+
- + +
+
+ + +
+
+ + +
+
+ + +
+
+
@@ -719,7 +911,7 @@ exports[`MTVJudgeDisposition with dismissed disposition selected renders correct > - Provide context and instructions on which issues should be dismissed + Provide context and instructions on which issues should be granted @@ -733,14 +925,114 @@ exports[`MTVJudgeDisposition with dismissed disposition selected renders correct name="instructions" />
+
+
-
- - - - Which issues would you like to vacate? - - - -
- - -
-
- - -
-
@@ -1478,7 +1729,7 @@ exports[`MTVJudgeDisposition with partially_granted disposition selected renders > - Provide context and instructions on which issues should be partially_granted + Provide context and instructions on which issues should be granted diff --git a/scripts/enable_features_dev.rb b/scripts/enable_features_dev.rb index 5a0a2ddf6c3..f6053eedb20 100644 --- a/scripts/enable_features_dev.rb +++ b/scripts/enable_features_dev.rb @@ -54,11 +54,12 @@ def call # - they make significantly drastic changes in Dev/Demo compared to Production # - the work around the feature has been paused # - the flag is only being used to disable functionality -disabled_flags = [ - "legacy_das_deprecation", - "cavc_dashboard_workflow", - "poa_auto_refresh", - "interface_version_2" +disabled_flags = %w[ + legacy_das_deprecation + cavc_dashboard_workflow + poa_auto_refresh + interface_version_2 + cc_vacatur_visibility ] all_features = AllFeatureToggles.new.call.flatten.uniq diff --git a/spec/feature/queue/motion_to_vacate_spec.rb b/spec/feature/queue/motion_to_vacate_spec.rb index c07feb9b71d..1841031eaf7 100644 --- a/spec/feature/queue/motion_to_vacate_spec.rb +++ b/spec/feature/queue/motion_to_vacate_spec.rb @@ -435,6 +435,7 @@ def submit_and_fetch_task(judge) expect(new_task.available_actions(motions_attorney)).to include( Constants.TASK_ACTIONS.LIT_SUPPORT_PULAC_CERULLO.to_h ) + expect(new_task.instructions.join("")).to eq(instructions) end end diff --git a/spec/support/queue_helpers.rb b/spec/support/queue_helpers.rb index bfd61ed4c25..39d1cbabb0c 100644 --- a/spec/support/queue_helpers.rb +++ b/spec/support/queue_helpers.rb @@ -9,6 +9,10 @@ def disposition_text mtv_const.DISPOSITION_TEXT.to_h end + def disposition_timeline_text + mtv_const.DISPOSITION_TIMELINE_TEXT.to_h + end + def recommendation_text mtv_const.DISPOSITION_RECOMMENDATIONS.to_h end @@ -32,14 +36,26 @@ def format_mtv_attorney_instructions(notes:, disposition:, hyperlinks: []) end def format_mtv_judge_instructions(notes:, disposition:, vacate_type: nil, hyperlink: nil) - parts = ["I am proceeding with a #{disposition_text[disposition.to_sym]}."] - - parts += case disposition - when "granted", "partial" - ["This will be a #{vacate_types[vacate_type.to_sym]}", notes] - else - [notes, "\nHere is the hyperlink to the signed denial document", hyperlink] - end + parts = ["**Motion To Vacate:** \n#{disposition_timeline_text[disposition.to_sym]}\n"] + + case disposition + when "granted", "partially_granted" + parts += ["**Type:** "] + parts += ["#{vacate_types[vacate_type.to_sym]}\n"] + if !notes.empty? + parts += ["**Detail:** "] + parts += ["#{notes}\n"] + end + when "denied", "dismissed" + if !notes.empty? + parts += ["**Detail:** "] + parts += ["#{notes}\n"] + end + if hyperlink.present? + parts += ["**Hyperlink:** "] + parts += ["#{hyperlink}\n"] + end + end parts.join("\n") end From 93d1fed108dac17824e6d4cc3cabeddc798fd781 Mon Sep 17 00:00:00 2001 From: Tyler Broyles <109369527+TylerBroyles@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:52:56 -0400 Subject: [PATCH 304/308] Removed the skip tag from docket_spec.rb spec test (#18984) --- spec/models/docket_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/models/docket_spec.rb b/spec/models/docket_spec.rb index 620fe365327..78e6734650b 100644 --- a/spec/models/docket_spec.rb +++ b/spec/models/docket_spec.rb @@ -213,8 +213,7 @@ end context "blocking mail tasks with status completed or cancelled" do - it "includes those appeals", - skip: "https://github.com/department-of-veterans-affairs/caseflow/issues/10516#issuecomment-503269122" do + it "includes those appeals" do with_blocking_but_closed_tasks = create(:appeal, :with_post_intake_tasks, docket_type: Constants.AMA_DOCKETS.direct_review) From d23f113b21e1d26843aa9f969c990d9d2f6bae33 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 12 Jul 2023 21:25:23 -0400 Subject: [PATCH 305/308] Revert --- app/jobs/ama_notification_efolder_sync_job.rb | 2 +- app/jobs/legacy_notification_efolder_sync_job.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/ama_notification_efolder_sync_job.rb b/app/jobs/ama_notification_efolder_sync_job.rb index 27ec96b7da7..99813809bc2 100644 --- a/app/jobs/ama_notification_efolder_sync_job.rb +++ b/app/jobs/ama_notification_efolder_sync_job.rb @@ -17,7 +17,7 @@ def perform all_active_ama_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync - sync_notification_reports(all_active_ama_appeals.uniq.first(BATCH_LIMIT.to_i)) + sync_notification_reports(all_active_ama_appeals.first(BATCH_LIMIT.to_i)) end private diff --git a/app/jobs/legacy_notification_efolder_sync_job.rb b/app/jobs/legacy_notification_efolder_sync_job.rb index a833af6c477..d37847a8dbc 100644 --- a/app/jobs/legacy_notification_efolder_sync_job.rb +++ b/app/jobs/legacy_notification_efolder_sync_job.rb @@ -17,7 +17,7 @@ def perform all_active_legacy_appeals = appeals_recently_outcoded + appeals_never_synced + ready_for_resync - sync_notification_reports(all_active_legacy_appeals.uniq.first(BATCH_LIMIT.to_i)) + sync_notification_reports(all_active_legacy_appeals.first(BATCH_LIMIT.to_i)) end private From 9e6af29ea9e5ae8ba30c4c8fc0ba9ee96aafcc00 Mon Sep 17 00:00:00 2001 From: Craig Reese <109101548+craigrva@users.noreply.github.com> Date: Thu, 13 Jul 2023 07:47:03 -0500 Subject: [PATCH 306/308] Craig/appeals 24719 (#18987) * modify test data and setup * fix hearings controller spec assertion * replace array sorting with match_array in dispatch task spec where applicable * added comment for why time is 11:30pm --- client/test/app/queue/ColocatedTaskListView.test.js | 5 +++-- client/test/data/queue/taskLists/index.js | 2 +- spec/controllers/hearings_controller_spec.rb | 2 +- spec/models/dispatch/task_spec.rb | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/client/test/app/queue/ColocatedTaskListView.test.js b/client/test/app/queue/ColocatedTaskListView.test.js index 6660012b6c0..570ec2d2e87 100644 --- a/client/test/app/queue/ColocatedTaskListView.test.js +++ b/client/test/app/queue/ColocatedTaskListView.test.js @@ -31,8 +31,9 @@ const WrapperComponent = ({ children }) => ( ); -// Date constructor uses zero-based offset for months — this is 2021-03-17 -const fakeDate = new Date(2021, 2, 17, 12); +// Date constructor uses zero-based offset for months — this is 2021-03-17. The time (11:30pm) is to ensure +// that the crossover between days doesn't affect the front end calculations for when tasks were assigned +const fakeDate = new Date(2021, 2, 17, 23, 30, 0, 0); beforeAll(() => { // Ensure consistent handling of dates across tests diff --git a/client/test/data/queue/taskLists/index.js b/client/test/data/queue/taskLists/index.js index 08250c39455..1b99fb70dad 100644 --- a/client/test/data/queue/taskLists/index.js +++ b/client/test/data/queue/taskLists/index.js @@ -18,7 +18,7 @@ const getAmaTaskTemplate = ({ id = 1 } = {}) => ({ placed_on_hold_at: null, on_hold_duration: null, status: null, - assigned_at: formatISO(sub(new Date(), { hours: 47 })), + assigned_at: formatISO(sub(new Date(), { days: 2 })), closest_regional_office: null, assigned_to: { css_id: null, diff --git a/spec/controllers/hearings_controller_spec.rb b/spec/controllers/hearings_controller_spec.rb index 00753efa88d..aa3546a0646 100644 --- a/spec/controllers/hearings_controller_spec.rb +++ b/spec/controllers/hearings_controller_spec.rb @@ -467,7 +467,7 @@ patch :update, as: :json, params: params expect(response.status).to eq 200 ama_hearing.reload - expect(ama_hearing.advance_on_docket_motion.person.id).to eq ama_hearing.appeal.appellant.id + expect(ama_hearing.advance_on_docket_motion.person.id).to eq ama_hearing.appeal.appellant.person.id expect(ama_hearing.advance_on_docket_motion.reason).to eq Constants.AOD_REASONS.age expect(ama_hearing.advance_on_docket_motion.granted).to eq true end diff --git a/spec/models/dispatch/task_spec.rb b/spec/models/dispatch/task_spec.rb index 2ed2640fb83..7f7eef117e5 100644 --- a/spec/models/dispatch/task_spec.rb +++ b/spec/models/dispatch/task_spec.rb @@ -56,7 +56,7 @@ def should_invalidate? let!(:unassigned_task) { FakeTask.create!(aasm_state: :unassigned, prepared_at: Date.yesterday) } let!(:reviewed_task) { FakeTask.create!(aasm_state: :reviewed, prepared_at: Date.yesterday) } - it { is_expected.to eq([unassigned_task, reviewed_task]) } + it { is_expected.to match_array [unassigned_task, reviewed_task] } end context ".completed_on" do @@ -79,7 +79,7 @@ def should_invalidate? end # .sort added in case ActiveRecord returns tasks out of order in subject - it { is_expected.to eq([task_completed_this_morning, task_completed_tonight].sort) } + it { is_expected.to match_array [task_completed_this_morning, task_completed_tonight] } end context ".completed_success" do From 8b5a3f3d3367ed21d940727516a2cb1869687bb9 Mon Sep 17 00:00:00 2001 From: Brandon Lee Dorner Date: Thu, 13 Jul 2023 08:01:58 -0500 Subject: [PATCH 307/308] Fix flake spec "access the appeal's case details" (#18981) --- spec/feature/queue/case_details_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/feature/queue/case_details_spec.rb b/spec/feature/queue/case_details_spec.rb index ad4ac936d3a..635e80d969b 100644 --- a/spec/feature/queue/case_details_spec.rb +++ b/spec/feature/queue/case_details_spec.rb @@ -655,9 +655,10 @@ def wait_for_page_render Fakes::BGSService.inaccessible_appeal_vbms_ids << appeal.veteran_file_number allow_any_instance_of(Fakes::BGSService).to receive(:fetch_veteran_info) .and_raise(BGS::ShareError, "NonUniqueResultException") + appeal.veteran&.multiple_phone_numbers? end - scenario "access the appeal's case details", skip: "flake" do + scenario "access the appeal's case details" do visit "/queue/appeals/#{appeal.external_id}" expect(page).to have_content(COPY::DUPLICATE_PHONE_NUMBER_TITLE) From 9a6b4207dd74fb4b4387c4df800ede86f8053037 Mon Sep 17 00:00:00 2001 From: Matt Roth Date: Thu, 13 Jul 2023 15:35:19 -0400 Subject: [PATCH 308/308] Update MAC_INTEL.md (#18997) * Update MAC_INTEL.md * Update MAC_INTEL.md * Update MAC_INTEL.md * update setup scripts * Update MAC_INTEL.md --- MAC_INTEL.md | 91 ++++++++++++++++------------------ scripts/dev_env_setup_step1.sh | 11 ++-- scripts/dev_env_setup_step2.sh | 6 +-- 3 files changed, 49 insertions(+), 59 deletions(-) diff --git a/MAC_INTEL.md b/MAC_INTEL.md index dc4a757491c..96e2951e042 100644 --- a/MAC_INTEL.md +++ b/MAC_INTEL.md @@ -3,6 +3,7 @@ [<< Back](README.md) **Pre-requisites for setup:** +**Some steps require completing VA On-boarding** 1. Create GitHub user account [VA github access process](https://department-of-veterans-affairs.github.io/github-handbook/guides/onboarding/getting-access) @@ -20,46 +21,37 @@ 2. Install Homebrew * a. Using BAH Self Service if BAH employee Run ```brew install git-lfs .``` This is required to clone caseflow-facols repo -3. Create a caseflow-setup folder by typing: `mkdir caseflow-setup` (step can be skipped if you have the file transfer files) +3. Create an appeals folder by typing: `mkdir ~/appeals` -4. Change directory to caseflow-setup by typing: `cd caseflow-setup` +4. Change directory to appeals by typing: `cd appeals` 5. Navigate to [instant client](https://www.oracle.com/database/tecdchnologies/instant-client/linux-x86-64-downloads.html) -6. Download the following zip files to caseflow-setup directory (Copy from downloads to the caseflow-setup directory if they download to downloads) (Step can be skipped if you received the file transfer files) +6. Download the following zip files (Step can be skipped if you received the file transfer files) * instantclient-basic-linux.x64-12.2.0.1.0.zip * instantclient-sqlplus-linux.x64-12.2.0.1.0.zip * instantclient-sdk-linux.x64-12.2.0.1.0.zip -7. Clone caseflow repositories required for setup into caseflow-setup directory (caseflow-facols requires github account and the account has to be in the VA org in github and can be found in the file transfer files) pwd - * HTTP protocol - * `git clone https://github.com/department-of-veterans-affairs/caseflow.git` - * `git clone https://github.com/department-of-veterans-affairs/caseflow-facols.git` - * Upon completion, navigate to caseflow-facols (`cd ~/caseflow-setup/caseflow-facols`) - * Run: `git lfs install` (needed to initialize large file storage in repo) - * Run: `git lfs pull` (this will pull the large zipfile) - * If you do not have VA access yet to clone caseflow-vacols can contact (Your Tech lead or the bid_appeals_mac_support channel) to receive a zip of the repository +7. Clone the following caseflow repositories required into appeals directory + * https://github.com/department-of-veterans-affairs/caseflow + * https://github.com/department-of-veterans-affairs/caseflow-facols -**SSH protocol** +8. Upon completion, navigate to caseflow-facols (`cd ~/appeals/caseflow-facols`) + 1. Run: `git lfs install` (needed to initialize large file storage in repo) + 2. Run: `git lfs pull` (this will pull the large zipfile) + 3. Copy the `~/appeals/caseflow-facols/build_facols` directory into `~/appeals/caseflow/local/vacols/` directory. -1. `git clone git@github.com:department-of-veterans-affairs/caseflow.git` +9. Navigate to the caseflow directory in your terminal (type: `cd ~/appeals/caseflow`) and checkout the grant/setup-no-aws branch `git checkout grant/setup-no-aws` -2. `git clone git@github.com:department-of-veterans-affairs/caseflow-facols.git` - * Upon completion, navigate to caseflow-facols (`cd ~/caseflow-setup/caseflow-facols`) - * Run: `git lfs install` (needed to initialize large file storage in repo) - * Run: `git lfs pull` (this will pull the large zipfile) +10. Navigate to caseflow/docker-bin directory (type: `cd docker-bin`) -3. Navigate to the caseflow directory in your terminal (type: `cd ~/caseflow-setup/caseflow`) and checkout the grant/setup-no-aws branch `git checkout grant/setup-no-aws` +11. Create oracle_libs subdirectory (type: `mkdir oracle_libs`) -4. Navigate to caseflow/docker-bin directory (type: `cd docker-bin`) +12. Copy the 3 instant-client zip files from step 6 into the oracle_libs directory -5. Create oracle_libs subdirectory (type: `mkdir oracle_libs`) +13. Navigate to the caseflow root directory (type: `cd ~/appeals/caseflow`) -6. Copy the 3 instant-client zip files from the caseflow-setup directory into the oracle_libs directory - -7. Navigate to the caseflow root directory (type: `cd ..`) - -8. Run scripts/dev_env_setup_step1.sh script from bash terminal (How to run script in Mac Terminal) (Will be prompted for a password will be the SUDO password which is the password used to log into mac after restart) +14. Run `scripts/dev_env_setup_step1.sh` script from bash terminal [[How to run script in Mac Terminal](https://apple.stackexchange.com/questions/235128/how-do-i-run-a-sh-or-command-file-in-terminal)] (Will be prompted for a password will be the SUDO password which is the password used to log into mac after restart) * If/When mac says Chromedriver cannot be opened do this: * Click cancel on the warning modal * Push Command + Space @@ -68,7 +60,7 @@ * Click General tab * Click the lock icon and put in your BAH pin Click allow anyway on chromedriver warning Click the lock icon to re lock -9. Setup Docker to use 4 CPUs and 8G memory and sign-in to your personal DockerHub account +15. Setup Docker to use 4 CPUs and 8G memory and sign-in to your personal DockerHub account * To get to these settings: * Command + Space * Type docker @@ -76,42 +68,47 @@ * Click the gear icon * Click Resources -10. The script updated your bash profile and you need to resource it into the terminal by typing: `source ~/.bash_profile` +16. The script updated your bash profile and you need to resource it into the terminal by typing: `source ~/.bash_profile` * If using zsh, will need to update and `source ~/.zshrc` instead -11. `brew install shared-mime-info` +17. `brew install shared-mime-info` -12. `brew install v8@3.15` +18. `brew install v8@3.15` -13. Run scripts/dev_env_setup_step2.sh script (may take a while to run) +19. Run `scripts/dev_env_setup_step2.sh` script (may take a while to run) -14. Run `gem install bundler` - * Copy the caseflow-facols/build_facols directory to the caseflow/local/vacols subdirectory. (Ensure you have a caseflow/local/vacols/build_facols directory with all the files before continuing to the next step) +20. Run `gem install bundler` -15. Navigate to caseflow/local/vacols in terminal `cd ~/caseflow- setup/caseflow/local/vacols` +21. Navigate to `~/appeals/caseflow/local/vacols` in terminal (type: `cd ~/appeals/caseflow/local/vacols`) -16. Run `./build_push.sh local` - * Requires the oracle database image to have been pulled after running scripts/dev_env_setup_step1.sh script +22. To install the latest and enterprise Oracle Database version follow (https://seanstacey.org/deploying-an-oracle-database-19c-as-a-docker-container/2020/09/) guide. + 1. Go to http://container-registry.oracle.com/ (Here log in and opt for Database) + 2. On command line `docker login container-registry.oracle.com` + 3. On command line `docker pull container-registry.oracle.com/database/enterprise:latest` -17. Navigate to caseflow root directory `cd ~/caseflow-setup/caseflow` +23. Run `./build_push.sh local` -18. Run `docker-compose up –d` +24. Navigate to caseflow root directory `cd ~/appeals/caseflow` -19. Run `bundle exec rake db:create` - * If you get connection issues stating no file to be found, run the following: - * `rm /opt/homebrew/var/postgres/postmaster.pid` or possibly `rm /usr/local/var/postgres/postmaster.pid` - * `brew services restart postgresql` +25. Run `ln -s Makefile.example Makefile` -20. Run `bundle exec rake local:vacols:seed` +26. Run `make up` -21. Run `bundle exec rake db:schema:load db:seed` +27. Run `make reset` + * If issues occur: + 1. Run `bundle exec rake db:create` + * If you get connection issues stating no file to be found, run the following: + * `rm /opt/homebrew/var/postgres/postmaster.pid` or possibly `rm /usr/local/var/postgres/postmaster.pid` + * `brew services restart postgresql` + 2. Run `bundle exec rake local:vacols:seed` + 3. Run `bundle exec rake db:schema:load db:seed` -22. Open a new tab in terminal +27. Open a new tab in terminal -23. In new tab run make: ```run-backend``` +28. In new tab run make: ```run-backend``` -24. In the old tab run: ```make run-frontend``` +29. In the old tab run: ```make run-frontend``` -25. Navigate to localhost:3000 in browser to see the application +30. Navigate to localhost:3000 in browser to see the application [<< Back](README.md) diff --git a/scripts/dev_env_setup_step1.sh b/scripts/dev_env_setup_step1.sh index 57259bf0bc6..e29b26b96da 100755 --- a/scripts/dev_env_setup_step1.sh +++ b/scripts/dev_env_setup_step1.sh @@ -98,13 +98,10 @@ echo "1. Run Docker and go into advanced preferences to limit Docker's resources Recommended settings are 4 CPUs, 8 GiB of internal memory, and 512 MiB of swap. " -echo "2. In a new terminal, run: - docker login -u dsvaappeals - The password is in the DSVA 1Password account. - Note you can use your personal account as well, you'll just have to accept - the license agreement for the Oracle Database docker image. - https://store.docker.com/images/oracle-database-enterprise-edition - To accept the agreement, checkout with the Oracle image on the docker store. +echo "2. To install the latest and enterprise Oracle Database version follow (https://seanstacey.org/deploying-an-oracle-database-19c-as-a-docker-container/2020/09/) guide. + 1. Go to http://container-registry.oracle.com/ (Here log in and opt for Database) + 2. On command line docker login container-registry.oracle.com + 3. On command line docker pull container-registry.oracle.com/database/enterprise:latest " echo "==> Close this terminal, open a new terminal, and run ./dev_env_setup_step2.sh diff --git a/scripts/dev_env_setup_step2.sh b/scripts/dev_env_setup_step2.sh index bbbce1ddc84..7df7a9dab77 100755 --- a/scripts/dev_env_setup_step2.sh +++ b/scripts/dev_env_setup_step2.sh @@ -46,11 +46,7 @@ ln -s Makefile.example Makefile echo " =================================== -You must do the following manually: - -AWS access is needed starting at this point. -If you need to get AWS access, follow these instructions: - https://github.com/department-of-veterans-affairs/appeals-deployment/wiki/New-Hires +Congratulations " echo 'Finish the manual set up from "Database environment setup":