openmrs_data_sanitizer 1.0.3 → 1.0.4
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: 871a8c260924d6911e5ed550ad158e3914d10eab5a93fc473bb37d56bcbcc641
|
4
|
+
data.tar.gz: 9af6e3f50d1beec93f505cedacaf0722bc66d4dacb69dbc3c6104166a7c333c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8117cb24ce418d40e297585b23d0d5f675af86290067a6d484dee81fe0a6a85fc3f3a62b2c383fc55983120269ea702182906368b9ddd795737861183e9253ee
|
7
|
+
data.tar.gz: 8a145dc8da6d99a3ec3ae2287a5a44927a187c580b405d109d639f0385e340e9fa605512e06ba94f6ebf48e4b07695dddbb91bd8bbca78d7ff7e13e1b64e913a
|
@@ -95,7 +95,7 @@ module OpenmrsDataSanitizer
|
|
95
95
|
drop_data_sanitizer_encounter_dates_table
|
96
96
|
create_data_sanitizer_encounter_dates_table
|
97
97
|
end
|
98
|
-
if count_table_columns('data_sanitizer_patient_outcomes') !=
|
98
|
+
if count_table_columns('data_sanitizer_patient_outcomes') != 6
|
99
99
|
drop_data_sanitizer_patient_outcomes_table
|
100
100
|
create_data_sanitizer_patient_outcomes_table
|
101
101
|
end
|
@@ -108,17 +108,22 @@ module OpenmrsDataSanitizer
|
|
108
108
|
drop_data_sanitizer_patient_reason_for_starting_table
|
109
109
|
create_data_sanitizer_patient_reason_for_starting_table
|
110
110
|
end
|
111
|
-
if count_table_columns('data_sanitizer_patient_detailed_side_effects') !=
|
111
|
+
if count_table_columns('data_sanitizer_patient_detailed_side_effects') != 24
|
112
112
|
drop_data_sanitizer_patient_detailed_side_effects_table
|
113
113
|
create_data_sanitizer_patient_detailed_side_effects_table
|
114
114
|
end
|
115
|
-
|
115
|
+
if count_table_columns('data_sanitizer_patients') != 8
|
116
|
+
drop_data_sanitizer_patients_table
|
117
|
+
create_data_sanitizer_patients_table
|
118
|
+
end
|
119
|
+
return unless count_table_columns('data_sanitizer_visits') != 37
|
116
120
|
|
117
121
|
drop_data_sanitizer_visits_table
|
118
122
|
create_data_sanitizer_visits_table
|
119
123
|
end
|
120
124
|
|
121
125
|
def process_data
|
126
|
+
insert_data_sanitizer_patients
|
122
127
|
insert_data_sanitizer_patients_height
|
123
128
|
insert_data_sanitizer_patients_weight
|
124
129
|
insert_data_sanitizer_patient_present
|
@@ -144,7 +149,7 @@ module OpenmrsDataSanitizer
|
|
144
149
|
data_sanitizer_side_effect data_sanitizer_adherence data_sanitizer_appointment
|
145
150
|
data_sanitizer_arv_medication data_sanitizer_arv_orders data_sanitizer_encounter_dates
|
146
151
|
data_sanitizer_patient_outcomes data_sanitizer_patient_who_stage data_sanitizer_patient_reason_for_starting
|
147
|
-
data_sanitizer_patient_detailed_side_effects data_sanitizer_visits ]
|
152
|
+
data_sanitizer_patient_detailed_side_effects data_sanitizer_visits data_sanitizer_patients]
|
148
153
|
table_names.each do |table_name|
|
149
154
|
ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{schema}.#{table_name}")
|
150
155
|
end
|
@@ -415,6 +420,21 @@ module OpenmrsDataSanitizer
|
|
415
420
|
SQL
|
416
421
|
create_data_sanitizer_visits_index
|
417
422
|
end
|
423
|
+
|
424
|
+
def create_data_sanitizer_patients_table
|
425
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
426
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patients (
|
427
|
+
patient_id INT PRIMARY KEY,
|
428
|
+
given_name VARCHAR(100),
|
429
|
+
middle_name VARCHAR(100),
|
430
|
+
family_name VARCHAR(100),
|
431
|
+
gender VARCHAR(1),
|
432
|
+
birthdate DATE,
|
433
|
+
phone_number VARCHAR(100),
|
434
|
+
village_name VARCHAR(100)
|
435
|
+
);
|
436
|
+
SQL
|
437
|
+
end
|
418
438
|
# rubocop:enable Metrics/MethodLength
|
419
439
|
|
420
440
|
# ========================
|
@@ -527,6 +547,12 @@ module OpenmrsDataSanitizer
|
|
527
547
|
# DATABASE TABLE DELETE METHODS
|
528
548
|
# ========================
|
529
549
|
|
550
|
+
def drop_data_sanitizer_patients_table
|
551
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
552
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patients;
|
553
|
+
SQL
|
554
|
+
end
|
555
|
+
|
530
556
|
def drop_data_sanitizer_patients_height_table
|
531
557
|
ActiveRecord::Base.connection.execute <<~SQL
|
532
558
|
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patients_height;
|
@@ -634,19 +660,28 @@ module OpenmrsDataSanitizer
|
|
634
660
|
# ========================
|
635
661
|
|
636
662
|
# rubocop:disable Metrics/MethodLength
|
663
|
+
def insert_data_sanitizer_patients
|
664
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
665
|
+
INSERT INTO #{schema}.data_sanitizer_patients (patient_id, given_name, middle_name, family_name, gender, birthdate, phone_number, village_name)
|
666
|
+
SELECT p.person_id, n.given_name, n.middle_name, n.family_name, IF(p.gender is NULL, 'U', LEFT(p.gender,1)), p.birthdate, phone.value, village.value
|
667
|
+
FROM #{schema}.person p
|
668
|
+
INNER JOIN #{schema}.patient ON patient.patient_id = p.person_id AND p.voided = 0
|
669
|
+
LEFT JOIN #{schema}.person_name n ON n.person_id = p.person_id AND n.voided = 0
|
670
|
+
LEFT JOIN #{schema}.person_attribute phone ON phone.person_id = p.person_id AND phone.voided = 0 AND phone.person_attribute_type_id = 12
|
671
|
+
LEFT JOIN #{schema}.person_attribute village ON village.person_id = p.person_id AND village.voided = 0 AND village.person_attribute_type_id = 19
|
672
|
+
WHERE p.voided = 0
|
673
|
+
GROUP BY p.person_id;
|
674
|
+
SQL
|
675
|
+
end
|
676
|
+
|
637
677
|
def insert_data_sanitizer_patients_height
|
638
678
|
ActiveRecord::Base.connection.execute <<~SQL
|
639
679
|
INSERT INTO #{schema}.data_sanitizer_patients_height (patient_id, height, visit_date)
|
640
680
|
SELECT e.patient_id, ROUND(obs.value_numeric), DATE(obs.obs_datetime) visit_date
|
641
681
|
FROM #{schema}.encounter e
|
642
|
-
INNER JOIN #{schema}.obs ON e.
|
643
|
-
|
644
|
-
|
645
|
-
AND e.program_id = 1
|
646
|
-
AND obs.voided = 0
|
647
|
-
AND obs.concept_id = 5090 -- Height concept_id
|
648
|
-
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
649
|
-
ORDER BY obs_datetime DESC;
|
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
|
+
WHERE e.voided = 0 and e.encounter_type = 6 and e.program_id = 1
|
684
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
650
685
|
SQL
|
651
686
|
end
|
652
687
|
|
@@ -655,14 +690,11 @@ module OpenmrsDataSanitizer
|
|
655
690
|
INSERT INTO #{schema}.data_sanitizer_patients_weight (patient_id, weight, visit_date)
|
656
691
|
SELECT e.patient_id, ROUND(obs.value_numeric), DATE(obs.obs_datetime) visit_date
|
657
692
|
FROM #{schema}.encounter e
|
658
|
-
INNER JOIN #{schema}.obs ON e.
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
AND obs.concept_id = 5089
|
664
|
-
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
665
|
-
ORDER BY obs_datetime DESC;
|
693
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
694
|
+
AND obs.voided = 0
|
695
|
+
AND obs.concept_id = 5089
|
696
|
+
WHERE e.voided = 0 and e.encounter_type = 6 and e.program_id = 1
|
697
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
666
698
|
SQL
|
667
699
|
end
|
668
700
|
|
@@ -673,14 +705,11 @@ module OpenmrsDataSanitizer
|
|
673
705
|
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS patient_present,
|
674
706
|
DATE(obs.obs_datetime) visit_date
|
675
707
|
FROM #{schema}.encounter e
|
676
|
-
INNER JOIN #{schema}.obs ON e.
|
677
|
-
AND e.voided = 0
|
678
|
-
AND e.encounter_type = 51
|
679
|
-
AND e.program_id = 1
|
708
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
680
709
|
AND obs.voided = 0
|
681
710
|
AND obs.concept_id = 1805
|
682
|
-
|
683
|
-
|
711
|
+
WHERE e.voided = 0 and e.encounter_type = 51 and e.program_id = 1
|
712
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
684
713
|
SQL
|
685
714
|
end
|
686
715
|
|
@@ -691,16 +720,13 @@ module OpenmrsDataSanitizer
|
|
691
720
|
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS guardian_present,
|
692
721
|
DATE(obs.obs_datetime) visit_date
|
693
722
|
FROM #{schema}.encounter e
|
694
|
-
INNER JOIN #{schema}.obs ON e.
|
695
|
-
|
696
|
-
|
697
|
-
AND e.program_id = 1
|
698
|
-
AND obs.voided = 0
|
699
|
-
AND obs.concept_id = 6794
|
723
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
724
|
+
AND obs.voided = 0
|
725
|
+
AND obs.concept_id = 6794
|
700
726
|
INNER JOIN #{schema}.person ON person.person_id = obs.person_id
|
701
|
-
|
702
|
-
|
703
|
-
|
727
|
+
AND person.gender IN('Female','F')
|
728
|
+
WHERE e.voided = 0 and e.encounter_type = 51 and e.program_id = 1
|
729
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
704
730
|
SQL
|
705
731
|
end
|
706
732
|
|
@@ -711,16 +737,13 @@ module OpenmrsDataSanitizer
|
|
711
737
|
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS pregnant_status,
|
712
738
|
DATE(obs.obs_datetime) visit_date
|
713
739
|
FROM #{schema}.encounter e
|
714
|
-
INNER JOIN #{schema}.obs ON e.
|
715
|
-
|
716
|
-
|
717
|
-
AND e.encounter_type = 53
|
718
|
-
AND obs.voided = 0
|
719
|
-
AND obs.concept_id IN(6131, 1755)
|
740
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
741
|
+
AND obs.voided = 0
|
742
|
+
AND obs.concept_id IN(6131, 1755)
|
720
743
|
INNER JOIN #{schema}.person ON person.person_id = obs.person_id
|
721
|
-
|
722
|
-
|
723
|
-
|
744
|
+
AND person.gender IN('Female','F')
|
745
|
+
WHERE e.voided = 0 and e.encounter_type = 53 and e.program_id = 1
|
746
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
724
747
|
SQL
|
725
748
|
end
|
726
749
|
|
@@ -731,34 +754,28 @@ module OpenmrsDataSanitizer
|
|
731
754
|
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS breastfeeding_status,
|
732
755
|
DATE(obs.obs_datetime) visit_date
|
733
756
|
FROM #{schema}.encounter e
|
734
|
-
INNER JOIN #{schema}.obs ON e.
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
AND obs.concept_id IN(834,5632, 8039,7965)
|
740
|
-
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
741
|
-
ORDER BY obs_datetime DESC;
|
757
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
758
|
+
AND obs.voided = 0
|
759
|
+
AND obs.concept_id IN(834,5632, 8039,7965)
|
760
|
+
WHERE e.voided = 0 and e.encounter_type = 53 and e.program_id = 1
|
761
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
742
762
|
SQL
|
743
763
|
end
|
744
764
|
|
745
765
|
def insert_data_sanitizer_side_effect
|
746
766
|
ActiveRecord::Base.connection.execute <<~SQL
|
747
767
|
INSERT INTO #{schema}.data_sanitizer_side_effect (patient_id, visit_date, concept_id, value_coded, available)
|
748
|
-
SELECT t.person_id,
|
749
|
-
DATE(t.obs_datetime) visit_date,
|
750
|
-
t2.concept_id,
|
751
|
-
t2.value_coded,
|
768
|
+
SELECT t.person_id,DATE(t.obs_datetime) visit_date,t2.concept_id,t2.value_coded,
|
752
769
|
(CASE WHEN t2.value_coded = 1065 THEN 'YES' ELSE 'NO' END) available
|
753
770
|
FROM #{schema}.obs t
|
754
771
|
INNER JOIN #{schema}.obs t2 ON t.concept_id = 7755
|
755
|
-
|
756
|
-
|
757
|
-
|
772
|
+
AND t.obs_id = t2.obs_group_id
|
773
|
+
AND t.voided = 0
|
774
|
+
AND t2.voided = 0
|
758
775
|
INNER JOIN #{schema}.encounter e ON e.encounter_id = t.encounter_id
|
759
|
-
|
760
|
-
|
761
|
-
|
776
|
+
AND e.program_id = 1
|
777
|
+
AND e.encounter_type = 53
|
778
|
+
AND e.voided = 0
|
762
779
|
GROUP BY t.person_id, DATE(t.obs_datetime), t.value_coded, t2.value_coded;
|
763
780
|
SQL
|
764
781
|
end
|
@@ -766,61 +783,46 @@ module OpenmrsDataSanitizer
|
|
766
783
|
def insert_data_sanitizer_adherence
|
767
784
|
ActiveRecord::Base.connection.execute <<~SQL
|
768
785
|
INSERT INTO #{schema}.data_sanitizer_adherence (patient_id, visit_date, adherence)
|
769
|
-
SELECT o.person_id,
|
770
|
-
DATE(o.visit_date) visit_date,
|
786
|
+
SELECT o.person_id, DATE(o.visit_date) visit_date,
|
771
787
|
ROUND(MAX(CASE WHEN (REPLACE(adherence, '%', '')) BETWEEN 95 AND 105 THEN (REPLACE(adherence, '%', '')) ELSE 0 END)) AS adherence
|
772
788
|
FROM (
|
773
789
|
SELECT obs.person_id, DATE(obs_datetime) AS visit_date, IF(value_numeric REGEXP '^[+-]?[0-9]+(\.[0-9]+)?%?$', CAST(REPLACE(value_numeric, '%', '') AS DECIMAL(10, 2)), 0) AS adherence
|
774
790
|
FROM #{schema}.obs
|
775
|
-
INNER JOIN #{schema}.encounter e ON e.
|
776
|
-
AND e.
|
791
|
+
INNER JOIN #{schema}.encounter e ON e.encounter_id = obs.encounter_id
|
792
|
+
AND e.encounter_type = 68
|
777
793
|
AND e.program_id = 1
|
778
794
|
WHERE obs.voided = 0
|
779
795
|
AND obs.concept_id = 6987 -- Drug adherence concept_id
|
780
796
|
AND (obs.value_numeric IS NOT NULL OR obs.value_text IS NOT NULL)
|
781
797
|
) AS o
|
782
798
|
GROUP BY o.person_id, o.visit_date
|
783
|
-
ORDER BY o.person_id, o.visit_date;
|
784
799
|
SQL
|
785
800
|
end
|
786
801
|
|
787
802
|
def insert_data_sanitizer_appointment
|
788
803
|
ActiveRecord::Base.connection.execute <<~SQL
|
789
804
|
INSERT INTO #{schema}.data_sanitizer_appointment (patient_id, value_datetime, visit_date)
|
790
|
-
SELECT e.patient_id,
|
791
|
-
DATE(value_datetime),
|
792
|
-
DATE(obs.obs_datetime) visit_date
|
805
|
+
SELECT e.patient_id, DATE(value_datetime),DATE(obs.obs_datetime) visit_date
|
793
806
|
FROM #{schema}.encounter e
|
794
|
-
INNER JOIN #{schema}.obs ON e.
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
AND obs.concept_id = 5096
|
800
|
-
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
801
|
-
ORDER BY obs_datetime DESC;
|
807
|
+
INNER JOIN #{schema}.obs ON e.encounter_id = obs.encounter_id
|
808
|
+
AND obs.voided = 0
|
809
|
+
AND obs.concept_id = 5096
|
810
|
+
WHERE e.voided = 0 and e.encounter_type = 7 and e.program_id = 1
|
811
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime);
|
802
812
|
SQL
|
803
813
|
end
|
804
814
|
|
805
815
|
def insert_data_sanitizer_arv_medication
|
806
816
|
ActiveRecord::Base.connection.execute <<~SQL
|
807
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)
|
808
|
-
SELECT e.patient_id, o.order_id ,
|
809
|
-
|
810
|
-
|
811
|
-
COUNT(DISTINCT d.drug_id) AS num_unique_arvs,
|
812
|
-
GROUP_CONCAT(DISTINCT d.drug_id SEPARATOR ', ') AS unique_arvs_given,
|
813
|
-
GROUP_CONCAT(DISTINCT d.name SEPARATOR ', ') AS drug_names
|
818
|
+
SELECT e.patient_id, o.order_id, DATE(o.start_date) AS visit_date, DATE(MIN(o.auto_expire_date)) AS drug_runout_date,
|
819
|
+
COUNT(DISTINCT d.drug_id) AS num_unique_arvs,GROUP_CONCAT(DISTINCT d.drug_id SEPARATOR ', ') AS unique_arvs_given,
|
820
|
+
GROUP_CONCAT(DISTINCT d.name SEPARATOR ', ') AS drug_names
|
814
821
|
FROM #{schema}.orders o
|
815
|
-
INNER JOIN #{schema}.drug_order da ON da.order_id = o.order_id
|
816
|
-
AND o.voided = 0
|
817
|
-
AND da.quantity > 0
|
822
|
+
INNER JOIN #{schema}.drug_order da ON da.order_id = o.order_id AND o.voided = 0 AND da.quantity > 0
|
818
823
|
INNER JOIN #{schema}.drug d ON d.drug_id = da.drug_inventory_id
|
819
|
-
INNER JOIN #{schema}.obs ON obs.order_id = o.order_id
|
820
|
-
AND obs.
|
821
|
-
INNER JOIN #{schema}.encounter e ON e.program_id = 1
|
822
|
-
AND e.encounter_id = obs.encounter_id
|
823
|
-
AND e.encounter_type = 54
|
824
|
+
INNER JOIN #{schema}.obs ON obs.order_id = o.order_id AND obs.voided = 0
|
825
|
+
INNER JOIN #{schema}.encounter e ON e.program_id = 1 AND e.encounter_id = obs.encounter_id AND e.encounter_type = 54
|
824
826
|
INNER JOIN #{schema}.arv_drug ON arv_drug.drug_id = d.drug_id
|
825
827
|
GROUP BY obs.person_id, o.order_id, DATE(o.start_date);
|
826
828
|
SQL
|
@@ -829,10 +831,9 @@ module OpenmrsDataSanitizer
|
|
829
831
|
def insert_data_sanitizer_arv_orders
|
830
832
|
ActiveRecord::Base.connection.execute <<~SQL
|
831
833
|
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)
|
832
|
-
SELECT
|
833
|
-
|
834
|
-
|
835
|
-
orders.start_date, orders.auto_expire_date,SUM(o.quantity)
|
834
|
+
SELECT m.patient_id, o.order_id, orders.encounter_id , m.visit_date,
|
835
|
+
d.drug_id, d.name, d.units, o.equivalent_daily_dose, orders.instructions,
|
836
|
+
orders.start_date, orders.auto_expire_date,SUM(o.quantity)
|
836
837
|
FROM #{schema}.data_sanitizer_arv_medication m
|
837
838
|
INNER JOIN #{schema}.drug_order o ON o.order_id = m.order_id
|
838
839
|
INNER JOIN #{schema}.drug d ON d.drug_id = o.drug_inventory_id
|
@@ -856,36 +857,36 @@ module OpenmrsDataSanitizer
|
|
856
857
|
INSERT INTO #{schema}.data_sanitizer_patient_outcomes(patient_id, visit_date, end_date, state, concept_id, outcome)
|
857
858
|
SELECT p.patient_id,s.start_date, s.end_date, s.state, pws.concept_id, cn.name
|
858
859
|
FROM #{schema}.patient_program p
|
859
|
-
INNER JOIN #{schema}.patient_state s ON p.patient_program_id = s.patient_program_id
|
860
|
-
AND p.program_id = 1 AND p.voided = 0 AND s.voided = 0 AND s.state IS NOT NULL
|
860
|
+
INNER JOIN #{schema}.patient_state s ON p.patient_program_id = s.patient_program_id AND p.program_id = 1 AND p.voided = 0 AND s.voided = 0 AND s.state IS NOT NULL
|
861
861
|
INNER JOIN #{schema}.program_workflow_state pws ON s.state = pws.program_workflow_state_id AND pws.retired = 0 AND pws.terminal = 1
|
862
862
|
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = pws.concept_id AND cn.voided = 0 AND cn.name IS NOT NULL AND LENGTH(cn.name) > 0
|
863
863
|
GROUP BY p.patient_id, DATE(s.start_date), DATE(p.date_enrolled)
|
864
|
-
ORDER BY DATE(s.start_date) DESC, DATE(p.date_enrolled) DESC;
|
865
864
|
SQL
|
866
865
|
end
|
867
866
|
|
868
867
|
def insert_data_sanitizer_patient_who_stage
|
869
868
|
ActiveRecord::Base.connection.execute <<~SQL
|
870
869
|
INSERT INTO #{schema}.data_sanitizer_patient_who_stage(patient_id, visit_date, who_stage)
|
871
|
-
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
870
|
+
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name
|
871
|
+
FROM #{schema}.encounter e
|
872
|
+
INNER JOIN #{schema}.obs t1 ON t1.encounter_id = e.encounter_id
|
873
|
+
AND t1.voided = 0 AND t1.concept_id = 7562
|
874
|
+
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = t1.value_coded AND cn.voided = 0 AND LENGTH(cn.name) > 0
|
875
|
+
WHERE e.voided = 0 and e.encounter_type = 52 and e.program_id = 1
|
876
|
+
GROUP BY e.patient_id
|
877
877
|
SQL
|
878
878
|
end
|
879
879
|
|
880
880
|
def insert_data_sanitizer_patient_reason_for_starting
|
881
881
|
ActiveRecord::Base.connection.execute <<~SQL
|
882
882
|
INSERT INTO #{schema}.data_sanitizer_patient_reason_for_starting(patient_id, visit_date, reason_for_starting_art)
|
883
|
-
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
883
|
+
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name
|
884
|
+
FROM #{schema}.encounter e
|
885
|
+
INNER JOIN #{schema}.obs t1 ON t1.encounter_id = e.encounter_id
|
886
|
+
AND t1.voided = 0 AND t1.concept_id = 7563
|
887
|
+
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = t1.value_coded AND cn.voided = 0 AND LENGTH(cn.name) > 0
|
888
|
+
WHERE e.voided = 0 and e.encounter_type = 52 and e.program_id = 1
|
889
|
+
GROUP BY e.patient_id
|
889
890
|
SQL
|
890
891
|
end
|
891
892
|
|
@@ -13,17 +13,11 @@ module OpenmrsDataSanitizer
|
|
13
13
|
# rubocop:disable Metrics/ClassLength
|
14
14
|
# AWS DataSanitizer
|
15
15
|
class DataSanitizer
|
16
|
-
attr_accessor :
|
17
|
-
:concept_names, :faker_names, :sites, :patients_json,
|
18
|
-
:fhir_medication_dispense
|
16
|
+
attr_accessor :regimen_combinations, :concept_names, :faker_names, :sites
|
19
17
|
|
20
18
|
def initialize(sites: [])
|
21
|
-
@fhir_encounters = Concurrent::Array.new
|
22
|
-
@fhir_observations = Concurrent::Array.new
|
23
|
-
@fhir_medication_dispense = Concurrent::Array.new
|
24
19
|
@concept_names = Concurrent::Hash.new
|
25
20
|
@faker_names = Concurrent::Hash.new
|
26
|
-
@patients_json = Concurrent::Array.new
|
27
21
|
@regimen_combinations = {}
|
28
22
|
@sites = sites
|
29
23
|
load_regimen_combinations
|
@@ -63,13 +57,29 @@ module OpenmrsDataSanitizer
|
|
63
57
|
end
|
64
58
|
next unless loc
|
65
59
|
|
66
|
-
|
60
|
+
thread_variables # Set thread variables before processing
|
61
|
+
process_location(loc) # Process location
|
62
|
+
write_data_to_files # Write data to files
|
63
|
+
clear_thread_variables # Clear thread variables after processing
|
67
64
|
end
|
68
65
|
end
|
69
66
|
end
|
70
67
|
|
71
68
|
threads.each(&:join)
|
72
|
-
|
69
|
+
end
|
70
|
+
|
71
|
+
def thread_variables
|
72
|
+
Thread.current[:fhir_encounters] = Concurrent::Array.new
|
73
|
+
Thread.current[:fhir_observations] = Concurrent::Array.new
|
74
|
+
Thread.current[:fhir_medication_dispense] = Concurrent::Array.new
|
75
|
+
Thread.current[:patients_json] = Concurrent::Array.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def clear_thread_variables
|
79
|
+
Thread.current[:fhir_encounters] = nil
|
80
|
+
Thread.current[:fhir_observations] = nil
|
81
|
+
Thread.current[:fhir_medication_dispense] = nil
|
82
|
+
Thread.current[:patients_json] = nil
|
73
83
|
end
|
74
84
|
|
75
85
|
def process_location(loc)
|
@@ -92,19 +102,18 @@ module OpenmrsDataSanitizer
|
|
92
102
|
|
93
103
|
def process_patients(schema, site_name)
|
94
104
|
patients = fetch_patients(schema:)
|
95
|
-
patients_ids = patients.map { |patient| patient['person_id'].to_i }
|
96
105
|
patients.map { |patient| build_patient_json(patient, site_name) }
|
97
106
|
|
98
|
-
visits = fetch_visits(
|
107
|
+
visits = fetch_visits(schema:)
|
99
108
|
process_visits(visits:)
|
100
109
|
process_medication(schema:)
|
101
110
|
end
|
102
111
|
|
103
112
|
def write_data_to_files
|
104
|
-
write_to_file(patients_json.to_json, 'patients')
|
105
|
-
write_to_file(fhir_encounters.to_json, 'visits')
|
106
|
-
write_to_file(fhir_observations.to_json, 'observations')
|
107
|
-
write_to_file(fhir_medication_dispense.to_json, 'medications')
|
113
|
+
write_to_file(Thread.current[:patients_json].to_json, 'patients')
|
114
|
+
write_to_file(Thread.current[:fhir_encounters].to_json, 'visits')
|
115
|
+
write_to_file(Thread.current[:fhir_observations].to_json, 'observations')
|
116
|
+
write_to_file(Thread.current[:fhir_medication_dispense].to_json, 'medications')
|
108
117
|
end
|
109
118
|
|
110
119
|
# ===================================
|
@@ -141,15 +150,7 @@ module OpenmrsDataSanitizer
|
|
141
150
|
|
142
151
|
def fetch_patients(schema:)
|
143
152
|
ActiveRecord::Base.connection.select_all <<~SQL
|
144
|
-
SELECT
|
145
|
-
p.person_id, given_name, middle_name, family_name, gender, birthdate,
|
146
|
-
phone.value phone_number, village.value village_name
|
147
|
-
FROM #{schema}.person p
|
148
|
-
INNER JOIN #{schema}.patient ON patient.patient_id = p.person_id AND p.voided = 0
|
149
|
-
INNER JOIN #{schema}.patient_program pp ON pp.patient_id = p.person_id AND pp.voided = 0 AND pp.program_id = 1
|
150
|
-
LEFT JOIN #{schema}.person_name n ON n.person_id = p.person_id AND n.voided = 0
|
151
|
-
LEFT JOIN #{schema}.person_attribute phone ON phone.person_id = p.person_id AND phone.voided = 0 AND phone.person_attribute_type_id = 12
|
152
|
-
LEFT JOIN #{schema}.person_attribute village ON village.person_id = p.person_id AND village.voided = 0 AND village.person_attribute_type_id = 19;
|
153
|
+
SELECT * FROM #{schema}.data_sanitizer_patients;
|
153
154
|
SQL
|
154
155
|
end
|
155
156
|
|
@@ -162,7 +163,7 @@ module OpenmrsDataSanitizer
|
|
162
163
|
given_name = get_or_generate_faker_value(patient['given_name'], Faker::Name, :first_name)
|
163
164
|
middle_name = get_or_generate_faker_value(patient['middle_name'], Faker::Name, :middle_name)
|
164
165
|
|
165
|
-
patients_json << FHIR::Patient.new(
|
166
|
+
Thread.current[:patients_json] << FHIR::Patient.new(
|
166
167
|
id: patient_id,
|
167
168
|
identifier: [{ system: "#{site_name}_#{patient_id}", value: patient_id }],
|
168
169
|
name: [{ use: 'official', family: family_name, given: [given_name, middle_name] }],
|
@@ -172,19 +173,29 @@ module OpenmrsDataSanitizer
|
|
172
173
|
telecom: [{ system: 'phone', value: cell_number, use: 'mobile' }]
|
173
174
|
)
|
174
175
|
end
|
175
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
176
176
|
|
177
177
|
def fetch_gender(gender:)
|
178
|
-
gender.
|
178
|
+
case gender.strip.downcase
|
179
|
+
when 'f'
|
180
|
+
'female'
|
181
|
+
when 'm'
|
182
|
+
'male'
|
183
|
+
when 'u'
|
184
|
+
'unknown'
|
185
|
+
else
|
186
|
+
'unknown'
|
187
|
+
end
|
179
188
|
rescue StandardError => e
|
180
189
|
Rails.logger.info("Error fetching gender for patient: #{e.message}")
|
181
190
|
'unknown'
|
182
191
|
end
|
192
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
183
193
|
|
184
|
-
def fetch_visits(
|
194
|
+
def fetch_visits(schema:)
|
185
195
|
ActiveRecord::Base.connection.select_all <<~SQL
|
186
|
-
SELECT
|
187
|
-
|
196
|
+
SELECT dsv.*
|
197
|
+
FROM #{schema}.data_sanitizer_visits dsv
|
198
|
+
INNER JOIN #{schema}.data_sanitizer_patients dsp ON dsp.patient_id = dsv.patient_id
|
188
199
|
SQL
|
189
200
|
end
|
190
201
|
|
@@ -202,7 +213,7 @@ module OpenmrsDataSanitizer
|
|
202
213
|
|
203
214
|
def aws_fhir_encounter(visit:, regimen:)
|
204
215
|
patient_id = visit['patient_id'].to_i
|
205
|
-
fhir_encounters << create_fhir_encounter(patient_id, visit['visit_date'])
|
216
|
+
Thread.current[:fhir_encounters] << create_fhir_encounter(patient_id, visit['visit_date'])
|
206
217
|
|
207
218
|
observations = process_indicators(visit, regimen)
|
208
219
|
create_fhir_observations(observations, patient_id, visit['visit_date'])
|
@@ -269,7 +280,7 @@ module OpenmrsDataSanitizer
|
|
269
280
|
observations.each do |obs|
|
270
281
|
next if obs.blank? || obs[:code].blank? || obs[:value].blank?
|
271
282
|
|
272
|
-
fhir_observations << FHIR::Observation.new(
|
283
|
+
Thread.current[:fhir_observations] << FHIR::Observation.new(
|
273
284
|
status: 'final',
|
274
285
|
code: {
|
275
286
|
coding: [
|
@@ -284,20 +295,20 @@ module OpenmrsDataSanitizer
|
|
284
295
|
reference: "Patient/#{patient_id}"
|
285
296
|
},
|
286
297
|
encounter: {
|
287
|
-
reference: "Encounter/#{fhir_encounters.last.id}"
|
298
|
+
reference: "Encounter/#{Thread.current[:fhir_encounters].last.id}"
|
288
299
|
},
|
289
300
|
effectiveDateTime: visit_date
|
290
301
|
)
|
291
302
|
|
292
303
|
if obs[:unit]
|
293
|
-
fhir_observations.last.valueQuantity = {
|
304
|
+
Thread.current[:fhir_observations].last.valueQuantity = {
|
294
305
|
value: obs[:value],
|
295
306
|
unit: obs[:unit],
|
296
307
|
system: 'EGPAF Malawi EMR',
|
297
308
|
code: obs[:code]
|
298
309
|
}
|
299
310
|
else
|
300
|
-
fhir_observations.last.valueCodeableConcept = {
|
311
|
+
Thread.current[:fhir_observations].last.valueCodeableConcept = {
|
301
312
|
coding: [
|
302
313
|
{
|
303
314
|
system: 'EGPAF Malawi EMR',
|
@@ -332,16 +343,14 @@ module OpenmrsDataSanitizer
|
|
332
343
|
|
333
344
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/BlockLength
|
334
345
|
def create_fhir_medications(orders:)
|
335
|
-
fhir_medication_dispense << (orders || []).map do |order|
|
336
|
-
order_id = order['order_id'].to_i
|
337
|
-
encounter_id = order['encounter_id'].to_i
|
346
|
+
Thread.current[:fhir_medication_dispense] << (orders || []).map do |order|
|
338
347
|
FHIR::MedicationDispense.new(
|
339
348
|
identifier: {
|
340
|
-
value: order_id
|
349
|
+
value: order['order_id'].to_i
|
341
350
|
},
|
342
351
|
status: 'completed',
|
343
352
|
patient: {
|
344
|
-
reference: encounter_id
|
353
|
+
reference: order['encounter_id'].to_i
|
345
354
|
},
|
346
355
|
medication: {
|
347
356
|
code: {
|
@@ -388,7 +397,7 @@ module OpenmrsDataSanitizer
|
|
388
397
|
def get_or_generate_faker_value(attribute, faker_module, faker_method)
|
389
398
|
return '' if attribute.blank?
|
390
399
|
|
391
|
-
|
400
|
+
faker_names[attribute] ||= faker_module.send(faker_method)
|
392
401
|
end
|
393
402
|
|
394
403
|
def get_concept_name(name)
|
@@ -411,9 +420,14 @@ module OpenmrsDataSanitizer
|
|
411
420
|
|
412
421
|
# Use the mutex to handle concurrent writes
|
413
422
|
FILE_MUTEX.synchronize do
|
423
|
+
if File.exist?(file_path)
|
424
|
+
system("sed -i '$s/\([][^{},]\)$/,/g' #{file_path}")
|
425
|
+
json_file.sub!('[', '')
|
426
|
+
end
|
427
|
+
|
414
428
|
File.open(file_path, 'a') do |out_file|
|
415
429
|
out_file.puts(json_file)
|
416
|
-
|
430
|
+
Rails.logger.info "Appended to file: #{file_path}"
|
417
431
|
end
|
418
432
|
end
|
419
433
|
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.4
|
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-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|