his_emr_api_lab 1.1.23 → 1.1.25

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: 629116134d63ff0d2d3da97b80b0b9f4a3249483e5d57f43d4f332a645ce35e5
4
- data.tar.gz: 414d3a1a4647e666599f71fca7e9026a034f210fbf6080da5cc501bb47c2e24f
3
+ metadata.gz: 93d57cd7dd12e53d88dbb8dda693c6472d52312e5115453d739cdeeab0a28eee
4
+ data.tar.gz: ee71326f52f9ad6a36ee153658987943746ab3bdbe15e58543f1041bd568b319
5
5
  SHA512:
6
- metadata.gz: b5bf3f01293464ab6f0be71a8707ab6b57801a371375f1bd6a2fae9812da72d4cba323a5b783e68f9b770db0f6e21c9a39162d89d3004add6b6a8327f7033cf1
7
- data.tar.gz: 6c09429e8520fc49459c40737214e1c538079cdacf2b715a9dc856d32bf2b562a8e68a4d5ad9f97bfbe3ead532484f510cc944986475978090755787d118c6f2
6
+ metadata.gz: 3386853e1bb7b9092e464ad608b901fa0ca78b2981e34b80269c9e2af98242b8215a87ababd824e9dc2774f87fd77d4df8f927d06d50383257fcb02510a4070b
7
+ data.tar.gz: 97c06feb45b3766e37b5c07c4e5f98818f484d07d9bd68e74f5f891c5e07acc0de7cc35ae0c2f60a8f0ef98186865df38dabfee017c959566e4c6099c9255802
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lab
4
+ class LabAcknowledgement < ::LimsAcknowledgementStatus
5
+ end
6
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lab
4
+ # acknoledgement service for creating lab acknowledgements
5
+ module AcknowledgementService
6
+ class << self
7
+ def create_acknowledgement(params)
8
+ order = Order.find(params[:order_id])
9
+ Lab::LabAcknowledgement.create!(order_id: order.id, test: params[:test], pushed: false,
10
+ acknowledgement_type: params[:entered_by] == 'LIMS' ? 'test_results_delivered_to_site_electronically' : 'test_results_delivered_to_site_manually',
11
+ date_received: params[:date_received])
12
+ end
13
+
14
+ def acknowledgements_pending_sync(batch_size)
15
+ Lab::LabAcknowledgement.where(pushed: false)
16
+ .limit(batch_size)
17
+ end
18
+
19
+ def push_acknowledgement(acknowledgement, lims_api)
20
+ Rails.logger.info("Pushing acknowledgement ##{acknowledgement.order_id}")
21
+
22
+ acknowledgement_dto = Lab::Lims::AcknowledgementSerializer.serialize_acknowledgement(acknowledgement)
23
+ mapping = Lab::LimsOrderMapping.find_by(order_id: acknowledgement.order_id)
24
+
25
+ ActiveRecord::Base.transaction do
26
+ if mapping
27
+ Rails.logger.info("Updating acknowledgement ##{acknowledgement_dto[:tracking_number]} in LIMS")
28
+ response = lims_api.acknowledge(acknowledgement_dto)
29
+ Rails.logger.info("Info #{response}")
30
+ if response['status'] == 200 || response['message'] == 'results already delivered for test name given'
31
+ acknowledgement.pushed = true
32
+ acknowledgement.date_pushed = Time.now
33
+ acknowledgement.save!
34
+ else
35
+ Rails.logger.error("Failed to process acknowledgement for tracking number ##{acknowledgement_dto[:tracking_number]} in LIMS")
36
+ end
37
+ else
38
+ Rails.logger.info("No mapping found for acknowledgement ##{acknowledgement_dto[:tracking_number]}")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lab
4
+ module Lims
5
+ ##
6
+ # Serialize a Lab::LabResult to LIMS' acknowledgement format
7
+ module AcknowledgementSerializer
8
+ class << self
9
+ include Utils
10
+
11
+ def serialize_acknowledgement(acknowledgement)
12
+ serialized_acknowledgement = Lims::Utils.structify(acknowledgement)
13
+ {
14
+ tracking_number: Lab::LabOrder.find(serialized_acknowledgement.order_id).accession_number,
15
+ test: ::ConceptName.where(concept_id: serialized_acknowledgement.test, concept_name_type: nil).first.name,
16
+ date_acknowledged: format_date(serialized_acknowledgement.date_received),
17
+ recipient_type: serialized_acknowledgement.acknowledgement_type
18
+ }
19
+ end
20
+
21
+ private
22
+
23
+ def format_date(date)
24
+ date.strftime('%Y%m%d %H:%M:%S')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lab
4
+ module Lims
5
+ # This class is responsible for handling the acknowledgement of lab orders
6
+ class AcknowledgementWorker
7
+ attr_reader :lims_api
8
+
9
+ include Utils # for logger
10
+
11
+ SECONDS_TO_WAIT_FOR_ORDERS = 30
12
+
13
+ def initialize(lims_api)
14
+ @lims_api = lims_api
15
+ end
16
+
17
+ def push_acknowledgement(batch_size: 1000, wait: false)
18
+ loop do
19
+ logger.info('Looking for new acknowledgements to push to LIMS...')
20
+ acknowledgements = Lab::AcknowledgementService.acknowledgements_pending_sync(batch_size).all
21
+
22
+ logger.debug("Found #{acknowledgements.size} acknowledgements...")
23
+ acknowledgements.each do |acknowledgement|
24
+ Lab::AcknowledgementService.push_acknowledgement(acknowledgement, @lims_api)
25
+ rescue GatewayError => e
26
+ logger.error("Failed to push acknowledgement ##{acknowledgement.order_id}: #{e.class} - #{e.message}")
27
+ end
28
+
29
+ break unless wait
30
+
31
+ logger.info('Waiting for acknowledgements...')
32
+ sleep(Lab::Lims::Config.updates_poll_frequency)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -32,6 +32,15 @@ class Lab::Lims::Api::RestApi
32
32
  )
