Skip to content

Commit

Permalink
Release 21.9.20 (#5)
Browse files Browse the repository at this point in the history
* docker image build updates, ruby version and bundler version bump

* Add operations for rrv manifest creation zip files

* Update filename

* Modify operations to create rrv medicare file for bulk of applications

* Add rrv medicare response operations

* refactor rrv medicare response operation

* Update aca entities reference

* revert back ruby version to 2.7.3

Co-authored-by: Matt Williams <m.a.dubya@gmail.com>
Co-authored-by: saipraveen18 <saipraveen.gudimetla@gmail.com>
  • Loading branch information
3 people authored Sep 20, 2021
1 parent 6f6aab0 commit 153acde
Show file tree
Hide file tree
Showing 15 changed files with 1,971 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .docker/base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
### app/rails config ###
########################

FROM ruby:2.7.2 AS app
FROM ruby:2.7.3 AS app

LABEL author="IdeaCrew"

Expand Down
2 changes: 1 addition & 1 deletion .docker/base_build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
docker build --build-arg BUNDLER_VERSION_OVERRIDE='2.2.10' \
docker build --build-arg BUNDLER_VERSION_OVERRIDE='2.2.24' \
--build-arg NODE_MAJOR='12' \
--build-arg YARN_VERSION='1.22.4' \
-f .docker/base/Dockerfile --target app -t $1:base .
Expand Down
2 changes: 1 addition & 1 deletion .docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ cp .docker/config/production.rb config/environments/
cp .docker/config/credentials.yml.enc config/
cp .docker/config/master.key config/

docker build --build-arg BUNDLER_VERSION_OVERRIDE='2.2.10' \
docker build --build-arg BUNDLER_VERSION_OVERRIDE='2.2.24' \
--build-arg NODE_MAJOR='12' \
--build-arg YARN_VERSION='1.22.4' \
-f .docker/production/Dockerfile --target app -t $2:$1 .
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ gem 'turbolinks', '~> 5'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'

gem 'rubyzip'

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
Expand Down
6 changes: 4 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GIT
remote: https://github.com/ideacrew/aca_entities.git
revision: 3d3985fc09f3f183d3c8b89e9687c9c7949760f8
revision: e047cacbb7077d2cdf262784d87b5e55af40396b
branch: trunk
specs:
aca_entities (0.4.0)
aca_entities (0.6.0)
deep_merge
dry-monads (~> 1.2)
dry-struct (~> 1.0)
Expand Down Expand Up @@ -384,6 +384,7 @@ GEM
rubocop-ast (>= 1.1.0)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rufus-scheduler (3.8.0)
fugit (~> 1.1, >= 1.1.6)
sass-rails (6.0.0)
Expand Down Expand Up @@ -481,6 +482,7 @@ DEPENDENCIES
rubocop-rails
rubocop-rake
rubocop-rspec
rubyzip
sass-rails (>= 6)
shoulda-matchers
turbolinks (~> 5)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module Subscribers
module Fdsh
module DeterminationRequests
# Publish events for FDSH RRV requests
class RrvMedicareDeterminationSubscriber
include ::EventSource::Subscriber[amqp: 'enroll.fdsh.verifications']

# rubocop:disable Lint/RescueException
# rubocop:disable Style/LineEndConcatenation
# rubocop:disable Style/StringConcatenation
subscribe(:on_magi_medicaid_application_determined) do |delivery_info, properties, payload|
# Sequence of steps that are executed as single operation
correlation_id = properties.correlation_id

determination_result = Operations::Fdsh::Rrv::Medicare::RequestRrvMedicareDetermination.new.call({
payload: payload,
correlation_id: correlation_id
})

if determination_result.success?
logger.info(
"OK: :on_fdsh_rrv_medicare_eligibility_determination_subscriber successful and acked"
)
ack(delivery_info.delivery_tag)
else
logger.error(
"Error: :on_fdsh_rrv_medicare_eligibility_determination_subscriber; nacked due to:#{determination_result.inspect}"
)
nack(delivery_info.delivery_tag)
end

rescue Exception => e
logger.error(
"Exception: :on_fdsh_rrv_medicare_eligibility_determination_subscriber\n Exception: #{e.inspect}" +
"\n Backtrace:\n" + e.backtrace.join("\n")
)
nack(delivery_info.delivery_tag)
end
# rubocop:enable Lint/RescueException
# rubocop:enable Style/LineEndConcatenation
# rubocop:enable Style/StringConcatenation
end
end
end
end
48 changes: 48 additions & 0 deletions app/operations/fdsh/rrv/medicare/build_medicare_request_xml.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require 'dry/monads'
require 'dry/monads/do'

module Fdsh
module Rrv
module Medicare
# This class takes happy mapper hash as input and returns
class BuildMedicareRequestXml
include Dry::Monads[:result, :do, :try]
include EventSource::Command

# PublishEventStruct = Struct.new(:name, :payload, :headers)
#
# PUBLISH_EVENT = "fdsh_determine_esi_mec_eligibility"

# @return [Dry::Monads::Result]
def call(applications)
rrv_medicare_request = yield Fdsh::Rrv::Medicare::TransformApplicationToRrvMedicareRequest.new.call(applications)
xml_string = yield encode_xml_and_schema_validate(rrv_medicare_request)
# TODO: STORE Request
# _updated_transaction = yield create_or_update_transaction('request', xml_string, params)
rrv_medicare_xml = yield encode_request_xml(xml_string)

Success(rrv_medicare_xml)
end

protected

def encode_xml_and_schema_validate(esi_request)
AcaEntities::Serializers::Xml::Fdsh::Rrv::Medicare::Operations::MedicareRequestToXml.new.call(esi_request)
end

def encode_request_xml(xml_string)
encoding_result = Try do
xml_doc = Nokogiri::XML(xml_string)
xml_doc.to_xml(:indent => 2, :encoding => 'UTF-8')
end

encoding_result.or do |e|
Failure(e)
end
end
end
end
end
end
147 changes: 147 additions & 0 deletions app/operations/fdsh/rrv/medicare/create_request_manifest_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# frozen_string_literal: true

require 'dry/monads'
require 'dry/monads/do'
require 'digest'
require 'zip'

module Fdsh
module Rrv
module Medicare
# This class create a rrv medicare request manifest file
class CreateRequestManifestFile
include Dry::Monads[:result, :do, :try]
include EventSource::Command

def call(applications)
@applicants_count = applications.flat_map(&:applicants).count
medicare_payload = yield BuildMedicareRequestXml.new.call(applications)
@medicare_file = yield create_medicare_xml_file(medicare_payload)
manifest_request = yield construct_manifest_request
validated_manifest_request = yield validate_manifest_request(manifest_request)
manifest_entity = yield transform_request_to_entity(validated_manifest_request)
xml_string = yield encode_xml_and_schema_validate(manifest_entity)
rrv_manifest_medicare_xml = yield encode_manifest_request_xml(xml_string)
@manifest_file = yield create_manifest_file(rrv_manifest_medicare_xml)
generate_batch_zip
Success("Zip generated succesfully")
end

private

def create_medicare_xml_file(rrv_medicare_xml)
folder = "#{Rails.root}/rrv_request_outbound"
@outbound_folder = FileUtils.mkdir_p(folder).first
file_name = @outbound_folder + "/MDCR_Request_00001_#{Time.now.gmtime.strftime('%Y%m%dT%H%M%S%LZ')}.xml"
file = File.open(file_name, "w")
file.write(rrv_medicare_xml.to_s)
file.close
Success(file)
end

def create_manifest_file(rrv_manifest_medicare_xml)
file = File.new("#{@outbound_folder}/manifest.xml", "w")
file.write(rrv_manifest_medicare_xml.to_s)
file.close
Success(file)
end

def validate_manifest_request(manifest_request)
result = AcaEntities::Fdsh::Rrv::H79::BatchHandlingServiceRequestContract.new.call(manifest_request)
result.success? ? Success(result) : Failure("Invalid Rrv Manifest request due to #{result.errors.to_h}")
end

def transform_request_to_entity(manifest_request)
Success(AcaEntities::Fdsh::Rrv::H79::BatchHandlingServiceRequest.new(manifest_request.to_h))
end

def encode_xml_and_schema_validate(esi_request)
AcaEntities::Serializers::Xml::Fdsh::Rrv::H79::Operations::RrvRequestToXml.new.call(esi_request)
end

def generate_batch_zip
input_files = [File.basename(@medicare_file), File.basename(@manifest_file)]
@zip_name = @outbound_folder + "/SBE00ME.DSH.RRVIN.D#{Time.now.strftime('%y%m%d.T%H%M%S%L.T')}.IN.zip"

Zip::File.open(@zip_name, create: true) do |zipfile|
input_files.each do |filename|
zipfile.add(filename, File.join(@outbound_folder, filename))
end
end
FileUtils.rm_rf(File.join(@outbound_folder, File.basename(@medicare_file)))
FileUtils.rm_rf(File.join(@outbound_folder, File.basename(@manifest_file)))
end

def encode_manifest_request_xml(xml_string)
encoding_result = Try do
xml_doc = Nokogiri::XML(xml_string)
xml_doc.to_xml(:indent => 2, :encoding => 'UTF-8')
end

encoding_result.or do |e|
Failure(e)
end
end

def construct_manifest_request
manifest_request = {
BatchMetadata: construct_batch_metadata,
TransmissionMetadata: construct_transmission_metadata,
ServiceSpecificData: construct_service_specific_data
}

Success(manifest_request)
end

def construct_batch_metadata
{
BatchID: Time.now.gmtime.strftime("%Y-%m-%dT%H:%M:%SZ"),
BatchPartnerID: "02.ME*.SBE.001.001",
BatchAttachmentTotalQuantity: 1,
BatchCategoryCode: "RRV_REQ",
BatchTransmissionQuantity: 1
}
end

def construct_transmission_metadata
{
TransmissionAttachmentQuantity: 1,
TransmissionSequenceID: 1
}
end

def construct_service_specific_data
{
MedicareFileMetadata: {
MedicareDocumentAttachmentQuantity: 1,
Attachment: construct_attachment
}
}
end

def construct_attachment
{
DocumentBinary: construct_document_binary,
DocumentFileName: File.basename(@medicare_file.path),
DocumentSequenceID: "00001",
DocumentRecordCount: @applicants_count
}
end

def construct_document_binary
{
ChecksumAugmentation: {
SHA256HashValueText: generate_checksum_hexdigest
},
BinarySizeValue: File.size(@medicare_file.path).to_s
}
end

def generate_checksum_hexdigest
sha256 = Digest::SHA256.file(@medicare_file.path)
sha256.hexdigest
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require 'dry/monads'
require 'dry/monads/do'
require 'digest'
require 'zip'

module Fdsh
module Rrv
module Medicare
module Response
# This class create a rrv medicare request manifest file
class ConstructMedicareResponse
include Dry::Monads[:result, :do, :try]
include EventSource::Command

def call(payload)
response_hash = yield construct_params(payload)
valid_response = yield validate_rrv_medicare_response(response_hash)
medicare_response = yield create_rrv_medicare_response(valid_response)

Success(medicare_response)
end

private

def construct_params(payload)
if payload.IndividualResponses.present?
result_hash = {
IndividualResponses: construct_individual_response(payload.IndividualResponses.IndividualResponses)
}
end

Success(result_hash)
end

def validate_rrv_medicare_response(response_hash)
result = ::AcaEntities::Fdsh::Rrv::Medicare::EesDshBatchResponseDataContract.new.call(response_hash)

if result.success?
Success(result)
else
Failure("Invalid response, #{result.errors.to_h}")
end
end

def create_rrv_medicare_response(value)
Success(::AcaEntities::Fdsh::Rrv::Medicare::EesDshBatchResponseData.new(value.to_h))
end

def construct_individual_response(individual_responses)
individual_responses.collect do |response|
{
PersonSSNIdentification: response.PersonSSNIdentification,
Insurances: construct_insurances(response.Insurances),
OrganizationResponseCode: response.OrganizationResponseCode,
OrganizationResponseCodeText: response.OrganizationResponseCodeText
}

end
end

def construct_insurances(insurances)
insurances.collect do |insurance|
insurance_hash = {}

insurance_hash.merge!(InsuranceEffectiveDate: insurance.InsuranceEffectiveDate) if insurance.InsuranceEffectiveDate.present?
insurance_hash.merge!(InsuranceEndDate: insurance.InsuranceEndDate) if insurance.InsuranceEndDate.present?

insurance_hash
end
end
end
end
end
end
end
Loading

0 comments on commit 153acde

Please sign in to comment.