emr_ohsp_interface 0.5.3 → 1.1.0

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: 145e8b4a017e7cbec4cc4ace99ca78f853f16bf5048a7043e1c8eba6b5486a54
4
- data.tar.gz: 741d47d437d4334b0218b9dbce8cdb328df9839ee68c95a71dc285c780a96425
3
+ metadata.gz: 649cb3e2144f053db93789503c1cd14bb48263a93c31d9fa92eb3edb30a54e42
4
+ data.tar.gz: 8f80cd97e51363c047610f2ac3661ca2cc967d81d1a475c157d9a402d3f009aa
5
5
  SHA512:
6
- metadata.gz: 6b5c9d1df00c1e00065fd95966924a4c28f130cdf9f7302ed7a7b7071288dcce42f9d1995c2e7d22307bd81749abf28879ef40a1c6f9abef4c1cb2990fe20ceb
7
- data.tar.gz: 78e83895b4a74c5d45bc1abdd420aff1003380bc0ba474f6b4d64dfb879309ef1989113f56e178c6f6a2fd52a16549810d3a077547d2482cb46b809ecbba1377
6
+ metadata.gz: 7a965d0f5e3d1bbbf830bdba32faad6426ca5a34970b908808b7165e8fa5a1851688e54f1a16b6c38ee545a3e59440c74c5d074642009f648258a600e264977f
7
+ data.tar.gz: 483de992deb8ab577a65821ebb60b8f6aaeaeb209d5d570eccf27aa996eb13c2dd7f59a948b847bbaa1d1ced9c6c9dc5398edd6c7e1a136fd9ea3cec24726bec
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2021 petroskayange
1
+ Copyright 2022 petroskayange, dominickasanga
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -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
@@ -5,6 +5,7 @@ module EmrOhspInterface
5
5
  class << self
6
6
  require 'csv'
7
7
  require 'rest-client'
8
+ require 'json'
8
9
  def settings
9
10
  file = File.read(Rails.root.join("db","idsr_metadata","idsr_ohsp_settings.json"))
10
11
  config = JSON.parse(file)
@@ -93,10 +94,11 @@ module EmrOhspInterface
93
94
  if request == nil
94
95
  response = send_data(collection,"weekly")
95
96
  end
97
+
96
98
  return collection
97
99
  end
98
- #idsr monthly report
99
100
 
101
+ #idsr monthly report
100
102
  def generate_monthly_idsr_report(request=nil,start_date=nil,end_date=nil)
101
103
  diag_map = settings["monthly_idsr_map"]
102
104
  epi_month = months_generator.first.first.strip
@@ -265,7 +267,10 @@ module EmrOhspInterface
265
267
 
266
268
  special_indicators = ["Malaria - new cases (under 5)",
267
269
  "Malaria - new cases (5 & over)",
268
- "HIV confirmed positive (15-49 years) new cases"
270
+ "HIV confirmed positive (15-49 years) new cases",
271
+ "Diarrhoea non - bloody -new cases (under5)",
272
+ "Malnutrition - new case (under 5)",
273
+ "Acute respiratory infections - new cases (U5)"
269
274
  ]
270
275
 
271
276
  diag_map.each do |key,value|
@@ -315,7 +320,6 @@ module EmrOhspInterface
315
320
  options["ids"] = under_five
316
321
 
317
322
  collection[key] = options
318
-
319
323
  end
320
324
 
321
325
  if key.eql?("Malaria - new cases (5 & over)")
@@ -350,11 +354,266 @@ module EmrOhspInterface
350
354
 
351
355
  collection[key] = options
352
356
  end
357
+
358
+ if key.eql?("Diarrhoea non - bloody -new cases (under5)")
359
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
360
+ AND encounter_type = ? AND value_coded IN (?)
361
+ AND concept_id IN(6543, 6542)',
362
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
363
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
364
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
365
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
366
+ select('encounter.encounter_type, obs.value_coded, p.*')
367
+
368
+ under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
369
+ collect{|record| record["person_id"]}
370
+
371
+ options["ids"] = under_five
372
+
373
+ collection[key] = options
374
+ end
375
+
376
+ if key.eql?("Malnutrition - new case (under 5)")
377
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
378
+ AND encounter_type = ? AND value_coded IN (?)
379
+ AND concept_id IN(6543, 6542)',
380
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
381
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
382
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
383
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
384
+ select('encounter.encounter_type, obs.value_coded, p.*')
385
+
386
+ under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
387
+ collect{|record| record["person_id"]}
388
+
389
+ options["ids"] = under_five
390
+
391
+ collection[key] = options
392
+ end
393
+
394
+ if key.eql?("Acute respiratory infections - new cases (U5)")
395
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
396
+ AND encounter_type = ? AND value_coded IN (?)
397
+ AND concept_id IN(6543, 6542)',
398
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
399
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
400
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
401
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
402
+ select('encounter.encounter_type, obs.value_coded, p.*')
403
+
404
+ under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
405
+ collect{|record| record["person_id"]}
406
+
407
+ options["ids"] = under_five
408
+
409
+ collection[key] = options
410
+ end
411
+
353
412
  end