33
33
  end
34
34
 
35
+ def acknowledge(acknowledgement_dto)
36
+ Rails.logger.info("Acknowledging order ##{acknowledgement_dto} in LIMS")
37
+ response = in_authenticated_session do |headers|
38
+ RestClient.post(expand_uri('/acknowledge/test/results/recipient'), acknowledgement_dto, headers)
39
+ end
40
+ Rails.logger.info("Acknowledged order ##{acknowledgement_dto} in LIMS. Response: #{response}")
41
+ JSON.parse(response)
42
+ end
43
+
35
44
  def update_order(_id, order_dto)
36
45
  in_authenticated_session do |headers|
37
46
  RestClient.post(expand_uri('update_order'), make_update_params(order_dto), headers)
@@ -191,6 +200,7 @@ class Lab::Lims::Api::RestApi
191
200
  arv_number: order_dto.fetch(:patient).fetch(:arv_number),
192
201
  art_regimen: order_dto.fetch(:patient).fetch(:art_regimen),
193
202
  art_start_date: order_dto.fetch(:patient).fetch(:art_start_date),
203
+ date_of_birth: order_dto.fetch(:patient).fetch(:dob),
194
204
  national_patient_id: order_dto.fetch(:patient).fetch(:id),
195
205
  requesting_clinician: requesting_clinician(order_dto),
196
206
  sample_type: order_dto.fetch(:sample_type),
@@ -380,7 +390,7 @@ class Lab::Lims::Api::RestApi
380
390
  orders_without_specimen(patient_id).each { |order| orders[order.order_id] = order }
381
391
  orders_without_results(patient_id).each { |order| orders[order.order_id] = order }
382
392
  orders_without_reason(patient_id).each { |order| orders[order.order_id] = order }
383
-
393
+
384
394
  orders.values
385
395
  end
386
396
 
@@ -67,6 +67,7 @@ module Lab
67
67
  arv_number: find_arv_number(patient_id),
68
68
  art_regimen: find_current_regimen(patient_id),
69
69
  art_start_date: find_art_start_date(patient_id),
70
+ dob: person.birthdate,
70
71
  phone_number: phone_number&.value || 'Unknown',
71
72
  gender: person.gender,
72
73
  email: nil
@@ -14,6 +14,7 @@ module Lab
14
14
 
15
15
  fork(&method(:start_push_worker))
16
16
  fork(&method(:start_pull_worker))
17
+ fork(&method(:start_acknowledgement_worker))
17
18
  fork(&method(:start_realtime_pull_worker)) if realtime_updates_enabled?
18
19
 
19
20
  Process.waitall
@@ -27,6 +28,13 @@ module Lab
27
28
  end
28
29
  end
29
30
 
