From 7cf18dc91dfab92ada8b964a548627170e0a182d Mon Sep 17 00:00:00 2001 From: Oren Mittman Date: Mon, 23 Dec 2024 11:52:17 -0500 Subject: [PATCH] [ART] POA request representative --- app/models/accredited_individual.rb | 5 ++ app/models/accredited_organization.rb | 5 ++ .../power_of_attorney_requests_controller.rb | 15 +++++- .../power_of_attorney_request.rb | 7 ++- .../power_of_attorney_request_serializer.rb | 12 +++++ .../accredited_individual_serializer.rb | 17 +++++++ .../power_of_attorney_holder_serializer.rb | 32 ++++++++++++ .../factories/power_of_attorney_request.rb | 3 ++ .../v0/power_of_attorney_requests_spec.rb | 49 ++++++++++++++++++- 9 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/accredited_individual_serializer.rb create mode 100644 modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/power_of_attorney_holder_serializer.rb diff --git a/app/models/accredited_individual.rb b/app/models/accredited_individual.rb index 46b06d7142a..86bebe29aea 100644 --- a/app/models/accredited_individual.rb +++ b/app/models/accredited_individual.rb @@ -23,6 +23,11 @@ class AccreditedIndividual < ApplicationRecord has_many :accreditations, dependent: :destroy has_many :accredited_organizations, through: :accreditations + has_many :power_of_attorney_requests, + as: :power_of_attorney_holder, + inverse_of: :power_of_attorney_holder, + class_name: 'AccreditedRepresentativePortal::PowerOfAttorneyRequest' + validates :ogc_id, :registration_number, :individual_type, presence: true validates :poa_code, length: { is: 3 }, allow_blank: true validates :individual_type, uniqueness: { scope: :registration_number } diff --git a/app/models/accredited_organization.rb b/app/models/accredited_organization.rb index 5ae1546caed..312a9acf366 100644 --- a/app/models/accredited_organization.rb +++ b/app/models/accredited_organization.rb @@ -19,6 +19,11 @@ class AccreditedOrganization < ApplicationRecord has_many :accreditations, dependent: :destroy has_many :accredited_individuals, through: :accreditations + has_many :power_of_attorney_requests, + as: :power_of_attorney_holder, + inverse_of: :power_of_attorney_holder, + class_name: 'AccreditedRepresentativePortal::PowerOfAttorneyRequest' + validates :ogc_id, :poa_code, presence: true validates :poa_code, length: { is: 3 } validates :poa_code, uniqueness: true diff --git a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/power_of_attorney_requests_controller.rb b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/power_of_attorney_requests_controller.rb index f376037b0fc..d256e37c97e 100644 --- a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/power_of_attorney_requests_controller.rb +++ b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/power_of_attorney_requests_controller.rb @@ -4,20 +4,31 @@ module AccreditedRepresentativePortal module V0 class PowerOfAttorneyRequestsController < ApplicationController def index - poa_requests = PowerOfAttorneyRequest.includes(resolution: :resolving).limit(100) + poa_requests = poa_requests_rel.limit(100) serializer = PowerOfAttorneyRequestSerializer.new(poa_requests) render json: serializer.serializable_hash, status: :ok end def show - poa_request = PowerOfAttorneyRequest.includes(resolution: :resolving).find(params[:id]) + poa_request = poa_requests_rel.find(params[:id]) serializer = PowerOfAttorneyRequestSerializer.new(poa_request) render json: serializer.serializable_hash, status: :ok rescue ActiveRecord::RecordNotFound render json: { error: 'Record not found' }, status: :not_found end + + private + + def poa_requests_rel + PowerOfAttorneyRequest.includes( + :power_of_attorney_form, + :power_of_attorney_holder, + :accredited_individual, + resolution: :resolving + ) + end end end end diff --git a/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_request.rb b/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_request.rb index a7db8664312..8283d5a05e5 100644 --- a/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_request.rb +++ b/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_request.rb @@ -10,7 +10,6 @@ module ClaimantTypes belongs_to :claimant, class_name: 'UserAccount' has_one :power_of_attorney_form, - class_name: 'AccreditedRepresentativePortal::PowerOfAttorneyForm', inverse_of: :power_of_attorney_request, required: true @@ -18,6 +17,12 @@ module ClaimantTypes class_name: 'AccreditedRepresentativePortal::PowerOfAttorneyRequestResolution', inverse_of: :power_of_attorney_request + belongs_to :power_of_attorney_holder, + inverse_of: :power_of_attorney_requests, + polymorphic: true + + belongs_to :accredited_individual + before_validation :set_claimant_type private diff --git a/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer.rb b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer.rb index 1710d9a77b2..26169307864 100644 --- a/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer.rb +++ b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer.rb @@ -23,5 +23,17 @@ class PowerOfAttorneyRequestSerializer < ApplicationSerializer .new(poa_request.resolution) .serializable_hash end + + attribute :power_of_attorney_holder do |poa_request| + PowerOfAttorneyHolderSerializer + .new(poa_request.power_of_attorney_holder) + .serializable_hash + end + + attribute :accredited_individual do |poa_request| + AccreditedIndividualSerializer + .new(poa_request.accredited_individual) + .serializable_hash + end end end diff --git a/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/accredited_individual_serializer.rb b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/accredited_individual_serializer.rb new file mode 100644 index 00000000000..e72529559c0 --- /dev/null +++ b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/accredited_individual_serializer.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module AccreditedRepresentativePortal + class PowerOfAttorneyRequestSerializer + class AccreditedIndividualSerializer < ApplicationSerializer + attribute :full_name do |poa_holder| + parts = [ + poa_holder.first_name, + poa_holder.middle_initial, + poa_holder.last_name + ] + + parts.reject(&:blank?).join(' ') + end + end + end +end diff --git a/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/power_of_attorney_holder_serializer.rb b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/power_of_attorney_holder_serializer.rb new file mode 100644 index 00000000000..bec5719076f --- /dev/null +++ b/modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer/power_of_attorney_holder_serializer.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module AccreditedRepresentativePortal + class PowerOfAttorneyRequestSerializer + class PowerOfAttorneyHolderSerializer < ApplicationSerializer + attribute :type do |poa_holder| + case poa_holder + when AccreditedIndividual + "accredited_#{poa_holder.individual_type}" + when AccreditedOrganization + 'veteran_service_organization' + end + end + + with_options if: proc { |poa_holder| poa_holder.is_a?(AccreditedOrganization) } do + attribute :name + end + + with_options if: proc { |poa_holder| poa_holder.is_a?(AccreditedIndividual) } do + attribute :full_name do |poa_holder| + parts = [ + poa_holder.first_name, + poa_holder.middle_initial, + poa_holder.last_name + ] + + parts.reject(&:blank?).join(' ') + end + end + end + end +end diff --git a/modules/accredited_representative_portal/spec/factories/power_of_attorney_request.rb b/modules/accredited_representative_portal/spec/factories/power_of_attorney_request.rb index 10929482348..a421ce16bc1 100644 --- a/modules/accredited_representative_portal/spec/factories/power_of_attorney_request.rb +++ b/modules/accredited_representative_portal/spec/factories/power_of_attorney_request.rb @@ -5,6 +5,9 @@ association :claimant, factory: :user_account association :power_of_attorney_form, strategy: :build + association :power_of_attorney_holder, factory: [:accredited_organization, :with_representatives] + accredited_individual { power_of_attorney_holder.accredited_individuals.first } + trait :with_acceptance do resolution { create(:power_of_attorney_request_resolution, :acceptance) } end diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec.rb b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec.rb index 9e3a3c8c712..92a75148a7e 100644 --- a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec.rb +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec.rb @@ -23,7 +23,7 @@ end describe 'GET /accredited_representative_portal/v0/power_of_attorney_requests' do - it 'returns the list of power of attorney requests', skip: 'temporarily for a migration' do + it 'returns the list of power of attorney requests' do poa_requests get('/accredited_representative_portal/v0/power_of_attorney_requests') @@ -88,6 +88,15 @@ 'email' => 'veteran@example.com' } }, + 'power_of_attorney_holder' => { + 'id' => poa_requests[0].power_of_attorney_holder.id, + 'type' => 'veteran_service_organization', + 'name' => poa_requests[0].power_of_attorney_holder.name + }, + 'accredited_individual' => { + 'id' => poa_requests[0].accredited_individual.id, + 'full_name' => "#{poa_requests[0].accredited_individual.first_name} #{poa_requests[0].accredited_individual.last_name}", + }, 'resolution' => nil }, { @@ -145,6 +154,15 @@ 'email' => 'veteran@example.com' } }, + 'power_of_attorney_holder' => { + 'id' => poa_requests[1].power_of_attorney_holder.id, + 'type' => 'veteran_service_organization', + 'name' => poa_requests[1].power_of_attorney_holder.name + }, + 'accredited_individual' => { + 'id' => poa_requests[1].accredited_individual.id, + 'full_name' => "#{poa_requests[1].accredited_individual.first_name} #{poa_requests[1].accredited_individual.last_name}", + }, 'resolution' => { 'id' => poa_requests[1].resolution.id, 'type' => 'decision', @@ -208,6 +226,15 @@ 'email' => 'veteran@example.com' } }, + 'power_of_attorney_holder' => { + 'id' => poa_requests[2].power_of_attorney_holder.id, + 'type' => 'veteran_service_organization', + 'name' => poa_requests[2].power_of_attorney_holder.name + }, + 'accredited_individual' => { + 'id' => poa_requests[2].accredited_individual.id, + 'full_name' => "#{poa_requests[2].accredited_individual.first_name} #{poa_requests[2].accredited_individual.last_name}", + }, 'resolution' => { 'id' => poa_requests[2].resolution.id, 'type' => 'decision', @@ -272,6 +299,15 @@ 'email' => 'veteran@example.com' } }, + 'power_of_attorney_holder' => { + 'id' => poa_requests[3].power_of_attorney_holder.id, + 'type' => 'veteran_service_organization', + 'name' => poa_requests[3].power_of_attorney_holder.name + }, + 'accredited_individual' => { + 'id' => poa_requests[3].accredited_individual.id, + 'full_name' => "#{poa_requests[3].accredited_individual.first_name} #{poa_requests[3].accredited_individual.last_name}", + }, 'resolution' => { 'id' => poa_requests[3].resolution.id, 'type' => 'expiration', @@ -284,7 +320,7 @@ end describe 'GET /accredited_representative_portal/v0/power_of_attorney_requests/:id' do - it 'returns the details of a specific power of attorney request', skip: 'temporarily for a migration' do + it 'returns the details of a specific power of attorney request' do get("/accredited_representative_portal/v0/power_of_attorney_requests/#{poa_request.id}") parsed_response = JSON.parse(response.body) @@ -353,6 +389,15 @@ 'creator_id' => poa_request.resolution.resolving.creator_id, 'reason' => 'Didn\'t authorize treatment record disclosure', 'decision_type' => 'declination' + }, + 'power_of_attorney_holder' => { + 'id' => poa_request.power_of_attorney_holder.id, + 'type' => 'veteran_service_organization', + 'name' => poa_request.power_of_attorney_holder.name + }, + 'accredited_individual' => { + 'id' => poa_request.accredited_individual.id, + 'full_name' => "#{poa_request.accredited_individual.first_name} #{poa_request.accredited_individual.last_name}", } } )