354
413
  end
355
414
  collection
356
415
  end
357
416
 
417
+ def disaggregate(disaggregate_key, concept_ids, start_date, end_date, type)
418
+ options = {"ids"=>nil}
419
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
420
+ AND encounter_type = ? AND value_coded IN (?)
421
+ AND concept_id IN(6543, 6542)',
422
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
423
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
424
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
425
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
426
+ select('encounter.encounter_type, obs.value_coded, p.*')
427
+
428
+ if disaggregate_key == "less"
429
+ options["ids"] = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
430
+ collect{|record| record["person_id"]}
431
+ else
432
+ if disaggregate_key == "greater"
433
+ options["ids"] = data.select{|record| calculate_age(record["birthdate"]) >= 5 }.\
434
+ collect{|record| record["person_id"]}
435
+ end
436
+ end
437
+
438
+ options
439
+ end
440
+
441
+ def generate_hmis_17_report(start_date=nil,end_date=nil)
442
+
443
+ diag_map = settings["hmis_17_map"]
444
+
445
+ #pull the data
446
+ type = EncounterType.find_by_name 'Outpatient diagnosis'
447
+ collection = {}
448
+
449
+ special_indicators = [
450
+ "Referals from other institutions",
451
+ "OPD total attendance",
452
+ "Referal to other institutions",
453
+ "Malaria 5 years and older - new"
454
+ ]
455
+
456
+ special_under_five_indicators = [
457
+ "Measles under five years - new",
458
+ "Pneumonia under 5 years- new",
459
+ "Dysentery under 5 years - new",
460
+ "Diarrhoea non - bloody -new cases (under5)",
461
+ "Malaria under 5 years - new"
462
+ ]
463
+
464
+ diag_map.each do |key,value|
465
+ options = {"ids"=>nil}
466
+ concept_ids = ConceptName.where(name: value).collect{|cn| cn.concept_id}
467
+
468
+ if !special_indicators.include?(key) && !special_under_five_indicators.include?(key)
469
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
470
+ AND encounter_type = ? AND value_coded IN (?)
471
+ AND concept_id IN(6543, 6542)',
472
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
473
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
474
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
475
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
476
+ select('encounter.encounter_type, obs.value_coded, p.*')
477
+
478
+ all = data.collect{|record| record.person_id}
479
+
480
+
481
+ options["ids"] = all
482
+
483
+ collection[key] = options
484
+ else
485
+ if key.eql?("Referals from other institutions")
486
+ _type = EncounterType.find_by_name 'PATIENT REGISTRATION'
487
+ visit_type = ConceptName.find_by_name 'Type of visit'
488
+
489
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
490
+ AND encounter_type = ? AND value_coded IS NOT NULL
491
+ AND obs.concept_id = ?', start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
492
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),_type.id, visit_type.concept_id).\
493
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
494
+ INNER JOIN person p ON p.person_id = encounter.patient_id
495
+ INNER JOIN concept_name c ON c.concept_id = 6541').\
496
+ select('encounter.encounter_type, obs.value_coded, obs.obs_datetime, p.*, c.name visit_type').\
497
+ group('p.person_id, encounter.encounter_id')
498
+
499
+ all = data.collect{|record| record.person_id}
500
+
501
+ options["ids"] = all
502
+
503
+ collection[key] = options
504
+ end
505
+
506
+ if key.eql?("OPD total attendance")
507
+ _type = EncounterType.find_by_name 'PATIENT REGISTRATION'
508
+ visit_type = ConceptName.find_by_name 'Type of visit'
509
+
510
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
511
+ AND encounter_type = ? AND value_coded IS NOT NULL
512
+ AND obs.concept_id = ?', start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
513
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),_type.id, visit_type.concept_id).\
514
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
515
+ INNER JOIN person p ON p.person_id = encounter.patient_id
516
+ INNER JOIN concept_name c ON c.concept_id = obs.value_coded
517
+ LEFT JOIN person_name n ON n.person_id = encounter.patient_id AND n.voided = 0
518
+ RIGHT JOIN person_address a ON a.person_id = encounter.patient_id').\
519
+ select('encounter.encounter_type, n.family_name, n.given_name,
520
+ obs.value_coded, obs.obs_datetime, p.*, c.name visit_type,
521
+ a.state_province district, a.township_division ta, a.city_village village').\
522
+ order('n.date_created DESC').group('n.person_id, encounter.encounter_id')
523
+
524
+ all = data.collect{|record| record.person_id}
525
+
526
+ options["ids"] = all
527
+
528
+ collection[key] = options
529
+ end
530
+
531
+ if key.eql?("Referal to other institutions")
532
+ data = Observation.where("obs_datetime BETWEEN ? AND ?
533
+ AND concept_id = ?",start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
534
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),'7414').\
535
+ joins('LEFT JOIN location l ON l.location_id = obs.value_text').\
536
+ select('obs.person_id').order('obs_datetime DESC')
537
+
538
+ all = data.collect{|record| record.person_id}
539
+
540
+ options["ids"] = all
541
+
542
+ collection[key] = options
543
+ end
544
+
545
+ if key.eql?("Measles under five years - new")
546
+ collection[key] = disaggregate('less',concept_ids, start_date, end_date, type)
547
+ end
548
+
549
+ if key.eql?("Pneumonia under 5 years- new")
550
+ collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
551
+ end
552
+
553
+ if key.eql?("Malaria under 5 years - new")
554
+ collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
555
+ end
556
+
557
+ if key.eql?("Malaria 5 years and older - new")
558
+ collection[key] = disaggregate('greater',concept_ids, start_date, end_date, type)
559
+ end
560
+
561
+ if key.eql?("Dysentery under 5 years - new")
562
+ collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
563
+ end
564
+
565
+ if key.eql?("Diarrhoea non - bloody -new cases (under5)")
566
+ collection[key] = disaggregate('less', concept_ids, start_date, end_date, type)
567
+ end
568
+
569
+ end
570
+ end
571
+
572
+ collection
573
+
574
+ end
575
+
576
+ def generate_notifiable_disease_conditions_report(start_date=nil,end_date=nil)
577
+ diag_map = settings["notifiable_disease_conditions"]
578
+
579
+ start_date = Date.today.strftime("%Y-%m-%d") if start_date.nil?
580
+ end_date = Date.today.strftime("%Y-%m-%d") if end_date.nil?
581
+
582
+ type = EncounterType.find_by_name 'Outpatient diagnosis'
583
+ collection = {}
584
+ concept_name_for_sms_portal = {}
585
+
586
+ diag_map.each do |key,value|
587
+ options = {"<5yrs"=>nil,">=5yrs"=>nil}
588
+ concept_ids = ConceptName.where(name: value).collect{|cn| cn.concept_id}
589
+
590
+ data = Encounter.where('encounter_datetime BETWEEN ? AND ?
591
+ AND encounter_type = ? AND value_coded IN (?)
592
+ AND concept_id IN(6543, 6542)',
593
+ start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
594
+ end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
595
+ joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
596
+ INNER JOIN person p ON p.person_id = encounter.patient_id').\
597
+ select('encounter.encounter_type, obs.value_coded, p.*')
598
+
599
+ #under_five
600
+ under_five = data.select{|record| calculate_age(record["birthdate"]) < 5}.\
601
+ collect{|record| record.person_id}
602
+ options["<5yrs"] = under_five
603
+ #above 5 years
604
+ over_five = data.select{|record| calculate_age(record["birthdate"]) >=5 }.\
605
+ collect{|record| record.person_id}
606
+
607
+ options[">=5yrs"] = over_five
608
+
609
+ collection[key] = options
610
+
611
+ concept_name_for_sms_portal[key] = concept_ids
612
+ end
613
+ send_data_to_sms_portal(collection, concept_name_for_sms_portal)
614
+ return collection
615
+ end
616
+
358
617
  # helper menthod
359
618
  def months_generator
360
619
  months = Hash.new
@@ -426,11 +685,11 @@ module EmrOhspInterface
426
685
  if !special.include?(key)
427
686
  option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
428
687
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
429
- "value"=>value["<5yrs"].size }
688
+ "value"=>value["<5yrs"].size } rescue {}
430
689
 