31
+ def self.start_acknowledgement_worker
32
+ start_worker('acknowledgement_worker') do
33
+ worker = AcknowledgementWorker.new(lims_api)
34
+ worker.push_acknowledgement
35
+ end
36
+ end
37
+
30
38
  def self.start_pull_worker
31
39
  start_worker('pull_worker') do
32
40
  worker = PullWorker.new(lims_api)
@@ -136,7 +136,7 @@ module Lab
136
136
  patient_id: encounter.patient_id,
137
137
  start_date: params[:date]&.to_date || Date.today,
138
138
  auto_expire_date: params[:end_date],
139
- accession_number: params[:accession_number] || next_accession_number,
139
+ accession_number: params[:accession_number] || next_accession_number(params[:date]&.to_date || Date.today),
140
140
  orderer: User.current&.user_id
141
141
  )
142
142
  end
@@ -32,22 +32,30 @@ module Lab
32
32
 
33
33
  serializer = Lab::ResultSerializer.serialize(results_obs)
34
34
  end
35
- NotificationService.new.create_notification(result_enter_by, prepare_notification_message(results_obs, serializer, result_enter_by))
35
+ process_acknowledgement(results_obs, result_enter_by)
36
+ precess_notification_message(results_obs, serializer, result_enter_by)
36
37
  Rails.logger.info("Lab::ResultsService: Result created for test #{test_id} #{serializer}")
37
38
  serializer
38
39
  end
39
40
 
40
41
  private
41
42
 
42
- def prepare_notification_message(result, values, result_enter_by)
43
+ def precess_notification_message(result, values, result_enter_by)
43
44
  order = Order.find(result.order_id)
44
- { Type: result_enter_by,
45
- 'Test type': ConceptName.find_by(concept_id: result.test.value_coded)&.name,
46
- 'Accession number': order&.accession_number,
47
- 'ARV-Number': find_arv_number(result.person_id),
48
- PatientID: result.person_id,
49
- 'Ordered By': order&.provider&.person&.name,
50
- Result: values }.as_json
45
+ data = { Type: result_enter_by,
46
+ 'Test type': ConceptName.find_by(concept_id: result.test.value_coded)&.name,
47
+ 'Accession number': order&.accession_number,
48
+ 'ARV-Number': find_arv_number(result.person_id),
49
+ PatientID: result.person_id,
50
+ 'Ordered By': order&.provider&.person&.name,
51
+ Result: values }.as_json
52
+ NotificationService.new.create_notification(result_enter_by, data)
53
+ end
54
+
55
+ def process_acknowledgement(results, results_enter_by)
56
+ Lab::AcknowledgementService.create_acknowledgement({ order_id: results.order_id, test: results.test.value_coded,
57
+ date_received: Time.now,
58
+ entered_by: results_enter_by })
51
59
  end
52
60
 
53
61
  def find_arv_number(patient_id)
data/lib/lab/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lab
4
- VERSION = '1.1.23'
4
+ VERSION = '1.1.25'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: his_emr_api_lab
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.23
4
+ version: 1.1.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elizabeth Glaser Pediatric Foundation Malawi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-14 00:00:00.000000000 Z
11
+ date: 2022-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: couchrest
@@ -254,6 +254,7 @@ files:
254
254
  - app/mailers/lab/application_mailer.rb
255
255
  - app/models/lab/application_record.rb
256
256
  - app/models/lab/lab_accession_number_counter.rb
257
+ - app/models/lab/lab_acknowledgement.rb
257
258
  - app/models/lab/lab_encounter.rb
258
259
  - app/models/lab/lab_order.rb
259
260
  - app/models/lab/lab_result.rb
@@ -264,8 +265,11 @@ files:
264
265
  - app/serializers/lab/result_serializer.rb
265
266
  - app/serializers/lab/test_serializer.rb
266
267
  - app/services/lab/accession_number_service.rb
268
+ - app/services/lab/acknowledgement_service.rb
267
269
  - app/services/lab/concepts_service.rb
268
270
  - app/services/lab/labelling_service/order_label.rb
271
+ - app/services/lab/lims/acknowledgement_serializer.rb
272
+ - app/services/lab/lims/acknowledgement_worker.rb
269
273
  - app/services/lab/lims/api/blackhole_api.rb
270
274
  - app/services/lab/lims/api/couchdb_api.rb
271
275
  - app/services/lab/lims/api/mysql_api.rb