Class: DdeClient::MergingService

Inherits:
Object
  • Object
show all
Includes:
ModelUtils
Defined in:
app/services/dde_client/merging_service.rb

Overview

An extension to the DdeService that provides merging functionality for local patients and remote patients

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ModelUtils

#concept, #concept_id_to_name, #concept_name, #concept_name_to_id, #drug, #encounter_type, #global_property, #order_type, #patient_identifier_type, #report_type, #user_property, #visit_type

Constructor Details

#initialize(parent, dde_client) ⇒ MergingService

Initialise Dde’s merging service.

Parameters:

parent: Is the parent Dde service
dde_client: Is a configured Dde client


15
16
17
18
# File 'app/services/dde_client/merging_service.rb', line 15

def initialize(parent, dde_client)
  @parent = parent
  @dde_client = dde_client
end

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



8
9
10
# File 'app/services/dde_client/merging_service.rb', line 8

def parent
  @parent
end

Instance Method Details

Binds the remote patient to the local patient by blessing the local patient with the remotes npid and doc_id



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'app/services/dde_client/merging_service.rb', line 79

def link_local_to_remote_patient(local_patient, remote_patient)
  return local_patient if local_patient_linked_to_remote?(local_patient, remote_patient)

  national_id_type = patient_identifier_type('National id')
  old_identifier = patient_identifier_type('Old Identification Number')
  doc_id_type = patient_identifier_type('Dde person document id')

  local_patient.patient_identifiers.where(type: [national_id_type, doc_id_type, old_identifier]).each do |identifier|
    # We are now voiding all ids
    # if identifier.identifier_type == national_id_type.id && identifier.identifier.match?(/^\s*P\d{12}\s*$/i)
    #   # We have a v3 NPID that should get demoted to legacy national id
    #   create_local_patient_identifier(local_patient, identifier.identifier, 'Old Identification Number')
    # end

    identifier.void("Assigned new id: #{remote_patient['doc_id']}")
  end

  create_local_patient_identifier(local_patient, remote_patient['doc_id'], 'Dde person document id')
  create_local_patient_identifier(local_patient, find_remote_patient_npid(remote_patient), 'National id')

  local_patient.reload
  local_patient
end

#local_patient_linked_to_remote?(local_patient, remote_patient) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
106
107
108
109
110
111
# File 'app/services/dde_client/merging_service.rb', line 103

def local_patient_linked_to_remote?(local_patient, remote_patient)
  identifier_exists = lambda do |type, value|
    PatientIdentifier.where(patient: local_patient, identifier_type: PatientIdentifierType.where(name: type), identifier: value)
                     .exists?
  end

  identifier_exists['National id',
                    remote_patient['npid']] && identifier_exists['Dde person document id', remote_patient['doc_id']]
end

#merge_local_patients(primary_patient_ids, secondary_patient_ids, merge_type) ⇒ Object

Merges @secondary_patient into @primary_patient. rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/services/dde_client/merging_service.rb', line 50

def merge_local_patients(primary_patient_ids, secondary_patient_ids, merge_type)
  ActiveRecord::Base.transaction do
    primary_patient = Patient.find(primary_patient_ids['patient_id'])
    secondary_patient = Patient.find(secondary_patient_ids['patient_id'])
    merge_name(primary_patient, secondary_patient)
    merge_identifiers(primary_patient, secondary_patient)
    merge_attributes(primary_patient, secondary_patient)
    merge_address(primary_patient, secondary_patient)
    @obs_map = {}
    if female_male_merge?(primary_patient, secondary_patient) && secondary_female?(secondary_patient)
      void_visit_type_encounter(primary_patient, secondary_patient, 'CxCa visit_type')
      void_visit_type_encounter(primary_patient, secondary_patient, 'ANC PROGRAM')
    end
    result = merge_encounters(primary_patient, secondary_patient)
    merge_observations(primary_patient, secondary_patient, result)
    merge_orders(primary_patient, secondary_patient, result)
    merge_visit_types(primary_patient, secondary_patient)
    merge_patient_visits(primary_patient, secondary_patient)
    DdeClient::MergeAuditService.new.create_merge_audit(primary_patient.id, secondary_patient.id, merge_type) if defined?(DdeClient::MergeAuditService)
    secondary_patient.void("Merged into patient ##{primary_patient.id}:0")

    primary_patient
  end
end

#merge_patients(primary_patient_ids, secondary_patient_ids_list) ⇒ Object

Merge secondary patient(s) into primary patient.

Parameters:

primary_patient_ids - An object of them form { 'patient_id' => xxx, 'doc_id' }.
                      One of 'patient_id' and 'doc_id' must be present else an
                      InvalidParametersError be thrown.
secondary_patient_ids_list - An array of objects like that for 'primary_patient_ids'
                             above


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/services/dde_client/merging_service.rb', line 28

def merge_patients(primary_patient_ids, secondary_patient_ids_list)
  secondary_patient_ids_list.collect do |secondary_patient_ids|
    if !dde_enabled?
      merge_local_patients(primary_patient_ids, secondary_patient_ids, 'Local Patients')
    elsif remote_merge?(primary_patient_ids, secondary_patient_ids)
      merge_remote_patients(primary_patient_ids, secondary_patient_ids)
    elsif remote_local_merge?(primary_patient_ids, secondary_patient_ids)
      merge_remote_and_local_patients(primary_patient_ids, secondary_patient_ids, 'Remote and Local Patient')
    elsif inverted_remote_local_merge?(primary_patient_ids, secondary_patient_ids)
      merge_remote_and_local_patients(primary_patient_ids, secondary_patient_ids, 'Remote and Local Patient')
    elsif local_merge?(primary_patient_ids, secondary_patient_ids)
      merge_local_patients(primary_patient_ids, secondary_patient_ids, 'Local Patients')
    else
      raise StandardError,
            "Invalid merge parameters: primary => #{primary_patient_ids}, secondary => #{secondary_patient_ids}"
    end
  end.first
end