emr_ohsp_interface 0.2.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/emr_ohsp_interface/emr_lims_interface_controller.rb +24 -0
- data/app/controllers/emr_ohsp_interface/emr_ohsp_interface_controller.rb +13 -0
- data/app/services/emr_ohsp_interface/emr_lims_interface_service.rb +410 -0
- data/app/services/emr_ohsp_interface/emr_ohsp_interface_service.rb +234 -18
- data/config/routes.rb +5 -1
- data/lib/emr_ohsp_interface/version.rb +1 -1
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b0a446ac067b3e70a193019ee45c89339716467f917d8a370bcbb1a223b75b6
|
4
|
+
data.tar.gz: b281e439cc147418468af783a1896940f5aa9d5311c85616dc6f57d1945cdfc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a76ba192164398c65368d1b9ac19b67b74696e53f1f2df83cb8155f2f50cd496f9a98d512166c8afdc61ccae88a4c14bef99b5f932072e9b5e8750be364640c8
|
7
|
+
data.tar.gz: c225131968d0b931b1e15c0c8be724d2e7e754690c998426d186aa9517bac464a99e4b75af4eae5ef012d2939ee993f8bb240f8e37e36c551eb67a2500eb07d6
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EmrOhspInterface::EmrLimsInterfaceController < ::ApplicationController
|
4
|
+
def create
|
5
|
+
# lab_details = params.require %i[lab_details]
|
6
|
+
# render json: "#{lab_details[0]['firstname']}"
|
7
|
+
# render json:
|
8
|
+
order_params_list, clinician_id = params.require %i[lab_details clinician_id]
|
9
|
+
|
10
|
+
render json: service.create_lab_order(order_params_list, clinician_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def index
|
14
|
+
render json: service.get_lims_test_results(params[:id],params[:patient_id])
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_user_info()
|
18
|
+
render json: service.get_user_details(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def service
|
22
|
+
EmrOhspInterface::EmrLimsInterfaceService
|
23
|
+
end
|
24
|
+
end
|
@@ -2,8 +2,21 @@ class EmrOhspInterface::EmrOhspInterfaceController < ::ApplicationController
|
|
2
2
|
def weeks_generator
|
3
3
|
render json: service.weeks_generator();
|
4
4
|
end
|
5
|
+
|
5
6
|
def months_generator
|
6
7
|
render json: service.months_generator();
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate_weekly_idsr_report
|
11
|
+
render json: service.generate_weekly_idsr_report(params[:request],params[:start_date],params[:end_date]);
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_monthly_idsr_report
|
15
|
+
render json: service.generate_monthly_idsr_report(params[:request],params[:start_date],params[:end_date]);
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_hmis_15_report
|
19
|
+
render json: service.generate_hmis_15_report(params[:request],params[:start_date],params[:end_date]);
|
7
20
|
end
|
8
21
|
|
9
22
|
def service
|
@@ -0,0 +1,410 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'emr_ohsp_interface/version'
|
4
|
+
module EmrOhspInterface
|
5
|
+
module EmrLimsInterfaceService
|
6
|
+
class << self
|
7
|
+
require 'csv'
|
8
|
+
require 'rest-client'
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@mysql_connection_pool = {}
|
12
|
+
end
|
13
|
+
######################################### start creation of lab test in lims #####################################################
|
14
|
+
def settings
|
15
|
+
file = File.read(Rails.root.join('db', 'lims_metadata', 'lims_map.json'))
|
16
|
+
JSON.parse(file)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_patient_number
|
20
|
+
get_patient_id = query "SELECT id FROM iblis.patients order by id desc limit 1;"
|
21
|
+
|
22
|
+
get_patient_id.each do |x|
|
23
|
+
return patient_number = x['id']
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_patient_number(patient_id)
|
31
|
+
get_patient_id = query "SELECT patient_number FROM patients WHERE `external_patient_number` ='#{patient_id}'; "
|
32
|
+
|
33
|
+
get_patient_id.each do |x|
|
34
|
+
return patient_number = x['patient_number']
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def filterpatient_number(data)
|
40
|
+
patient_number = 0
|
41
|
+
data.each do |x|
|
42
|
+
patient_number = x['patient_identify']
|
43
|
+
end
|
44
|
+
patient_number
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_patient_dentifier(patient_id)
|
48
|
+
patient_dentifier =PatientIdentifier.where('patient_id= ? AND identifier_type = ?', patient_id,3)[0]
|
49
|
+
patient_dentifier[:identifier]
|
50
|
+
end
|
51
|
+
def create_lab_order(lab_details, clinician_id)
|
52
|
+
external_patient_number = get_patient_dentifier(lab_details[0][:patient_id])
|
53
|
+
patient_number = check_patient_number(external_patient_number)
|
54
|
+
time = Time.new
|
55
|
+
date = time.strftime('%Y-%m-%d %H:%M:%S')
|
56
|
+
lab_details.map do |order_params|
|
57
|
+
if patient_number.blank?
|
58
|
+
patient_number = get_patient_number() + 1
|
59
|
+
|
60
|
+
person_data = Person.where('person_id= ?', order_params[:patient_id])[0]
|
61
|
+
address_data = PersonAddress.where('person_id= ?', order_params[:patient_id])[0]
|
62
|
+
name_data = PersonName.where('person_id= ?', order_params[:patient_id])[0]
|
63
|
+
|
64
|
+
gender = person_data[:gender].match(/f/i) ? 1 : (person_data[:gender].match(/m/i) ? 0 : 2)
|
65
|
+
create_patient(
|
66
|
+
name_data[:given_name],
|
67
|
+
name_data[:family_name],
|
68
|
+
clinician_id[0][:requesting_clinician_id],
|
69
|
+
address_data[:address1],
|
70
|
+
gender,
|
71
|
+
person_data[:birthdate],
|
72
|
+
person_data[:birthdate_estimated],
|
73
|
+
external_patient_number,
|
74
|
+
patient_number,
|
75
|
+
date
|
76
|
+
)
|
77
|
+
end
|
78
|
+
create_visit(patient_number, date)
|
79
|
+
create_specimens(
|
80
|
+
clinician_id[0][:requesting_clinician_id],
|
81
|
+
order_params[:specimen][:name],
|
82
|
+
order_params[:accession_number]
|
83
|
+
)
|
84
|
+
specimen_id = get_specimen_id
|
85
|
+
create_unsync_orders(date, specimen_id)
|
86
|
+
|
87
|
+
create_test(specimen_id, order_params[:requesting_clinician], order_params[:tests][0][:name])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_patient(
|
92
|
+
firstname, surname,
|
93
|
+
user_id, address,
|
94
|
+
gender, dob,
|
95
|
+
dob_estimated, external_patient_number,
|
96
|
+
patient_number, date
|
97
|
+
)
|
98
|
+
query(
|
99
|
+
"INSERT INTO `patients` (`name`, `first_name_code`, `last_name_code`, `created_by`, `address`, `gender`, `patient_number`, `dob`, `dob_estimated`, `external_patient_number`, `created_at`, `updated_at`)
|
100
|
+
VALUES ('#{firstname} #{surname}', SOUNDEX('#{firstname}'), SOUNDEX('#{surname}'), #{user_id}, '#{address}',#{gender},'#{patient_number}', '#{dob}', '#{dob_estimated}', '#{external_patient_number}', '#{date}', '#{date}')"
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def create_visit(patient_number, date)
|
105
|
+
query "INSERT INTO `visits` (`patient_id`, `visit_type`, `ward_or_location`, `created_at`, `updated_at`)
|
106
|
+
VALUES ('#{patient_number}', 'Out Patient', 'EM OPD', '#{date}', '#{date}')"
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_specimens(user_id, specimen_type, tracking_number)
|
110
|
+
specimen_type_id = settings['lims_specimen_map'][specimen_type.to_s]
|
111
|
+
accession_number = new_accession_number
|
112
|
+
# prepare_next_tracking_number()
|
113
|
+
# tracking_number = create_local_tracking_number()
|
114
|
+
query(" INSERT INTO `specimens` (`specimen_type_id`, `accepted_by`, `priority`, `accession_number`, `tracking_number`)
|
115
|
+
VALUES ('#{specimen_type_id}', '#{user_id}', 'Stat', '#{accession_number}', '#{tracking_number}')")
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_unsync_orders(date, specimen_id)
|
119
|
+
query(" INSERT INTO `unsync_orders` (`specimen_id`, `data_not_synced`, `data_level`, `sync_status`, `updated_by_name`, `updated_by_id`, `created_at`, `updated_at`)
|
120
|
+
VALUES ('#{specimen_id}', 'new order', 'specimen', 'not-synced', 'kBLIS Administrator', '1', '#{date}', '#{date}')")
|
121
|
+
end
|
122
|
+
|
123
|
+
def create_test(specimen_id, requested_by, test_type)
|
124
|
+
visit_id = get_visit_id
|
125
|
+
test_type_id = settings['lims_test_type_map'][test_type.to_s]
|
126
|
+
query("INSERT INTO `tests` (`visit_id`, `test_type_id`, `specimen_id`, `test_status_id`, `not_done_reasons`, `person_talked_to_for_not_done`, `created_by`, `requested_by`)
|
127
|
+
VALUES ('#{visit_id}', '#{test_type_id}', '#{specimen_id}', '2', '0', '0', 1, '#{requested_by}')")
|
128
|
+
end
|
129
|
+
|
130
|
+
def new_accession_number
|
131
|
+
# Generate the next accession number for specimen registration
|
132
|
+
@mutex = Mutex.new if @mutex.blank?
|
133
|
+
@mutex.lock
|
134
|
+
max_acc_num = 0
|
135
|
+
return_value = nil
|
136
|
+
sentinel = 99_999_999
|
137
|
+
|
138
|
+
settings = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
|
139
|
+
code = settings['facility_code']
|
140
|
+
year = Date.today.year.to_s[2..3]
|
141
|
+
|
142
|
+
record = get_last_accession_number
|
143
|
+
|
144
|
+
unless record.blank?
|
145
|
+
max_acc_num = record[5..20].match(/\d+/)[0].to_i # first 5 chars are for facility code and 2 digit year
|
146
|
+
end
|
147
|
+
|
148
|
+
if max_acc_num < sentinel
|
149
|
+
max_acc_num += 1
|
150
|
+
else
|
151
|
+
max_acc_num = 1
|
152
|
+
end
|
153
|
+
|
154
|
+
max_acc_num = max_acc_num.to_s.rjust(8, '0')
|
155
|
+
return_value = "#{code}#{year}#{max_acc_num}"
|
156
|
+
@mutex.unlock
|
157
|
+
|
158
|
+
return_value
|
159
|
+
end
|
160
|
+
|
161
|
+
def get_last_accession_number
|
162
|
+
data = query('SELECT * FROM specimens WHERE accession_number IS NOT NULL ORDER BY id DESC LIMIT 1')
|
163
|
+
data.each do |x|
|
164
|
+
return last_accession_number = x['accession_number']
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_specimen_id
|
169
|
+
data = query('SELECT * FROM specimens WHERE accession_number IS NOT NULL ORDER BY id DESC LIMIT 1')
|
170
|
+
data.each do |x|
|
171
|
+
return specimen_id = x['id']
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def get_visit_id
|
176
|
+
data = query('SELECT * FROM visits WHERE id IS NOT NULL ORDER BY id DESC LIMIT 1')
|
177
|
+
data.each do |x|
|
178
|
+
return specimen_id = x['id']
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def prepare_next_tracking_number
|
183
|
+
file = JSON.parse(File.read("#{Rails.root}/public/tracker.json"))
|
184
|
+
todate = Time.now.strftime('%Y%m%d')
|
185
|
+
|
186
|
+
counter = file[todate]
|
187
|
+
counter = counter.to_i + 1
|
188
|
+
fi = {}
|
189
|
+
fi[todate] = counter
|
190
|
+
File.open("#{Rails.root}/public/tracker.json", 'w') do |f|
|
191
|
+
f.write(fi.to_json)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
###### lims tracking number ###############
|
196
|
+
def create_local_tracking_number
|
197
|
+
configs = YAML.load_file "#{Rails.root}/config/application.yml"
|
198
|
+
site_code = configs['facility_code']
|
199
|
+
file = JSON.parse(File.read("#{Rails.root}/public/tracker.json"))
|
200
|
+
todate = Time.now.strftime('%Y%m%d')
|
201
|
+
year = Time.now.strftime('%Y%m%d').to_s.slice(2..3)
|
202
|
+
month = Time.now.strftime('%m')
|
203
|
+
day = Time.now.strftime('%d')
|
204
|
+
|
205
|
+
key = file.keys
|
206
|
+
|
207
|
+
if todate > key[0]
|
208
|
+
|
209
|
+
fi = {}
|
210
|
+
fi[todate] = 1
|
211
|
+
File.open("#{Rails.root}/public/tracker.json", 'w') do |f|
|
212
|
+
f.write(fi.to_json)
|
213
|
+
end
|
214
|
+
|
215
|
+
value = '001'
|
216
|
+
tracking_number = "X#{site_code}#{year}#{get_month(month)}#{get_day(day)}#{value}"
|
217
|
+
|
218
|
+
else
|
219
|
+
counter = file[todate]
|
220
|
+
|
221
|
+
value = if counter.to_s.length == 1
|
222
|
+
'00' + counter.to_s
|
223
|
+
elsif counter.to_s.length == 2
|
224
|
+
'0' + counter.to_s
|
225
|
+
else
|
226
|
+
begin
|
227
|
+
counter.to_s
|
228
|
+
rescue StandardError
|
229
|
+
'001'
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
tracking_number = "X#{site_code}#{year}#{get_month(month)}#{get_day(day)}#{value}"
|
234
|
+
|
235
|
+
end
|
236
|
+
tracking_number
|
237
|
+
end
|
238
|
+
|
239
|
+
def get_month(month)
|
240
|
+
case month
|
241
|
+
|
242
|
+
when '01'
|
243
|
+
'1'
|
244
|
+
when '02'
|
245
|
+
'2'
|
246
|
+
when '03'
|
247
|
+
'3'
|
248
|
+
when '04'
|
249
|
+
'4'
|
250
|
+
when '05'
|
251
|
+
'5'
|
252
|
+
when '06'
|
253
|
+
'6'
|
254
|
+
when '07'
|
255
|
+
'7'
|
256
|
+
when '08'
|
257
|
+
'8'
|
258
|
+
when '09'
|
259
|
+
'9'
|
260
|
+
when '10'
|
261
|
+
'A'
|
262
|
+
when '11'
|
263
|
+
'B'
|
264
|
+
when '12'
|
265
|
+
'C'
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def get_day(day)
|
270
|
+
case day
|
271
|
+
|
272
|
+
when '01'
|
273
|
+
'1'
|
274
|
+
when '02'
|
275
|
+
'2'
|
276
|
+
when '03'
|
277
|
+
'3'
|
278
|
+
when '04'
|
279
|
+
'4'
|
280
|
+
when '05'
|
281
|
+
'5'
|
282
|
+
when '06'
|
283
|
+
'6'
|
284
|
+
when '07'
|
285
|
+
'7'
|
286
|
+
when '08'
|
287
|
+
'8'
|
288
|
+
when '09'
|
289
|
+
'9'
|
290
|
+
when '10'
|
291
|
+
'A'
|
292
|
+
when '11'
|
293
|
+
'B'
|
294
|
+
when '12'
|
295
|
+
'C'
|
296
|
+
when '13'
|
297
|
+
'E'
|
298
|
+
when '14'
|
299
|
+
'F'
|
300
|
+
when '15'
|
301
|
+
'G'
|
302
|
+
when '16'
|
303
|
+
'H'
|
304
|
+
when '17'
|
305
|
+
'Y'
|
306
|
+
when '18'
|
307
|
+
'J'
|
308
|
+
when '19'
|
309
|
+
'K'
|
310
|
+
when '20'
|
311
|
+
'Z'
|
312
|
+
when '21'
|
313
|
+
'M'
|
314
|
+
when '22'
|
315
|
+
'N'
|
316
|
+
when '23'
|
317
|
+
'O'
|
318
|
+
when '24'
|
319
|
+
'P'
|
320
|
+
when '25'
|
321
|
+
'Q'
|
322
|
+
when '26'
|
323
|
+
'R'
|
324
|
+
when '27'
|
325
|
+
'S'
|
326
|
+
when '28'
|
327
|
+
'T'
|
328
|
+
when '29'
|
329
|
+
'V'
|
330
|
+
when '30'
|
331
|
+
'W'
|
332
|
+
when '31'
|
333
|
+
'X'
|
334
|
+
end
|
335
|
+
end
|
336
|
+
############################################# end creation of lab test in lims #####################################################
|
337
|
+
|
338
|
+
############## get results from lims ###############
|
339
|
+
|
340
|
+
def get_lims_test_results(tracking_number,patient_id)
|
341
|
+
external_patient_number = get_patient_dentifier(patient_id)
|
342
|
+
data = query("
|
343
|
+
SELECT
|
344
|
+
visits.ward_or_location, specimens.accession_number,
|
345
|
+
tests.created_by, tests.verified_by,
|
346
|
+
tests.time_completed,tests.requested_by,tests.interpretation,
|
347
|
+
tests.time_created as tests_time_created,
|
348
|
+
test_types.name as test_types_name,
|
349
|
+
test_categories.name as test_categories_name,
|
350
|
+
tests.time_verified as tests_time_verified,
|
351
|
+
users.name as users_name,
|
352
|
+
specimen_types.name as specimen_types_name,
|
353
|
+
specimen_statuses.name as specimen_statuses_name,
|
354
|
+
test_results.result as test_results_result,
|
355
|
+
test_results.device_name as test_results_device_name,
|
356
|
+
measures.name as measures_name,
|
357
|
+
measures.unit as measures_unit,
|
358
|
+
measure_ranges.range_lower as measure_ranges_range_lower,
|
359
|
+
measure_ranges.range_upper as measure_ranges_range_upper
|
360
|
+
FROM iblis.patients
|
361
|
+
inner join iblis.visits on `visits`.`patient_id` = `patients`.`patient_number`
|
362
|
+
inner join iblis.tests on `tests`.`visit_id` = `visits`.`id`
|
363
|
+
inner join iblis.test_types on `test_types`.`id` = `tests`.`test_type_id`
|
364
|
+
inner join iblis.test_categories on `test_categories`.`id` = `test_types`.`test_category_id`
|
365
|
+
inner join iblis.users on `users`.`id` = `tests`.`tested_by`
|
366
|
+
inner join iblis.specimens on `specimens`.`id` = `tests`.`specimen_id`
|
367
|
+
inner join iblis.specimen_types on `specimen_types`.`id` = `specimens`.`specimen_type_id`
|
368
|
+
inner join iblis.specimen_statuses on `specimen_statuses`.`id` = `specimens`.`specimen_status_id`
|
369
|
+
right join iblis.test_results on `test_results`.`test_id` = `tests`.`id`
|
370
|
+
right join iblis.measures on `measures`.`id` = `test_results`.`measure_id`
|
371
|
+
right join iblis.measure_ranges on `measure_ranges`.`measure_id` = `measures`.`id`
|
372
|
+
where `patients`.`deleted_at` is null and `specimens`.`tracking_number` = '#{tracking_number}' and `patients`.`external_patient_number` = '#{external_patient_number}' and `measure_ranges`.`deleted_at`
|
373
|
+
is null group by(`measure_ranges`.`measure_id`) order by time_completed asc ;
|
374
|
+
")
|
375
|
+
data
|
376
|
+
end
|
377
|
+
def get_user_details(user_id)
|
378
|
+
data = query("SELECT * FROM iblis.users where id = #{user_id};")
|
379
|
+
data
|
380
|
+
end
|
381
|
+
############################################# start connection to lims database ######################################################
|
382
|
+
def query(sql)
|
383
|
+
Rails.logger.debug(sql.to_s)
|
384
|
+
result = mysql.query(sql)
|
385
|
+
end
|
386
|
+
|
387
|
+
def mysql
|
388
|
+
# self.initialize
|
389
|
+
return mysql_connection if mysql_connection
|
390
|
+
|
391
|
+
connection = Mysql2::Client.new(host: settings['headers']['host'],
|
392
|
+
username: settings['headers']['username'],
|
393
|
+
password: settings['headers']['password'],
|
394
|
+
port: settings['headers']['port'],
|
395
|
+
database: settings['headers']['database'],
|
396
|
+
reconnect: true)
|
397
|
+
self.mysql_connection = connection
|
398
|
+
end
|
399
|
+
|
400
|
+
def mysql_connection=(connection)
|
401
|
+
@mysql_connection_pool = connection
|
402
|
+
end
|
403
|
+
|
404
|
+
def mysql_connection
|
405
|
+
@mysql_connection_pool
|
406
|
+
end
|
407
|
+
############################################# end connection to lims database ######################################################
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
@@ -23,13 +23,14 @@ module EmrOhspInterface
|
|
23
23
|
result = []
|
24
24
|
#["waoQ016uOz1", "r1AT49VBKqg", "FPN4D0s6K3m", "zE8k2BtValu"]
|
25
25
|
# ds, de_id , <5yrs , >=5yrs
|
26
|
+
puts de
|
26
27
|
if type == "weekly"
|
27
28
|
file = File.open(Rails.root.join("db","idsr_metadata","idsr_weekly_ohsp_ids.csv"))
|
28
29
|
else
|
29
30
|
file = File.open(Rails.root.join("db","idsr_metadata","idsr_monthly_ohsp_ids.csv"))
|
30
31
|
end
|
31
32
|
data = CSV.parse(file,headers: true)
|
32
|
-
row = data.select{|row| row["Data Element Name"].strip.downcase.eql?(de.downcase)}
|
33
|
+
row = data.select{|row| row["Data Element Name"].strip.downcase.eql?(de.downcase.strip)}
|
33
34
|
ohsp_ds_id = row[0]["Data Set ID"]
|
34
35
|
result << ohsp_ds_id
|
35
36
|
ohsp_de_id = row[0]["UID"]
|
@@ -52,13 +53,13 @@ module EmrOhspInterface
|
|
52
53
|
data_set_id = data.first["Data Set ID"]
|
53
54
|
end
|
54
55
|
|
55
|
-
def generate_weekly_idsr_report()
|
56
|
+
def generate_weekly_idsr_report(request=nil,start_date=nil,end_date=nil)
|
56
57
|
|
57
58
|
diag_map = settings["weekly_idsr_map"]
|
58
59
|
|
59
60
|
epi_week = weeks_generator.last.first.strip
|
60
|
-
start_date = weeks_generator.last.last.split("to")[0].strip
|
61
|
-
end_date = weeks_generator.last.last.split("to")[1].strip
|
61
|
+
start_date = weeks_generator.last.last.split("to")[0].strip if start_date.nil?
|
62
|
+
end_date = weeks_generator.last.last.split("to")[1].strip if end_date.nil?
|
62
63
|
|
63
64
|
#pull the data
|
64
65
|
type = EncounterType.find_by_name 'Outpatient diagnosis'
|
@@ -89,11 +90,194 @@ module EmrOhspInterface
|
|
89
90
|
|
90
91
|
collection[key] = options
|
91
92
|
end
|
93
|
+
if request == nil
|
94
|
+
response = send_data(collection,"weekly")
|
95
|
+
end
|
96
|
+
return collection
|
97
|
+
end
|
98
|
+
#idsr monthly report
|
99
|
+
|
100
|
+
def generate_monthly_idsr_report(request=nil,start_date=nil,end_date=nil)
|
101
|
+
diag_map = settings["monthly_idsr_map"]
|
102
|
+
epi_month = months_generator.first.first.strip
|
103
|
+
start_date = months_generator.first.last[1].split("to").first.strip if start_date.nil?
|
104
|
+
end_date = months_generator.first.last[1].split("to").last.strip if end_date.nil?
|
105
|
+
type = EncounterType.find_by_name 'Outpatient diagnosis'
|
106
|
+
collection = {}
|
107
|
+
|
108
|
+
special_indicators = ["Malaria in Pregnancy","HIV New Initiated on ART"]
|
92
109
|
|
93
|
-
|
110
|
+
diag_map.each do |key,value|
|
111
|
+
options = {"<5yrs"=>nil,">=5yrs"=>nil}
|
112
|
+
concept_ids = ConceptName.where(name: value).collect{|cn| cn.concept_id}
|
113
|
+
if !special_indicators.include?(key)
|
114
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
115
|
+
AND encounter_type = ? AND value_coded IN (?)
|
116
|
+
AND concept_id IN(6543, 6542)',
|
117
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
118
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
119
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
120
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
121
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
122
|
+
|
123
|
+
#under_five
|
124
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5}.\
|
125
|
+
collect{|record| record.person_id}
|
126
|
+
options["<5yrs"] = under_five
|
127
|
+
#above 5 years
|
128
|
+
over_five = data.select{|record| calculate_age(record["birthdate"]) >=5 }.\
|
129
|
+
collect{|record| record.person_id}
|
130
|
+
|
131
|
+
options[">=5yrs"] = over_five
|
132
|
+
|
133
|
+
collection[key] = options
|
134
|
+
else
|
135
|
+
if key.eql?("Malaria in Pregnancy")
|
136
|
+
mal_patient_id = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
137
|
+
AND encounter_type = ? AND value_coded IN (?)
|
138
|
+
AND concept_id IN(6543, 6542)',
|
139
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
140
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
141
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
142
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
143
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
144
|
+
|
145
|
+
mal_patient_id= mal_patient_id.collect{|record| record.person_id}
|
146
|
+
#find those that are pregnant
|
147
|
+
preg = Observation.where(["concept_id = 6131 AND obs_datetime
|
148
|
+
BETWEEN ? AND ? AND person_id IN(?)
|
149
|
+
AND value_coded =1065",
|
150
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
151
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),mal_patient_id ])
|
152
|
+
|
153
|
+
options[">=5yrs"] = preg.collect{|record| record.person_id} rescue 0
|
154
|
+
collection[key] = options
|
155
|
+
end
|
156
|
+
|
157
|
+
if key.eql?("HIV New Initiated on ART")
|
158
|
+
data = ActiveRecord::Base.connection.select_all(
|
159
|
+
"SELECT * FROM temp_earliest_start_date
|
160
|
+
WHERE date_enrolled BETWEEN '#{start_date}' AND '#{end_date}'
|
161
|
+
AND date_enrolled = earliest_start_date
|
162
|
+
GROUP BY patient_id" ).to_hash
|
163
|
+
|
164
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
165
|
+
collect{|record| record["patient_id"]}
|
166
|
+
|
167
|
+
over_five = data.select{|record| calculate_age(record["birthdate"]) >=5 }.\
|
168
|
+
collect{|record| record["patient_id"]}
|
169
|
+
|
170
|
+
options["<5yrs"] = under_five
|
171
|
+
options[">=5yrs"] = over_five
|
172
|
+
|
173
|
+
collection[key] = options
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
if request == nil
|
178
|
+
response = send_data(collection,"monthly")
|
179
|
+
end
|
180
|
+
return collection
|
94
181
|
end
|
95
182
|
|
96
|
-
def
|
183
|
+
def generate_hmis_15_report(start_date=nil,end_date=nil)
|
184
|
+
|
185
|
+
diag_map = settings["hmis_15_map"]
|
186
|
+
|
187
|
+
#pull the data
|
188
|
+
type = EncounterType.find_by_name 'Outpatient diagnosis'
|
189
|
+
collection = {}
|
190
|
+
|
191
|
+
special_indicators = ["Malaria - new cases (under 5)",
|
192
|
+
"Malaria - new cases (5 & over)",
|
193
|
+
"HIV confirmed positive (15-49 years) new cases"
|
194
|
+
]
|
195
|
+
|
196
|
+
diag_map.each do |key,value|
|
197
|
+
options = {"ids"=>nil}
|
198
|
+
concept_ids = ConceptName.where(name: value).collect{|cn| cn.concept_id}
|
199
|
+
|
200
|
+
if !special_indicators.include?(key)
|
201
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
202
|
+
AND encounter_type = ? AND value_coded IN (?)
|
203
|
+
AND concept_id IN(6543, 6542)',
|
204
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
205
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
206
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
207
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
208
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
209
|
+
|
210
|
+
# #under_five
|
211
|
+
# under_five = data.select{|record| calculate_age(record["birthdate"]) < 5}.\
|
212
|
+
# collect{|record| record.person_id}
|
213
|
+
# options["<5yrs"] = under_five
|
214
|
+
# #above 5 years
|
215
|
+
# over_five = data.select{|record| calculate_age(record["birthdate"]) >=5 }.\
|
216
|
+
# collect{|record| record.person_id}
|
217
|
+
|
218
|
+
# options[">=5yrs"] = over_five
|
219
|
+
|
220
|
+
all = data.collect{|record| record.person_id}
|
221
|
+
|
222
|
+
|
223
|
+
options["ids"] = all
|
224
|
+
|
225
|
+
collection[key] = options
|
226
|
+
else
|
227
|
+
if key.eql?("Malaria - new cases (under 5)")
|
228
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
229
|
+
AND encounter_type = ? AND value_coded IN (?)
|
230
|
+
AND concept_id IN(6543, 6542)',
|
231
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
232
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
233
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
234
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
235
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
236
|
+
|
237
|
+
under_five = data.select{|record| calculate_age(record["birthdate"]) < 5 }.\
|
238
|
+
collect{|record| record["person_id"]}
|
239
|
+
|
240
|
+
options["ids"] = under_five
|
241
|
+
|
242
|
+
collection[key] = options
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
if key.eql?("Malaria - new cases (5 & over)")
|
247
|
+
data = Encounter.where('encounter_datetime BETWEEN ? AND ?
|
248
|
+
AND encounter_type = ? AND value_coded IN (?)
|
249
|
+
AND concept_id IN(6543, 6542)',
|
250
|
+
start_date.to_date.strftime('%Y-%m-%d 00:00:00'),
|
251
|
+
end_date.to_date.strftime('%Y-%m-%d 23:59:59'),type.id,concept_ids).\
|
252
|
+
joins('INNER JOIN obs ON obs.encounter_id = encounter.encounter_id
|
253
|
+
INNER JOIN person p ON p.person_id = encounter.patient_id').\
|
254
|
+
select('encounter.encounter_type, obs.value_coded, p.*')
|
255
|
+
|
256
|
+
over_and_five = data.select{|record| calculate_age(record["birthdate"]) >= 5 }.\
|
257
|
+
collect{|record| record["person_id"]}
|
258
|
+
|
259
|
+
options["ids"] = over_and_five
|
260
|
+
|
261
|
+
collection[key] = options
|
262
|
+
end
|
263
|
+
|
264
|
+
if key.eql?("HIV confirmed positive (15-49 years) new cases")
|
265
|
+
data = ActiveRecord::Base.connection.select_all(
|
266
|
+
"SELECT * FROM temp_earliest_start_date
|
267
|
+
WHERE date_enrolled BETWEEN '#{start_date}' AND '#{end_date}'
|
268
|
+
AND date_enrolled = earliest_start_date
|
269
|
+
GROUP BY patient_id" ).to_hash
|
270
|
+
|
271
|
+
over_and_15_49 = data.select{|record| calculate_age(record["birthdate"]) >= 15 && calculate_age(record["birthdate"]) <=49 }.\
|
272
|
+
collect{|record| record["patient_id"]}
|
273
|
+
|
274
|
+
options["ids"] = over_and_15_49
|
275
|
+
|
276
|
+
collection[key] = options
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
collection
|
97
281
|
end
|
98
282
|
|
99
283
|
# helper menthod
|
@@ -160,24 +344,56 @@ module EmrOhspInterface
|
|
160
344
|
"orgUnit"=> get_ohsp_facility_id,
|
161
345
|
"dataValues"=> []
|
162
346
|
}
|
347
|
+
special = ["Severe Pneumonia in under 5 cases","Malaria in Pregnancy",
|
348
|
+
"Underweight Newborns < 2500g in Under 5 Cases","Diarrhoea In Under 5"]
|
163
349
|
|
164
350
|
data.each do |key,value|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
351
|
+
if !special.include?(key)
|
352
|
+
option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
353
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
|
354
|
+
"value"=>value["<5yrs"].size }
|
355
|
+
|
356
|
+
option2 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
357
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[3],
|
358
|
+
"value"=>value[">=5yrs"].size}
|
359
|
+
|
360
|
+
#fill data values array
|
361
|
+
payload["dataValues"] << option1
|
362
|
+
payload["dataValues"] << option2
|
363
|
+
else
|
364
|
+
case key
|
365
|
+
when special[0]
|
366
|
+
option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
367
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
|
368
|
+
"value"=>value["<5yrs"].size }
|
369
|
+
|
370
|
+
payload["dataValues"] << option1
|
371
|
+
when special[1]
|
372
|
+
option2 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
373
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[3],
|
374
|
+
"value"=>value[">=5yrs"].size }
|
375
|
+
|
376
|
+
payload["dataValues"] << option2
|
377
|
+
when special[2]
|
378
|
+
option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
379
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
|
380
|
+
"value"=>value["<5yrs"].size }
|
381
|
+
|
382
|
+
payload["dataValues"] << option1
|
383
|
+
when special[3]
|
384
|
+
option1 = {"dataElement"=>get_ohsp_de_ids(key,type)[1],
|
385
|
+
"categoryOptionCombo"=> get_ohsp_de_ids(key,type)[2],
|
386
|
+
"value"=>value["<5yrs"].size}
|
387
|
+
|
388
|
+
payload["dataValues"] << option1
|
389
|
+
end
|
390
|
+
end
|
176
391
|
end
|
177
392
|
|
178
|
-
puts "now sending these values: #{payload.
|
393
|
+
puts "now sending these values: #{payload.to_json}"
|
179
394
|
url = "#{conn["url"]}/api/dataValueSets"
|
180
395
|
puts url
|
396
|
+
puts "pushing #{type} IDSR Reports"
|
181
397
|
send = RestClient::Request.execute(method: :post,
|
182
398
|
url: url,
|
183
399
|
headers:{'Content-Type'=> 'application/json'},
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
EmrOhspInterface::Engine.routes.draw do
|
2
|
-
resources :
|
2
|
+
resources :emr_lims_interface, path: 'api/v1/emr_lims_interface'
|
3
|
+
get '/get_lims_user', to: 'emr_lims_interface#get_user_info'
|
3
4
|
get '/get_weeks', to: 'emr_ohsp_interface#weeks_generator'
|
4
5
|
get '/get_months', to: 'emr_ohsp_interface#months_generator'
|
6
|
+
get '/generate_weekly_idsr_report', to: 'emr_ohsp_interface#generate_weekly_idsr_report'
|
7
|
+
get '/generate_monthly_idsr_report', to: 'emr_ohsp_interface#generate_monthly_idsr_report'
|
8
|
+
get '/generate_hmis_15_report', to: 'emr_ohsp_interface#generate_hmis_15_report'
|
5
9
|
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.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Justin Manda
|
7
|
+
- Justin Manda and Petros Kayange
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-06 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
|
77
|
+
- justinmandah@gmail.com, kayangepetros@gmail.com
|
78
78
|
executables: []
|
79
79
|
extensions: []
|
80
80
|
extra_rdoc_files: []
|
@@ -86,11 +86,13 @@ files:
|
|
86
86
|
- app/assets/javascripts/emr_ohsp_interface/application.js
|
87
87
|
- app/assets/stylesheets/emr_ohsp_interface/application.css
|
88
88
|
- app/controllers/emr_ohsp_interface/application_controller.rb
|
89
|
+
- app/controllers/emr_ohsp_interface/emr_lims_interface_controller.rb
|
89
90
|
- app/controllers/emr_ohsp_interface/emr_ohsp_interface_controller.rb
|
90
91
|
- app/helpers/emr_ohsp_interface/application_helper.rb
|
91
92
|
- app/jobs/emr_ohsp_interface/application_job.rb
|
92
93
|
- app/mailers/emr_ohsp_interface/application_mailer.rb
|
93
94
|
- app/models/emr_ohsp_interface/application_record.rb
|
95
|
+
- app/services/emr_ohsp_interface/emr_lims_interface_service.rb
|
94
96
|
- app/services/emr_ohsp_interface/emr_ohsp_interface_service.rb
|
95
97
|
- app/views/layouts/emr_ohsp_interface/application.html.erb
|
96
98
|
- config/routes.rb
|
@@ -118,9 +120,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
120
|
- !ruby/object:Gem::Version
|
119
121
|
version: '0'
|
120
122
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
123
|
+
rubygems_version: 3.2.32
|
122
124
|
signing_key:
|
123
125
|
specification_version: 4
|
124
|
-
summary: This in a gem that facilitates interfacing of EMR
|
125
|
-
Platform
|
126
|
+
summary: This in a gem that facilitates interfacing of EMR, One Health Surveillance
|
127
|
+
Platform and Lims
|
126
128
|
test_files: []
|