431
690
  option2 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
432
691
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[3],
433
- "value"=>value[">=5yrs"].size}
692
+ "value"=>value[">=5yrs"].size} rescue {}
434
693
 
435
694
  #fill data values array
436
695
  payload["dataValues"] << option1
@@ -440,25 +699,25 @@ module EmrOhspInterface
440
699
  when special[0]
441
700
  option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
442
701
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
443
- "value"=>value["<5yrs"].size }
702
+ "value"=>value["<5yrs"].size } rescue {}
444
703
 
445
704
  payload["dataValues"] << option1
446
705
  when special[1]
447
706
  option2 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
448
707
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[3],
449
- "value"=>value[">=5yrs"].size }
708
+ "value"=>value[">=5yrs"].size } rescue {}
450
709
 
451
710
  payload["dataValues"] << option2
452
711
  when special[2]
453
712
  option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
454
713
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
455
- "value"=>value["<5yrs"].size }
714
+ "value"=>value["<5yrs"].size } rescue {}
456
715
 
457
716
  payload["dataValues"] << option1
458
717
  when special[3]
459
718
  option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
460
719
  "categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
461
- "value"=>value["<5yrs"].size}
720
+ "value"=>value["<5yrs"].size} rescue {}
462
721
 
463
722
  payload["dataValues"] << option1
