From 0d42b992008e88bd4d397965d915d59a0ab2c5e9 Mon Sep 17 00:00:00 2001 From: Jonathan Cohen Date: Mon, 24 Apr 2023 10:43:15 -0400 Subject: [PATCH 001/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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/293] 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 3b9870825d24b021c5d3e63abf01cf4457aaef76 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 27 Jun 2023 08:57:35 -0400 Subject: [PATCH 203/293] 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 204/293] 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 205/293] 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 206/293] 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 207/293] 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 208/293] 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 209/293] 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 210/293] 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 211/293] 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 212/293] 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 213/293] 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 214/293] 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 215/293] 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 216/293] 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 217/293] 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 218/293] 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 219/293] 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 220/293] 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 221/293] 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 222/293] 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 223/293] 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 224/293] 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 225/293] 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 226/293] 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 227/293] 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 228/293] 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 229/293] 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 230/293] 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 231/293] 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 232/293] 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 233/293] 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 234/293] 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 235/293] 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 236/293] 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 237/293] 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 238/293] 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 239/293] 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 240/293] 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 241/293] 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 242/293] 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 243/293] 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 244/293] 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 245/293] 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 246/293] 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 247/293] 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 248/293] 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 249/293] 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 250/293] 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 251/293] 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 252/293] 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 253/293] 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 254/293] 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 255/293] 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 256/293] 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 257/293] 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 258/293] 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 259/293] 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 260/293] 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 261/293] 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 262/293] 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 263/293] 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 264/293] 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 265/293] 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 266/293] 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 267/293] 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 268/293] 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 269/293] 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 270/293] 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 271/293] 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 272/293] 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 273/293] 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 d9967c6eba24546eeec5d743c1496677bfdff726 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Thu, 6 Jul 2023 13:21:11 -0400 Subject: [PATCH 274/293] 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 275/293] 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 276/293] 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 2ca80920089b11bca7d8d7bbc51f02c41fd41cc5 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Tue, 11 Jul 2023 13:46:06 -0400 Subject: [PATCH 277/293] 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 278/293] 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 279/293] 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 280/293] 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 281/293] 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 282/293] 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 283/293] 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 284/293] 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 285/293] 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 286/293] 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 287/293] 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 288/293] 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 289/293] 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 290/293] --- 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 257a0a1560d28986bc6ff0f369efb1ff9598f23b Mon Sep 17 00:00:00 2001 From: Marc Steele Date: Wed, 12 Jul 2023 12:38:34 -0400 Subject: [PATCH 291/293] 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 29e3405aec406757f2a86d87abed737b996d3a96 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 12 Jul 2023 14:17:34 -0400 Subject: [PATCH 292/293] 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 d23f113b21e1d26843aa9f969c990d9d2f6bae33 Mon Sep 17 00:00:00 2001 From: Matthew Thornton Date: Wed, 12 Jul 2023 21:25:23 -0400 Subject: [PATCH 293/293] 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