diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c093ed2..f8eb4e8 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,14 +3,20 @@ + + + + + - + - - + + + + + + + + + + + + + + + + @@ -192,46 +220,17 @@ - file://$PROJECT_DIR$/app/controllers/health_care_provider_controller.rb - 12 + file://$PROJECT_DIR$/app/controllers/notifications_controller.rb + 46 - - - file://$PROJECT_DIR$/app/helpers/insurance_helper.rb - 38 - - - - - file://$PROJECT_DIR$/app/helpers/central_entity_helper.rb - 20 - - - - - file://$PROJECT_DIR$/app/helpers/notification_helper.rb - 5 - - - - - file://$PROJECT_DIR$/app/controllers/consents_controller.rb - 16 - - + \ No newline at end of file diff --git a/app/controllers/consents_controller.rb b/app/controllers/consents_controller.rb index 07dd9e4..043e4ef 100644 --- a/app/controllers/consents_controller.rb +++ b/app/controllers/consents_controller.rb @@ -14,9 +14,9 @@ def show end def approve_consent - @consent = Consent.create(consultation_id: params[:consultation_id], person_id: params[:person_id], registered_on: Time.now) - notification = Notification.find_by(id: params[:notification_id]) - notification.update(notification_type: Notification::TYPE["NOTICE"], data: @notification.data + " Approved") + @consent = Consent.create(consultation_id: params[:consultation_id].to_i, person_id: params[:person_id].to_i, registered_on: Time.now) + # notification = Notification.find_by(id: params[:notification_id].to_i) + # notification.update(notification_type: Notification::TYPE["NOTICE"], data: notification.data + "has been Approved by you.") render json: @consent end diff --git a/app/controllers/health_care_provider_controller.rb b/app/controllers/health_care_provider_controller.rb index 3c28d38..8490b77 100644 --- a/app/controllers/health_care_provider_controller.rb +++ b/app/controllers/health_care_provider_controller.rb @@ -14,7 +14,7 @@ def check_eligibility render json: resp rescue StandardError => e puts(e.message) - render json: {msg: "Bad request"} + render json: {msg: "no data available", is_eligible: false} end def send_pre_auth_request @@ -32,17 +32,17 @@ def send_pre_auth_request end def update_docs_and_send_claim_request - claim_id = params[:claim_id] - amount = params[:amount] - claim_type = params[:claim_type] + claim_id = params[:claim_id].to_i + amount = params[:amount].to_i + claim_type = params[:claim_type].to_s health_id = params["health_id"].to_s customer = Person.find_by_health_id(health_id) eligibility = CentralEntityHelper.get_eligibility(amount, claim_type, customer.id) resp = InsuranceHelper.send_claim_request(claim_id, amount, eligibility) claim = Claim.find_by(id: claim_id) - ConsultationHelper.add_data_to_consultation(params[:prescriptions], params[:invoices], [claim], params[:consultation_id]) + ConsultationHelper.add_data_to_consultation(params[:prescriptions], params[:invoices], [claim], claim.consultation_id) #todo: debug low priority why above line wasn't working - consultation = Consultation.find_by(id: params[:consultation_id]) + consultation = claim.consultation CentralEntityHelper.add_data_to_health_record(consultation, customer.id) render json: resp rescue StandardError => e diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index e92581c..b90cba6 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -1,5 +1,5 @@ class NotificationsController < ApplicationController - before_action :set_notification, only: %i[ show update destroy ] + before_action :set_notification, only: %i[ show update destroy approve_notification] # GET /notifications?person_id def index @@ -42,6 +42,18 @@ def destroy @notification.destroy end + def approve_notification + notification_id = params[:id] + approval = params[:approval] # boolean (true/false) + consultation = @notification.consultation + Consent.create(consultation_id: consultation.id, person_id: @notification.person_id, registered_on: Time.now) + if approval + @notification.update(notification_type: Notification::TYPE["NOTICE"], data: @notification.data + " Approved") + else + @notification.update(notification_type: Notification::TYPE["NOTICE"], data: @notification.data + " Rejected") + end + end + private # Use callbacks to share common setup or constraints between actions. def set_notification diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 077b149..1882ece 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -38,8 +38,6 @@ def destroy @person.destroy end - - private # Use callbacks to share common setup or constraints between actions. def set_person diff --git a/app/helpers/central_entity_helper.rb b/app/helpers/central_entity_helper.rb index 4e47e78..63312cf 100644 --- a/app/helpers/central_entity_helper.rb +++ b/app/helpers/central_entity_helper.rb @@ -6,10 +6,10 @@ def get_eligibility(claim_amount, claim_type, customer_id) return { is_eligible: false } unless health_report health_report.insurance_policies.each do |policy| if policy.covers.include?(claim_type.downcase) && claim_amount <= policy.coverage.to_i - return { eligible_policy_id: policy.id, max_coverage_left: policy.coverage, is_eligible: true } + return { eligible_policy_id: policy.id, max_coverage_left: policy.coverage, is_eligible: true, requester: policy.insurer} end end - { is_eligible: false } + { is_eligible: false, msg: "claim limit exceeds coverage" } # get uhid of customer # get health record # check insurances and it's active status diff --git a/app/helpers/consultation_helper.rb b/app/helpers/consultation_helper.rb index 226850d..3655510 100644 --- a/app/helpers/consultation_helper.rb +++ b/app/helpers/consultation_helper.rb @@ -17,7 +17,7 @@ def add_data_to_consultation(new_prescriptions, new_invoices, new_claims, consul claims << nc end end - consultation.update(invoices: invoices, prescriptions: prescriptions, claims: claims) + consultation.update(invoices: invoices, prescriptions: prescriptions, claims: claims, status: 'completed') return consultation end diff --git a/app/helpers/insurance_helper.rb b/app/helpers/insurance_helper.rb index 0df7bdf..8df8011 100644 --- a/app/helpers/insurance_helper.rb +++ b/app/helpers/insurance_helper.rb @@ -8,8 +8,15 @@ class << self def process_pre_auth(requester_id, customer_id, eligibility) health_report = HealthReport.find_by_person_id(customer_id) # create new consultation at time of pre-auth - consultation = Consultation.create(health_report: health_report) - #todo: stitch some mechanism to create consent when notification is approved or just create consent from seeds + existing_consultations = health_report.consultations || [] + consultation = nil + existing_consultations.each do |ec| + if ec.status == 'pre-auth-approved' + consultation = ec + break + end + end + consultation = Consultation.create(health_report: health_report, status: 'pre-auth-approved') if consultation.nil? consent = Consent.find_by(person_id: customer_id, consultation_id: consultation.id) #todo: comment next line # consent = Consent.create(consultation: consultation, person_id: customer_id, registered_on: Time.now) @@ -17,12 +24,21 @@ def process_pre_auth(requester_id, customer_id, eligibility) if consent && (Time.now-1.day..Time.now+2.days).cover?(consent.registered_on) # health_report = HealthReport.find_by_person_id(customer_id) eligible_policy_id = eligibility[:eligible_policy_id] - claim = Claim.create(status: "pre-auth-approved", person_id: customer_id, insurance_policy_id: eligible_policy_id, consultation_id: consultation.id) + existing_claims = consultation.claims || [] + claim = nil + existing_claims.each do |ec| + if ec.status == 'pre-auth-approved' + claim = ec + break + end + end + claim = Claim.create(status: "pre-auth-approved", person_id: customer_id, insurance_policy_id: eligible_policy_id, consultation_id: consultation.id) if claim.nil? return { "success": true, "claim_id": claim.id, "consultation_id": consultation.id, msg: "Pre auth claim registered successfully" } else NotificationHelper.send_notification(requester_id, customer_id, "Pre Auth Request", consultation.id, "CONSENT") # send notification - return { "success": false, "msg": "Consent pending fom customer" } + claim = Claim.find_by(consultation_id: consultation.id, status: "pre-auth-approved") + return { "success": false, "msg": "Consent pending fom customer", "claim_id": claim&.id, "consultation_id": consultation.id } end end @@ -40,20 +56,24 @@ def send_claim_request(claim_id, amount, eligibility) if !claim || claim.status != 'pre-auth-approved' return {"success": false, msg: "customer not authorised, invalid claim status"} end + fraud_response = nil if eligibility[:is_eligible] updateClaimStatus("processing", claim) insured_policy = InsurancePolicy.find_by_id(eligibility[:eligible_policy_id]) is_fraud = false # todo: replace with gpt call - unless is_fraud + medical_report = ClaimReportGenerator.new(claim.person_id).generate + fraud_response = FraudDetectionService.detect(medical_report) + if fraud_response[:approved] == "Yes" updateClaimStatus("approved", claim) updated_coverage = insured_policy.coverage - amount insured_policy.update(coverage: updated_coverage) NotificationHelper.send_notification(insured_policy.insurer, claim.person_id, "Claim of Rs." + (amount.to_s) +" approved", claim.consultation_id, "NOTICE") - return {"success": true, "msg": "Claim processed successfully"} + return {"success": true, "msg": "Claim processed successfully", fraud_detector_response: fraud_response} end end updateClaimStatus("rejected", claim) - NotificationHelper.send_notification(insured_policy.insurer, claim.person_id, "Claim of Rs." + amount +" rejected", claim.consultation_id, "NOTICE") + NotificationHelper.send_notification(insured_policy.insurer, claim.person_id, "Claim of Rs." + (amount.to_s) +" rejected", claim.consultation_id, "NOTICE") + return {"success": false, "msg": "Claim rejected", fraud_detector_response: (fraud_response || {"summary": "Not eligible for claim"})} end private diff --git a/app/services/claim_report_generator.rb b/app/services/claim_report_generator.rb index fdd2202..6dd643f 100644 --- a/app/services/claim_report_generator.rb +++ b/app/services/claim_report_generator.rb @@ -44,9 +44,9 @@ def insurance_claim_history @claims.each_with_index do |claim, index| claim_data = CLAIM_HISTORY_TEMPLATE % { index: index + 1, - year_of_claim: claim.date_of_service.year, + year_of_claim: claim.date_of_service&.year, insurance_provider: claim.insurance_policy.insurer, - date_of_claim: claim.date_of_service.strftime("%b %d, %Y"), + date_of_claim: claim.date_of_service&.strftime("%b %d, %Y"), health_care_provider: claim.provider, diagnosis: claim.diagnosis, procedure: claim.procedure, diff --git a/app/services/fraud_detection_service.rb b/app/services/fraud_detection_service.rb index fec83da..041fde7 100644 --- a/app/services/fraud_detection_service.rb +++ b/app/services/fraud_detection_service.rb @@ -1,7 +1,6 @@ class FraudDetectionService # TODO: add env variable @@client = OpenAI::Client.new(access_token: ENV.fetch("OPEN_AI_TOKEN")) - binding.pry MODEL = "gpt-3.5-turbo" @@ -70,4 +69,34 @@ def self.detect(medical_history) # result[:success] = !(result[:approved].nil? || result[:confidence].nil? || result[:summary].nil?) # return result end + + def self.mock_response_success(medical_history) + return { + success: true, + approved: "Yes", + confidence: "0.99", + summary: "This is approved as it is mocked", + error_message: "" + } + end + + def self.mock_response_error(medical_history) + return { + success: false, + approved: nil, + confidence: nil, + summary: nil, + error_message: "Mocked error" + } + end + + def self.mock_response_fail(medical_history) + return { + success: true, + approved: "No", + confidence: "0.99", + summary: "This is rejected as it is mocked", + error_message: "" + } + end end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 512d8f2..4ce5f74 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,4 +19,5 @@ # # post '/approve_consent', to: "consents#approve_consent" + post '/notification/:id/approve', to: "notifications#approve_notification" end diff --git a/db/migrate/20230528035801_add_status_to_consultation.rb b/db/migrate/20230528035801_add_status_to_consultation.rb new file mode 100644 index 0000000..c79ebb1 --- /dev/null +++ b/db/migrate/20230528035801_add_status_to_consultation.rb @@ -0,0 +1,5 @@ +class AddStatusToConsultation < ActiveRecord::Migration[7.0] + def change + add_column :consultations, :status, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ee12b0b..3dc0d7d 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[7.0].define(version: 2023_05_27_235615) do +ActiveRecord::Schema[7.0].define(version: 2023_05_28_035801) do create_table "claim_status_histories", force: :cascade do |t| t.integer "claim_id" t.string "transition_from" @@ -56,6 +56,7 @@ t.integer "health_report_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "status" t.index ["health_report_id"], name: "index_consultations_on_health_report_id" end