464
723
  end
@@ -480,8 +739,41 @@ module EmrOhspInterface
480
739
  puts send
481
740
  end
482
741
 
742
+ def send_data_to_sms_portal(data, concept_name_collection)
743
+ conn2 = settings["sms_server"]
744
+ data = data.select {|k,v| v.select {|kk,vv| vv.length > 0}.length > 0}
745
+ payload = {
746
+ "email"=> conn2["user"],
747
+ "password" => conn2["pass"],
748
+ "emr_facility_id" => Location.current_health_center.id,
749
+ "emr_facility_name" => Location.current_health_center.name,
750
+ "payload" => data,
751
+ "concept_name_collection" => concept_name_collection
752
+ }
753
+
754
+
755
+
756
+ begin
757
+ response = RestClient::Request.execute(method: :post,
758
+ url: conn2["url"],
759
+ headers:{'Content-Type'=> 'application/json'},
760
+ payload: payload.to_json
761
+ )
762
+ rescue RestClient::ExceptionWithResponse => res
763
+ if res.class == RestClient::Forbidden
764
+ puts "error: #{res.class}"
765
+ end
766
+ end
767
+
768
+ if response.class != NilClass
769
+ if response.code == 200
770
+ puts "success: #{response}"
771
+ end
772
+ end
773
+
774
+ end
775
+
483
776
  end
484
777
  end
485
778
 
486
-
487
779
  end
data/config/routes.rb CHANGED
@@ -6,4 +6,14 @@ 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'
10
+
11
+ # for the new crossplatform OPD system
12
+ get 'api/v1/get_lims_user', to: 'emr_lims_interface#get_user_info'
13
+ get 'api/v1/get_weeks', to: 'emr_ohsp_interface#weeks_generator'
14
+ get 'api/v1/get_months', to: 'emr_ohsp_interface#months_generator'
15
+ get 'api/v1/generate_weekly_idsr_report', to: 'emr_ohsp_interface#generate_weekly_idsr_report'
16
+ get 'api/v1/generate_monthly_idsr_report', to: 'emr_ohsp_interface#generate_monthly_idsr_report'
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'
9
19
  end
@@ -1,3 +1,3 @@
1
1
  module EmrOhspInterface
2
- VERSION = '0.5.3'
2
+ VERSION = '1.1.0'
3
3
  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: 0.5.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Justin Manda and Petros Kayange
7
+ - Justin Manda, Petros Kayange, and Dominic Kasanga
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -74,7 +74,7 @@ dependencies:
74
74
  version: '0'
75
75
  description:
76
76
  email:
77
- - justinmandah@gmail.com, kayangepetros@gmail.com
77
+ - justinmandah@gmail.com, kayangepetros@gmail.com, dominickasanga@gmail.com
78
78
  executables: []
79
79
  extensions: []
80
80
  extra_rdoc_files: []
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  requirements: []
123
- rubygems_version: 3.2.32
123
+ rubygems_version: 3.0.9
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: This in a gem that facilitates interfacing of EMR, One Health Surveillance