openmrs_data_sanitizer 1.0.6 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40a55f5fb47f9307da0c2e0a5905f5554dee6688c1f4abf09889c4a7852fca95
|
4
|
+
data.tar.gz: 18ebfa45e8aefdd2fd3bf0cab02d0187ba9d3ac16e4f37e50a9de982cacd4e6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6db161bf332f91467f74e8f489cc536d06aac21689dc8114e296d70fbb1851d25a58face6b05141634d74806bbd9ea03a17d509ba87e8605e22a94795c8902fd
|
7
|
+
data.tar.gz: 9b0dfacd32c8bbbf5d9154bcf1402878e279bbf756ee37300d179e8d456d43b589ba857af87156619372679c798c713eae2505b42d671ed185db8c9b4884a1f1
|
@@ -681,7 +681,7 @@ module OpenmrsDataSanitizer
|
|
681
681
|
FROM #{schema}.encounter e
|
682
682
|
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id AND obs.voided = 0 AND obs.concept_id = 5090 -- Height concept_id
|
683
683
|
WHERE e.voided = 0 and e.encounter_type = 6 and e.program_id = 1
|
684
|
-
GROUP BY
|
684
|
+
GROUP BY e.patient_id, DATE(obs.obs_datetime);
|
685
685
|
SQL
|
686
686
|
end
|
687
687
|
|
@@ -694,7 +694,7 @@ module OpenmrsDataSanitizer
|
|
694
694
|
AND obs.voided = 0
|
695
695
|
AND obs.concept_id = 5089
|
696
696
|
WHERE e.voided = 0 and e.encounter_type = 6 and e.program_id = 1
|
697
|
-
GROUP BY
|
697
|
+
GROUP BY e.patient_id, DATE(obs.obs_datetime);
|
698
698
|
SQL
|
699
699
|
end
|
700
700
|
|
@@ -808,37 +808,35 @@ module OpenmrsDataSanitizer
|
|
808
808
|
AND obs.voided = 0
|
809
809
|
AND obs.concept_id = 5096
|
810
810
|
WHERE e.voided = 0 and e.encounter_type = 7 and e.program_id = 1
|
811
|
-
GROUP BY
|
811
|
+
GROUP BY e.patient_id, DATE(obs.obs_datetime);
|
812
812
|
SQL
|
813
813
|
end
|
814
814
|
|
815
815
|
def insert_data_sanitizer_arv_medication
|
816
816
|
ActiveRecord::Base.connection.execute <<~SQL
|
817
817
|
INSERT INTO #{schema}.data_sanitizer_arv_medication (patient_id, order_id, visit_date, drug_runout_date, num_unique_arvs, unique_arvs_given, drug_names)
|
818
|
-
SELECT
|
818
|
+
SELECT o.patient_id, o.order_id, DATE(o.start_date) AS visit_date, DATE(MIN(o.auto_expire_date)) AS drug_runout_date,
|
819
819
|
COUNT(DISTINCT d.drug_id) AS num_unique_arvs,GROUP_CONCAT(DISTINCT d.drug_id SEPARATOR ', ') AS unique_arvs_given,
|
820
820
|
GROUP_CONCAT(DISTINCT d.name SEPARATOR ', ') AS drug_names
|
821
821
|
FROM #{schema}.orders o
|
822
822
|
INNER JOIN #{schema}.drug_order da ON da.order_id = o.order_id AND o.voided = 0 AND da.quantity > 0
|
823
823
|
INNER JOIN #{schema}.drug d ON d.drug_id = da.drug_inventory_id
|
824
|
-
INNER JOIN #{schema}.
|
825
|
-
INNER JOIN #{schema}.encounter e ON e.program_id = 1 AND e.encounter_id = obs.encounter_id AND e.encounter_type = 54
|
824
|
+
INNER JOIN #{schema}.encounter e ON e.program_id = 1 AND e.encounter_id = o.encounter_id AND e.encounter_type = 54
|
826
825
|
INNER JOIN #{schema}.arv_drug ON arv_drug.drug_id = d.drug_id
|
827
|
-
GROUP BY
|
826
|
+
GROUP BY o.patient_id, DATE(o.start_date);
|
828
827
|
SQL
|
829
828
|
end
|
830
829
|
|
831
830
|
def insert_data_sanitizer_arv_orders
|
832
831
|
ActiveRecord::Base.connection.execute <<~SQL
|
833
832
|
INSERT INTO #{schema}.data_sanitizer_arv_orders(patient_id, order_id, encounter_id, visit_date, drug_id, drug_name, units, equivalent_daily_dose, instructions, start_date, runout_date, quantity)
|
834
|
-
SELECT
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
INNER JOIN #{schema}.
|
839
|
-
INNER JOIN #{schema}.
|
840
|
-
|
841
|
-
GROUP BY d.drug_id, o.order_id, m.visit_date;
|
833
|
+
SELECT e.patient_id, o.order_id, o.encounter_id, DATE(o.start_date) AS visit_date, da.drug_inventory_id AS drug_id, d.name AS drug_name, d.units, da.equivalent_daily_dose, o.instructions, DATE(o.start_date), DATE(o.auto_expire_date), da.quantity
|
834
|
+
FROM #{schema}.orders o
|
835
|
+
INNER JOIN #{schema}.encounter e ON e.encounter_id = o.encounter_id AND e.program_id = 1 AND e.voided = 0
|
836
|
+
INNER JOIN #{schema}.drug_order da ON da.order_id = o.order_id AND da.quantity > 0
|
837
|
+
INNER JOIN #{schema}.drug d ON d.drug_id = da.drug_inventory_id
|
838
|
+
INNER JOIN #{schema}.arv_drug ad ON ad.drug_id = d.drug_id
|
839
|
+
WHERE o.voided = 0
|
842
840
|
SQL
|
843
841
|
end
|
844
842
|
|
@@ -13,13 +13,14 @@ module OpenmrsDataSanitizer
|
|
13
13
|
# rubocop:disable Metrics/ClassLength
|
14
14
|
# AWS DataSanitizer
|
15
15
|
class DataSanitizer
|
16
|
-
attr_accessor :regimen_combinations, :concept_names, :faker_names, :sites
|
16
|
+
attr_accessor :regimen_combinations, :concept_names, :faker_names, :sites, :skip
|
17
17
|
|
18
|
-
def initialize(sites: [])
|
18
|
+
def initialize(sites: [], skip: true)
|
19
19
|
@concept_names = Concurrent::Hash.new
|
20
20
|
@faker_names = Concurrent::Hash.new
|
21
21
|
@regimen_combinations = {}
|
22
22
|
@sites = sites
|
23
|
+
@skip = skip
|
23
24
|
load_regimen_combinations
|
24
25
|
end
|
25
26
|
|
@@ -47,7 +48,7 @@ module OpenmrsDataSanitizer
|
|
47
48
|
queue = Queue.new
|
48
49
|
sites.each { |loc| queue << loc }
|
49
50
|
|
50
|
-
threads = Array.new(
|
51
|
+
threads = Array.new(60) do
|
51
52
|
Thread.new do
|
52
53
|
until queue.empty?
|
53
54
|
loc = begin
|
@@ -57,29 +58,24 @@ module OpenmrsDataSanitizer
|
|
57
58
|
end
|
58
59
|
next unless loc
|
59
60
|
|
60
|
-
thread_variables # Set thread variables before processing
|
61
61
|
process_location(loc) # Process location
|
62
|
-
write_data_to_files # Write data to files
|
63
|
-
clear_thread_variables # Clear thread variables after processing
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
68
66
|
threads.each(&:join)
|
67
|
+
close_files
|
69
68
|
end
|
70
69
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
Thread.current[:fhir_observations] = nil
|
81
|
-
Thread.current[:fhir_medication_dispense] = nil
|
82
|
-
Thread.current[:patients_json] = nil
|
70
|
+
def close_files
|
71
|
+
dir_path = Rails.root.join('log/openmrs_data_sanitizer')
|
72
|
+
file_path = dir_path.join('*.json')
|
73
|
+
Dir[file_path].each do |file|
|
74
|
+
# Remove trailing comma and append closing bracket
|
75
|
+
system("sed -i '$s/,$/]/' #{file}")
|
76
|
+
# Log the file closure
|
77
|
+
Rails.logger.info "Closed file: #{file}"
|
78
|
+
end
|
83
79
|
end
|
84
80
|
|
85
81
|
def process_location(loc)
|
@@ -90,7 +86,7 @@ module OpenmrsDataSanitizer
|
|
90
86
|
site_name = site['facility']
|
91
87
|
schema = site['schema']
|
92
88
|
|
93
|
-
OpenmrsDataSanitizer::DataAggregator.new(schema:).aggregate
|
89
|
+
OpenmrsDataSanitizer::DataAggregator.new(schema:).aggregate unless skip
|
94
90
|
|
95
91
|
process_patients(schema, site_name)
|
96
92
|
rescue StandardError => e
|
@@ -109,13 +105,6 @@ module OpenmrsDataSanitizer
|
|
109
105
|
process_medication(schema:)
|
110
106
|
end
|
111
107
|
|
112
|
-
def write_data_to_files
|
113
|
-
write_to_file(Thread.current[:patients_json].to_json, 'patients') unless Thread.current[:patients_json].blank?
|
114
|
-
write_to_file(Thread.current[:fhir_encounters].to_json, 'visits') unless Thread.current[:fhir_encounters].blank?
|
115
|
-
write_to_file(Thread.current[:fhir_observations].to_json, 'observations') unless Thread.current[:fhir_observations].blank?
|
116
|
-
write_to_file(Thread.current[:fhir_medication_dispense].to_json, 'medications') unless Thread.current[:fhir_medication_dispense].blank?
|
117
|
-
end
|
118
|
-
|
119
108
|
# ===================================
|
120
109
|
# REGION: REGIMEN COMBINATIONS
|
121
110
|
# ===================================
|
@@ -156,14 +145,14 @@ module OpenmrsDataSanitizer
|
|
156
145
|
|
157
146
|
# rubocop:disable Metrics/AbcSize
|
158
147
|
def build_patient_json(patient, site_name)
|
159
|
-
patient_id = patient['
|
160
|
-
village_name = get_or_generate_faker_value(patient['village_name'], Faker::Address, :community)
|
161
|
-
cell_number = get_or_generate_faker_value(patient['phone_number'], Faker::PhoneNumber, :phone_number)
|
162
|
-
family_name = get_or_generate_faker_value(patient['family_name'], Faker::Name, :last_name)
|
163
|
-
given_name = get_or_generate_faker_value(patient['given_name'], Faker::Name, :first_name)
|
164
|
-
middle_name = get_or_generate_faker_value(patient['middle_name'], Faker::Name, :middle_name)
|
165
|
-
|
166
|
-
|
148
|
+
patient_id = patient['patient_id'].to_i
|
149
|
+
village_name = get_or_generate_faker_value(patient['village_name']&.titlecase, Faker::Address, :community)
|
150
|
+
cell_number = get_or_generate_faker_value(patient['phone_number']&.titlecase, Faker::PhoneNumber, :phone_number)
|
151
|
+
family_name = get_or_generate_faker_value(patient['family_name']&.titlecase, Faker::Name, :last_name)
|
152
|
+
given_name = get_or_generate_faker_value(patient['given_name']&.titlecase, Faker::Name, :first_name)
|
153
|
+
middle_name = get_or_generate_faker_value(patient['middle_name']&.titlecase, Faker::Name, :middle_name)
|
154
|
+
|
155
|
+
fhir_patient = FHIR::Patient.new(
|
167
156
|
id: patient_id,
|
168
157
|
identifier: [{ system: "#{site_name}_#{patient_id}", value: patient_id }],
|
169
158
|
name: [{ use: 'official', family: family_name, given: [given_name, middle_name] }],
|
@@ -172,6 +161,7 @@ module OpenmrsDataSanitizer
|
|
172
161
|
address: [{ use: 'home', village: village_name }],
|
173
162
|
telecom: [{ system: 'phone', value: cell_number, use: 'mobile' }]
|
174
163
|
)
|
164
|
+
write_to_file(fhir_patient.to_json, 'patients') unless fhir_patient.blank?
|
175
165
|
end
|
176
166
|
|
177
167
|
def fetch_gender(gender:)
|
@@ -213,10 +203,11 @@ module OpenmrsDataSanitizer
|
|
213
203
|
|
214
204
|
def aws_fhir_encounter(visit:, regimen:)
|
215
205
|
patient_id = visit['patient_id'].to_i
|
216
|
-
|
206
|
+
fhir_encounter = create_fhir_encounter(patient_id, visit['visit_date'])
|
207
|
+
write_to_file(fhir_encounter.to_json, 'visits') unless fhir_encounter.blank?
|
217
208
|
|
218
209
|
observations = process_indicators(visit, regimen)
|
219
|
-
create_fhir_observations(observations, patient_id, visit['visit_date'])
|
210
|
+
create_fhir_observations(observations, patient_id, visit['visit_date'], fhir_encounter.id)
|
220
211
|
end
|
221
212
|
|
222
213
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
@@ -276,11 +267,11 @@ module OpenmrsDataSanitizer
|
|
276
267
|
end
|
277
268
|
|
278
269
|
# rubocop:disable Metrics/PerceivedComplexity
|
279
|
-
def create_fhir_observations(observations, patient_id, visit_date)
|
270
|
+
def create_fhir_observations(observations, patient_id, visit_date, encounter_id)
|
280
271
|
observations.each do |obs|
|
281
272
|
next if obs.blank? || obs[:code].blank? || obs[:value].blank?
|
282
273
|
|
283
|
-
|
274
|
+
fhir_obs = FHIR::Observation.new(
|
284
275
|
status: 'final',
|
285
276
|
code: {
|
286
277
|
coding: [
|
@@ -295,20 +286,19 @@ module OpenmrsDataSanitizer
|
|
295
286
|
reference: "Patient/#{patient_id}"
|
296
287
|
},
|
297
288
|
encounter: {
|
298
|
-
reference: "Encounter/#{
|
289
|
+
reference: "Encounter/#{encounter_id}"
|
299
290
|
},
|
300
291
|
effectiveDateTime: visit_date
|
301
292
|
)
|
302
|
-
|
303
293
|
if obs[:unit]
|
304
|
-
|
294
|
+
fhir_obs.valueQuantity = {
|
305
295
|
value: obs[:value],
|
306
296
|
unit: obs[:unit],
|
307
297
|
system: 'EGPAF Malawi EMR',
|
308
298
|
code: obs[:code]
|
309
299
|
}
|
310
300
|
else
|
311
|
-
|
301
|
+
fhir_obs.valueCodeableConcept = {
|
312
302
|
coding: [
|
313
303
|
{
|
314
304
|
system: 'EGPAF Malawi EMR',
|
@@ -322,6 +312,7 @@ module OpenmrsDataSanitizer
|
|
322
312
|
]
|
323
313
|
}
|
324
314
|
end
|
315
|
+
write_to_file(fhir_obs.to_json, 'observations') unless fhir_obs.blank?
|
325
316
|
end
|
326
317
|
end
|
327
318
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength, Metrics/PerceivedComplexity
|
@@ -343,8 +334,8 @@ module OpenmrsDataSanitizer
|
|
343
334
|
|
344
335
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/BlockLength
|
345
336
|
def create_fhir_medications(orders:)
|
346
|
-
|
347
|
-
FHIR::MedicationDispense.new(
|
337
|
+
(orders || []).each do |order|
|
338
|
+
fhir_med = FHIR::MedicationDispense.new(
|
348
339
|
identifier: {
|
349
340
|
value: order['order_id'].to_i
|
350
341
|
},
|
@@ -386,6 +377,7 @@ module OpenmrsDataSanitizer
|
|
386
377
|
}
|
387
378
|
}
|
388
379
|
)
|
380
|
+
write_to_file(fhir_med.to_json, 'medications') unless fhir_med.blank?
|
389
381
|
end
|
390
382
|
end
|
391
383
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/BlockLength
|
@@ -420,14 +412,15 @@ module OpenmrsDataSanitizer
|
|
420
412
|
|
421
413
|
# Use the mutex to handle concurrent writes
|
422
414
|
FILE_MUTEX.synchronize do
|
423
|
-
if File.exist?(file_path)
|
424
|
-
|
425
|
-
|
426
|
-
|
415
|
+
if !File.exist?(file_path)
|
416
|
+
File.open(file_path, 'w') do |out_file|
|
417
|
+
out_file.puts('[')
|
418
|
+
Rails.logger.info "Created file: #{file_path}"
|
419
|
+
end
|
427
420
|
end
|
428
421
|
|
429
422
|
File.open(file_path, 'a') do |out_file|
|
430
|
-
out_file.puts(json_file)
|
423
|
+
out_file.puts("#{json_file},")
|
431
424
|
Rails.logger.info "Appended to file: #{file_path}"
|
432
425
|
end
|
433
426
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openmrs_data_sanitizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mwatha
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
142
|
- !ruby/object:Gem::Version
|
143
143
|
version: '0'
|
144
144
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
145
|
+
rubygems_version: 3.4.1
|
146
146
|
signing_key:
|
147
147
|
specification_version: 4
|
148
148
|
summary: This gem will mask all patient identifyable data before exporting to AWS
|