emr_ohsp_interface 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73b9145df1d352e5e6df1cbf8983b7a28a15a3a91cc86ee06341141fb0c0dfee
|
4
|
+
data.tar.gz: 60069ab8d7ef564129e656e25bd41ba598639cdf07b4f90a317823e8ec9042ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84c0c258dd74dc53322b73b85b88fdef01232cf3fc76f6e989e25e0d141fc7a16a62386465a73471992222d2a7f2f37ce30c34198fb69f4535d9b8159b8b4369
|
7
|
+
data.tar.gz: 7497b891e1aaa5715457509ed5606baa8af6df7b948a94c51ec855f4d9f0485f10999709b2c9162043ed477e562110565d3f546bb04872f070f3e9adb9004aa7
|
data/MIT-LICENSE
CHANGED
@@ -18,6 +18,10 @@ class EmrOhspInterface::EmrOhspInterfaceController < ::ApplicationController
|
|
18
18
|
def generate_hmis_15_report
|
19
19
|
render json: service.generate_hmis_15_report(params[:start_date],params[:end_date]);
|
20
20
|
end
|
21
|
+
|
22
|
+
def generate_hmis_17_report
|
23
|
+
render json: service.generate_hmis_17_report(params[:start_date],params[:end_date]);
|
24
|
+
end
|
21
25
|
|
22
26
|
def service
|
23
27
|
EmrOhspInterface::EmrOhspInterfaceService
|
@@ -11,6 +11,10 @@ module EmrOhspInterface
|
|
11
11
|
config = JSON.parse(file)
|
12
12
|
end
|
13
13
|
|
14
|
+
def server_config
|
15
|
+
config =YAML.load_file("#{Rails.root}/config/application.yml")
|
16
|
+
end
|
17
|
+
|
14
18
|
def get_ohsp_facility_id
|
15
19
|
file = File.open(Rails.root.join("db","idsr_metadata","emr_ohsp_facility_map.csv"))
|
16
20
|
data = CSV.parse(file,headers: true)
|
@@ -129,11 +133,11 @@ module EmrOhspInterface
|
|
129
133
|
|
130
134
|
#under_five
|
131
135
|
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5}.\
|
132
|
-
collect{|record| record.person_id}
|
136
|
+
collect{|record| record.person_id}.uniq
|
133
137
|
options["<5yrs"] = under_five
|
134
138
|
#above 5 years
|
135
139
|
over_five = data.select{|record| calculate_age(record["birthdate"]) >=5 }.\
|
136
|
-
collect{|record| record.person_id}
|
140
|
+
collect{|record| record.person_id}.uniq
|
137
141
|
|
138
142
|
options[">=5yrs"] = over_five
|
139
143
|
|
@@ -267,7 +271,10 @@ module EmrOhspInterface
|
|
267
271
|
|
268
272
|
special_indicators = ["Malaria - new cases (under 5)",
|
269
273
|
"Malaria - new cases (5 & over)",
|
270
|
-
"HIV confirmed positive (15-49 years) new cases"
|
274
|
+
"HIV confirmed positive (15-49 years) new cases",
|
275
|
+
"Diarrhoea non - bloody -new cases (under5)",
|
276
|
+
"Malnutrition - new case (under 5)",
|
277
|
+
"Acute respiratory infections - new cases (U5)"
|
271
278
|
]
|
272
279
|
|
273
280
|
diag_map.each do |key,value|
|
@@ -317,7 +324,6 @@ module EmrOhspInterface
|
|
317
324
|
options["ids"] = under_five
|
318
325
|
|
319
326
|
collection[key] = options
|
320
|
-
|
321
327
|
end
|
322
328
|
|
323
329
|
if key.eql?("Malaria - new cases (5 & over)")
|
@@ -352,11 +358,225 @@ module EmrOhspInterface
|
|
352
358
|
|
353
359
|
collection[key] = options
|
354
360
|
end
|
361
|
+
|
362
|
+
if key.eql?("Diarrhoea non - bloody -new cases (under5)")
|
363
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
364
|
+
AND encounter_type = ? AND value_coded IN (?)
|
365
|
+
AND concept_id IN(6543, 6542)',
|
366
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
367
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
368
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
369
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
370
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
371
|
+
|
372
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
373
|
+
collect{|record| record["person_id"]}
|
374
|
+
|
375
|
+
options["ids"] = under_five
|
376
|
+
|
377
|
+
collection[key] = options
|
378
|
+
end
|
379
|
+
|
380
|
+
if key.eql?("Malnutrition - new case (under 5)")
|
381
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
382
|
+
AND encounter_type = ? AND value_coded IN (?)
|
383
|
+
AND concept_id IN(6543, 6542)',
|
384
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
385
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
386
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
387
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
388
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
389
|
+
|
390
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
391
|
+
collect{|record| record["person_id"]}
|
392
|
+
|
393
|
+
options["ids"] = under_five
|
394
|
+
|
395
|
+
collection[key] = options
|
396
|
+
end
|
397
|
+
|
398
|
+
if key.eql?("Acute respiratory infections - new cases (U5)")
|
399
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
400
|
+
AND encounter_type = ? AND value_coded IN (?)
|
401
|
+
AND concept_id IN(6543, 6542)',
|
402
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
403
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
404
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
405
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
406
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
407
|
+
|
408
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
409
|
+
collect{|record| record["person_id"]}
|
410
|
+
|
411
|
+
options["ids"] = under_five
|
412
|
+
|
413
|
+
collection[key] = options
|
414
|
+
end
|
415
|
+
|
355
416
|
end
|
356
417
|
end
|
357
418
|
collection
|
358
419
|
end
|
359
420
|
|
421
|
+
def disaggregate(disaggregate_key, concept_ids, start_date, end_date, type)
|
422
|
+
options = {"ids"=>nil}
|
423
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
424
|
+
AND encounter_type = ? AND value_coded IN (?)
|
425
|
+
AND concept_id IN(6543, 6542)',
|
426
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
427
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
428
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
429
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
430
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
431
|
+
|
432
|
+
if disaggregate_key == "less"
|
433
|
+
options["ids"] = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
434
|
+
collect{|record| record["person_id"]}
|
435
|
+
else
|
436
|
+
if disaggregate_key == "greater"
|
437
|
+
options["ids"] = data.select{|record| calculate_age(record["birthdate"]) >= 5 }.\
|
438
|
+
collect{|record| record["person_id"]}
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
options
|
443
|
+
end
|
444
|
+
|
445
|
+
def generate_hmis_17_report(start_date=nil,end_date=nil)
|
446
|
+
|
447
|
+
diag_map = settings["hmis_17_map"]
|
448
|
+
|
449
|
+
#pull the data
|
450
|
+
type = EncounterType.find_by_name 'Outpatient diagnosis'
|
451
|
+
collection = {}
|
452
|
+
|
453
|
+
special_indicators = [
|
454
|
+
"Referals from other institutions",
|
455
|
+
"OPD total attendance",
|
456
|
+
"Referal to other institutions",
|
457
|
+
"Malaria 5 years and older - new",
|
458
|
+
"HIV/AIDS - new"
|
459
|
+
]
|
460
|
+
|
461
|
+
special_under_five_indicators = [
|
462
|
+
"Measles under five years - new",
|
463
|
+
"Pneumonia under 5 years- new",
|
464
|
+
"Dysentery under 5 years - new",
|
465
|
+
"Diarrhoea non - bloody -new cases (under5)",
|
466
|
+
"Malaria under 5 years - new"
|
467
|
+
]
|
468
|
+
|
469
|
+
diag_map.each do |key,value|
|
470
|
+
options = {"ids"=>nil}
|
471
|
+
concept_ids = ConceptName.where(name: value).collect{|cn| cn.concept_id}
|
472
|
+
|
473
|
+
if !special_indicators.include?(key) && !special_under_five_indicators.include?(key)
|
474
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
475
|
+
AND encounter_type = ? AND value_coded IN (?)
|
476
|
+
AND concept_id IN(6543, 6542)',
|
477
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
478
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
479
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
480
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
481
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
482
|
+
|
483
|
+
all = data.collect{|record| record.person_id}
|
484
|
+
|
485
|
+
|
486
|
+
options["ids"] = all
|
487
|
+
|
488
|
+
collection[key] = options
|
489
|
+
else
|
490
|
+
if key.eql?("Referals from other institutions")
|
491
|
+
_type = EncounterType.find_by_name 'PATIENT REGISTRATION'
|
492
|
+
visit_type = ConceptName.find_by_name 'Type of visit'
|
493
|
+
|
494
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
495
|
+
AND encounter_type = ? AND value_coded IS NOT NULL
|
496
|
+
AND obs.concept_id = ?', start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
497
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),_type.id, visit_type.concept_id).\
|
498
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
499
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id
|
500
|
+
INNER JOIN concept_name c ON c.concept_id = 6541').\
|
501
|
+
select('encounter.encounter_type, obs.value_coded, obs.obs_datetime, p.*, c.name visit_type').\
|
502
|
+
group('p.person_id, encounter.encounter_id')
|
503
|
+
|
504
|
+
all = data.collect{|record| record.person_id}
|
505
|
+
|
506
|
+
options["ids"] = all
|
507
|
+
|
508
|
+
collection[key] = options
|
509
|
+
end
|
510
|
+
|
511
|
+
if key.eql?("OPD total attendance")
|
512
|
+
programID = Program.find_by_name 'OPD Program'
|
513
|
+
data = Encounter.find_by_sql(
|
514
|
+
"SELECT patient_id, DATE_FORMAT(encounter_datetime,'%Y-%m-%d') enc_date
|
515
|
+
FROM encounter e
|
516
|
+
LEFT OUTER JOIN person p ON p.person_id = e.patient_id
|
517
|
+
WHERE e.voided = 0 AND encounter_datetime BETWEEN '" + start_date.to_date.strftime('%Y-%m-%d 00:00:00') +"'
|
518
|
+
AND '" + end_date.to_date.strftime('%Y-%m-%d 23:59:59') + "'
|
519
|
+
AND program_id ='" + programID.program_id.to_s + "'
|
520
|
+
GROUP BY enc_date"
|
521
|
+
).map{|e| e. patient_id}
|
522
|
+
|
523
|
+
options["ids"] = data
|
524
|
+
collection[key] = options
|
525
|
+
end
|
526
|
+
|
527
|
+
if key.eql?("Referal to other institutions")
|
528
|
+
data = Observation.where("obs_datetime BETWEEN ? AND ?
|
529
|
+
AND concept_id = ?",start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
530
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),'7414').\
|
531
|
+
joins('LEFT JOIN location l ON l.location_id = obs.value_text').\
|
532
|
+
select('obs.person_id').order('obs_datetime DESC')
|
533
|
+
all = data.collect{|record| record.person_id}
|
534
|
+
options["ids"] = all
|
535
|
+
collection[key] = options
|
536
|
+
end
|
537
|
+
|
538
|
+
if key.eql?("HIV/AIDS - new")
|
539
|
+
data = ActiveRecord::Base.connection.select_all(
|
540
|
+
"SELECT * FROM temp_earliest_start_date
|
541
|
+
WHERE date_enrolled BETWEEN '#{start_date}' AND '#{end_date}'
|
542
|
+
AND date_enrolled = earliest_start_date
|
543
|
+
GROUP BY patient_id" ).to_hash
|
544
|
+
all = data.collect{|record| record["patient_id"]}
|
545
|
+
options["ids"] = all
|
546
|
+
collection[key] = options
|
547
|
+
end
|
548
|
+
|
549
|
+
if key.eql?("Measles under five years - new")
|
550
|
+
collection[key] = disaggregate('less',concept_ids, start_date, end_date, type)
|
551
|
+
end
|
552
|
+
|
553
|
+
if key.eql?("Pneumonia under 5 years- new")
|
554
|
+
collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
|
555
|
+
end
|
556
|
+
|
557
|
+
if key.eql?("Malaria under 5 years - new")
|
558
|
+
collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
|
559
|
+
end
|
560
|
+
|
561
|
+
if key.eql?("Malaria 5 years and older - new")
|
562
|
+
collection[key] = disaggregate('greater',concept_ids, start_date, end_date, type)
|
563
|
+
end
|
564
|
+
|
565
|
+
if key.eql?("Dysentery under 5 years - new")
|
566
|
+
collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
|
567
|
+
end
|
568
|
+
|
569
|
+
if key.eql?("Diarrhoea non - bloody -new cases (under5)")
|
570
|
+
collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
|
571
|
+
end
|
572
|
+
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
collection
|
577
|
+
|
578
|
+
end
|
579
|
+
|
360
580
|
def generate_notifiable_disease_conditions_report(start_date=nil,end_date=nil)
|
361
581
|
diag_map = settings["notifiable_disease_conditions"]
|
362
582
|
|
@@ -416,7 +636,7 @@ module EmrOhspInterface
|
|
416
636
|
def weeks_generator
|
417
637
|
|
418
638
|
weeks = Hash.new
|
419
|
-
first_day = (
|
639
|
+
first_day = (Date.today - (11).month).at_beginning_of_month
|
420
640
|
wk_of_first_day = first_day.cweek
|
421
641
|
|
422
642
|
if wk_of_first_day > 1
|
@@ -455,7 +675,7 @@ module EmrOhspInterface
|
|
455
675
|
def send_data(data,type)
|
456
676
|
# method used to post data to the server
|
457
677
|
#prepare payload here
|
458
|
-
conn =
|
678
|
+
conn = server_config['ohsp']
|
459
679
|
payload = {
|
460
680
|
"dataSet" =>get_data_set_id(type),
|
461
681
|
"period"=>(type.eql?("weekly") ? weeks_generator.last[0] : months_generator.first[0]),
|
@@ -517,18 +737,18 @@ module EmrOhspInterface
|
|
517
737
|
headers:{'Content-Type'=> 'application/json'},
|
518
738
|
payload: payload.to_json,
|
519
739
|
#headers: {accept: :json},
|
520
|
-
user: conn["
|
521
|
-
password: conn["
|
740
|
+
user: conn["username"],
|
741
|
+
password: conn["password"])
|
522
742
|
|
523
743
|
puts send
|
524
744
|
end
|
525
745
|
|
526
746
|
def send_data_to_sms_portal(data, concept_name_collection)
|
527
|
-
conn2 =
|
747
|
+
conn2 = server_config['idsr_sms']
|
528
748
|
data = data.select {|k,v| v.select {|kk,vv| vv.length > 0}.length > 0}
|
529
749
|
payload = {
|
530
|
-
"email"=> conn2["
|
531
|
-
"password" => conn2["
|
750
|
+
"email"=> conn2["username"],
|
751
|
+
"password" => conn2["password"],
|
532
752
|
"emr_facility_id" => Location.current_health_center.id,
|
533
753
|
"emr_facility_name" => Location.current_health_center.name,
|
534
754
|
"payload" => data,
|
data/config/routes.rb
CHANGED
@@ -6,6 +6,7 @@ EmrOhspInterface::Engine.routes.draw do
|
|
6
6
|
get '/generate_weekly_idsr_report', to: 'emr_ohsp_interface#generate_weekly_idsr_report'
|
7
7
|
get '/generate_monthly_idsr_report', to: 'emr_ohsp_interface#generate_monthly_idsr_report'
|
8
8
|
get '/generate_hmis_15_report', to: 'emr_ohsp_interface#generate_hmis_15_report'
|
9
|
+
get '/generate_hmis_17_report', to: 'emr_ohsp_interface#generate_hmis_17_report'
|
9
10
|
|
10
11
|
# for the new crossplatform OPD system
|
11
12
|
get 'api/v1/get_lims_user', to: 'emr_lims_interface#get_user_info'
|
@@ -14,4 +15,5 @@ EmrOhspInterface::Engine.routes.draw do
|
|
14
15
|
get 'api/v1/generate_weekly_idsr_report', to: 'emr_ohsp_interface#generate_weekly_idsr_report'
|
15
16
|
get 'api/v1/generate_monthly_idsr_report', to: 'emr_ohsp_interface#generate_monthly_idsr_report'
|
16
17
|
get 'api/v1/generate_hmis_15_report', to: 'emr_ohsp_interface#generate_hmis_15_report'
|
18
|
+
get 'api/v1/generate_hmis_17_report', to: 'emr_ohsp_interface#generate_hmis_17_report'
|
17
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emr_ohsp_interface
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Justin Manda and
|
7
|
+
- Justin Manda, Petros Kayange, and Dominic Kasanga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -72,9 +72,29 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: sqlite3
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.3.6
|
82
|
+
- - "~>"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '1.3'
|
85
|
+
type: :development
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 1.3.6
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '1.3'
|
75
95
|
description:
|
76
96
|
email:
|
77
|
-
- justinmandah@gmail.com, kayangepetros@gmail.com
|
97
|
+
- justinmandah@gmail.com, kayangepetros@gmail.com, dominickasanga@gmail.com
|
78
98
|
executables: []
|
79
99
|
extensions: []
|
80
100
|
extra_rdoc_files: []
|
@@ -120,7 +140,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
140
|
- !ruby/object:Gem::Version
|
121
141
|
version: '0'
|
122
142
|
requirements: []
|
123
|
-
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.7.6
|
124
145
|
signing_key:
|
125
146
|
specification_version: 4
|
126
147
|
summary: This in a gem that facilitates interfacing of EMR, One Health Surveillance
|