his_emr_api_lab 1.1.1 → 1.1.5

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: 360c214f3f26b5b18d01d1857d5ade3fa0dda1ddb54c846c44fcb354f6d47971
4
- data.tar.gz: 7b74dc551624446991404886012f19260411d90f1aa12e092fc89418e607e81f
3
+ metadata.gz: 960dc05ef6fbcddc4538762d7c7f3369e77d2f24b879e14a110ffa4ab2141d22
4
+ data.tar.gz: 666ea51bb7ff2938b6d4fd733a619a49cf600aed37c330c8be3f9680bdc4e94e
5
5
  SHA512:
6
- metadata.gz: 389813d90f57dca1542f698dcf6e10a396a8d5ad25f0aa29fc2f1cf668d5a2d38fb24f0810fc79ca88dab08b19ee98048ffa068f88745b40965f1e1e710a428f
7
- data.tar.gz: 743cb12464310c16dfde6e37ce931253479d7394961a48bf86a9350e3254bfcb2ab608f2f84076c6739936c6b31642453997e6cf3b101d1607da01f17456b89e
6
+ metadata.gz: 3ba9d9cb6d59d656b8d72190d6ecb1bcf6c193fdeb22121608ec39fb2fbb77e1b11e2b53d45d8937f6969cb1212e1adb045bb4a53e76f1eefa825731c2abcb98
7
+ data.tar.gz: 6e27abac8e38b86238adecf6eec31e3cad2503b5d46e534b498b47cad563cf15ebacf74fdc66c552338ebc584e3f08c331480cb57be14df5951c297ce642a44a
@@ -12,9 +12,22 @@ module Lab
12
12
  User.current = Lab::Lims::Utils.lab_user
13
13
  Location.current = Location.find_by_name('ART clinic')
14
14
 
15
- lims_api = Lab::Lims::Api::RestApi.new(Lab::Lims::Config.rest_api)
16
- worker = Lab::Lims::PullWorker.new(lims_api)
17
- worker.pull_orders(patient_id: patient_id)
15
+ lockfile = Rails.root.join('tmp', "update-patient-orders-#{patient_id}.lock")
16
+
17
+ done = File.open(lockfile, File::RDWR | File::CREAT) do |lock|
18
+ unless lock.flock(File::LOCK_NB | File::LOCK_EX)
19
+ Rails.logger.info('Another update patient job is already running...')
20
+ break false
21
+ end
22
+
23
+ lims_api = Lab::Lims::Api::RestApi.new(Lab::Lims::Config.rest_api)
24
+ worker = Lab::Lims::PullWorker.new(lims_api)
25
+ worker.pull_orders(patient_id: patient_id)
26
+
27
+ true
28
+ end
29
+
30
+ File.unlink(lockfile) if done
18
31
  end
19
32
  end
20
33
  end
@@ -38,6 +38,9 @@ module Lab
38
38
  end
39
39
 
40
40
  def create_order(order)
41
+ order = order.dup
42
+ order.delete('_id')
43
+
41
44
  bum.couch_rest :post, '/', order
42
45
  end
43
46
 
@@ -22,14 +22,13 @@ class Lab::Lims::Api::RestApi
22
22
  end
23
23
  end
24
24
 
25
- update_order_results(order_dto)
26
-
27
- data = JSON.parse(response.body)['data']
25
+ data = JSON.parse(response.body)
26
+ update_order_results(order_dto) unless data['message'].casecmp?('Order already available')
28
27
 
29
28
  ActiveSupport::HashWithIndifferentAccess.new(
30
- id: data['tracking_number'],
29
+ id: order_dto.fetch(:_id, order_dto[:tracking_number]),
31
30
  rev: 0,
32
- tracking_number: data['tracking_number']
31
+ tracking_number: order_dto[:tracking_number]
33
32
  )
34
33
  end
35
34
 
@@ -44,21 +43,25 @@ class Lab::Lims::Api::RestApi
44
43
  end
45
44
 
46
45
  def consume_orders(*_args, patient_id: nil, **_kwargs)
47
- Rails.logger.info('Looking for orders without results...')
48
- orders = Lab::OrdersSearchService.find_orders_without_results(patient_id: patient_id)
46
+ orders_pending_updates(patient_id).each do |order|
47
+ order_dto = Lab::Lims::OrderSerializer.serialize_order(order)
49
48
 
50
- orders.each do |order|
51
- response = in_authenticated_session do |headers|
52
- Rails.logger.info("Fetching results for order ##{order.accession_number}")
53
- RestClient.get(expand_uri("query_results_by_tracking_number/#{order.accession_number}"), headers)
49
+ if order_dto['priority'].nil? || order_dto['sample_type'].casecmp?('not_specified')
50
+ patch_order_dto_with_lims_order!(order_dto, find_lims_order(order.accession_number))
54
51
  end
55
52
 
56
- Rails.logger.info("Result for order ##{order.accession_number} found... Parsing...")
57
- results = JSON.parse(response).fetch('data').fetch('results')
58
- order_dto = Lab::Lims::OrderSerializer.serialize_order(order)
59
- yield lims_results_to_order_dto(results, order_dto), OpenStruct.new(last_seq: 0)
60
- rescue InvalidParameters => e # LIMS responds with a 401 when a result is not found :(
61
- Rails.logger.error("Failed to fetch results for ##{order.accession_number}: #{e.message}")
53
+ if order_dto['test_results'].empty?
54
+ begin
55
+ patch_order_dto_with_lims_results!(order_dto, find_lims_results(order.accession_number))
56
+ rescue InvalidParameters => e # LIMS responds with a 401 when a result is not found :(
57
+ Rails.logger.error("Failed to fetch results for ##{order.accession_number}: #{e.message}")
58
+ end
59
+ end
60
+
61
+ yield order_dto, OpenStruct.new(last_seq: 0)
62
+ rescue LimsApiError => e
63
+ Rails.logger.error("Failed to fetch updates for ##{order.accession_number}: #{e.class} - #{e.message}")
64
+ sleep(1)
62
65
  end
63
66
  end
64
67
 
@@ -105,8 +108,8 @@ class Lab::Lims::Api::RestApi
105
108
  self.authentication_token = nil
106
109
  retry if (retries -= 1).positive?
107
110
  rescue RestClient::ExceptionWithResponse => e
108
- Rails.logger.error("LIMS Error: #{e.response.code} - #{e.response.body}")
109
- raise e unless e.response.code == 401
111
+ Rails.logger.error("LIMS Error: #{e.response&.code} - #{e.response&.body}")
112
+ raise e unless e.response&.code == 401
110
113
 
111
114
  self.authentication_token = nil
112
115
  retry if (retries -= 1).positive?
@@ -117,7 +120,8 @@ class Lab::Lims::Api::RestApi
117
120
  password = config.fetch(:password)
118
121
 
119
122
  Rails.logger.debug("Authenticating with LIMS as: #{username}")
120
- response = RestClient.get(expand_uri("re_authenticate/#{username}/#{password}"), headers: { 'Content-type' => 'application/json' })
123
+ response = RestClient.get(expand_uri("re_authenticate/#{username}/#{password}"),
124
+ headers: { 'Content-type' => 'application/json' })
121
125
  response_body = JSON.parse(response.body)
122
126
 
123
127
  if response_body['status'] == 401
@@ -153,9 +157,7 @@ class Lab::Lims::Api::RestApi
153
157
 
154
158
  Rails.logger.error("Lims Api Error: #{response.body}")
155
159
 
156
- if body['status'] != 401
157
- raise LimsApiError, "#{body['status']} - #{body['message']}"
158
- end
160
+ raise LimsApiError, "#{body['status']} - #{body['message']}" if body['status'] != 401
159
161
 
160
162
  if body['message'].match?(/token expired/i)
161
163
  raise AuthenticationTokenExpired, "Authentication token expired: #{body['message']}"
@@ -255,11 +257,31 @@ class Lab::Lims::Api::RestApi
255
257
  "#{orderer[:first_name]} #{orderer[:last_name]}"
256
258
  end
257
259
 
260
+ def find_lims_order(tracking_number)
261
+ response = in_authenticated_session do |headers|
262
+ Rails.logger.info("Fetching order ##{tracking_number}")
263
+ RestClient.get(expand_uri("query_order_by_tracking_number/#{tracking_number}"), headers)
264
+ end
265
+
266
+ Rails.logger.info("Order ##{tracking_number} found... Parsing...")
267
+ JSON.parse(response).fetch('data')
268
+ end
269
+
270
+ def find_lims_results(tracking_number)
271
+ response = in_authenticated_session do |headers|
272
+ Rails.logger.info("Fetching results for order ##{tracking_number}")
273
+ RestClient.get(expand_uri("query_results_by_tracking_number/#{tracking_number}"), headers)
274
+ end
275
+
276
+ Rails.logger.info("Result for order ##{tracking_number} found... Parsing...")
277
+ JSON.parse(response).fetch('data').fetch('results')
278
+ end
279
+
258
280
  ##
259
281
  # Make a copy of the order_dto with the results from LIMS parsed
260
282
  # and appended to it.
261
- def lims_results_to_order_dto(results, order_dto)
262
- order_dto.merge(
283
+ def patch_order_dto_with_lims_results!(order_dto, results)
284
+ order_dto.merge!(
263
285
  '_id' => order_dto[:tracking_number],
264
286
  '_rev' => 0,
265
287
  'test_results' => results.each_with_object({}) do |result, formatted_results|
@@ -277,10 +299,16 @@ class Lab::Lims::Api::RestApi
277
299
  )
278
300
  end
279
301
 
302
+ def patch_order_dto_with_lims_order!(order_dto, lims_order)
303
+ order_dto.merge!(
304
+ 'sample_type' => lims_order['other']['sample_type'],
305
+ 'sample_status' => lims_order['other']['specimen_status'],
306
+ 'priority' => lims_order['other']['priority']
307
+ )
308
+ end
309
+
280
310
  def update_order_results(order_dto)
281
- if order_dto['test_results'].nil? || order_dto['test_results'].empty?
282
- return nil
283
- end
311
+ return nil if order_dto['test_results'].nil? || order_dto['test_results'].empty?
284
312
 
285
313
  order_dto['test_results'].each do |test_name, results|
286
314
  Rails.logger.info("Pushing result for order ##{order_dto['tracking_number']}")
@@ -341,4 +369,40 @@ class Lab::Lims::Api::RestApi
341
369
  test_status: 'voided'
342
370
  }
343
371
  end
372
+
373
+ def orders_pending_updates(patient_id = nil)
374
+ Rails.logger.info('Looking for orders that need to be updated...')
375
+ orders = {}
376
+
377
+ orders_without_specimen(patient_id).each { |order| orders[order.order_id] = order }
378
+ orders_without_results(patient_id).each { |order| orders[order.order_id] = order }
379
+ orders_without_reason(patient_id).each { |order| orders[order.order_id] = order }
380
+
381
+ orders.values
382
+ end
383
+
384
+ def orders_without_specimen(patient_id = nil)
385
+ Rails.logger.debug('Looking for orders without a specimen')
386
+ unknown_specimen = ConceptName.where(name: Lab::Metadata::UNKNOWN_SPECIMEN)
387
+ .select(:concept_id)
388
+ orders = Lab::LabOrder.where(concept_id: unknown_specimen)
389
+ orders = orders.where(patient_id: patient_id) if patient_id
390
+
391
+ orders
392
+ end
393
+
394
+ def orders_without_results(patient_id = nil)
395
+ Rails.logger.debug('Looking for orders without a result')
396
+ Lab::OrdersSearchService.find_orders_without_results(patient_id: patient_id)
397
+ end
398
+
399
+ def orders_without_reason(patient_id = nil)
400
+ Rails.logger.debug('Looking for orders without a reason for test')
401
+ orders = Lab::LabOrder.joins(:reason_for_test)
402
+ .merge(Observation.where(value_coded: nil, value_text: nil))
403
+ .limit(1000)
404
+ orders = orders.where(patient_id: patient_id) if patient_id
405
+
406
+ orders
407
+ end
344
408
  end
@@ -11,15 +11,19 @@ module Lab
11
11
  class ConfigNotFound < RuntimeError; end
12
12
 
13
13
  class << self
14
+ def preferred_api
15
+ emr_api_application('lims_api', 'couchdb')
16
+ end
17
+
14
18
  ##
15
19
  # Returns LIMS' couchdb configuration file for the current environment (Rails.env)
16
20
  def couchdb
17
21
  config_path = begin
18
- find_config_path('couchdb.yml')
19
- rescue ConfigNotFound => e
20
- Rails.logger.error("Failed to find default LIMS couchdb config: #{e.message}")
21
- find_config_path('couchdb-lims.yml') # This can be placed in HIS-EMR-API/config
22
- end
22
+ find_config_path('couchdb.yml')
23
+ rescue ConfigNotFound => e
24
+ Rails.logger.error("Failed to find default LIMS couchdb config: #{e.message}")
25
+ find_config_path('couchdb-lims.yml') # This can be placed in HIS-EMR-API/config
26
+ end
23
27
 
24
28
  Rails.logger.debug("Using LIMS couchdb config: #{config_path}")
25
29
 
@@ -64,9 +68,7 @@ module Lab
64
68
  @emr_api_application ||= YAML.load_file(Rails.root.join('config', 'application.yml'))
65
69
 
66
70
  @emr_api_application.fetch(param) do
67
- unless fallback
68
- raise ConfigNotFound, "Missing config param: #{param}"
69
- end
71
+ raise ConfigNotFound, "Missing config param: #{param}" unless fallback
70
72
 
71
73
  fallback
72
74
  end
@@ -83,9 +85,7 @@ module Lab
83
85
  Rails.root.parent.join("nlims_controller/config/#{filename}")
84
86
  ]
85
87
 
86
- if filename == 'couchdb.yml'
87
- paths = [Rails.root.join('config/lims-couchdb.yml'), *paths]
88
- end
88
+ paths = [Rails.root.join('config/lims-couchdb.yml'), *paths] if filename == 'couchdb.yml'
89
89
 
90
90
  paths.each do |path|
91
91
  Rails.logger.debug("Looking for LIMS couchdb config at: #{path}")
@@ -22,7 +22,7 @@ module Lab
22
22
  date: start_date,
23
23
  target_lab: facility_name(self['receiving_facility']),
24
24
  order_location: facility_name(self['sending_facility']),
25
- reason_for_test: reason_for_test
25
+ reason_for_test_id: reason_for_test
26
26
  )
27
27
  end
28
28
 
@@ -83,9 +83,14 @@ module Lab
83
83
 
84
84
  # Translates a LIMS sample priority to a concept_id
85
85
  def reason_for_test
86
- return unknown_concept.concept_id unless self['priority']
86
+ return nil unless self['priority']
87
87
 
88
- ConceptName.find_by_name!(self['priority']).concept_id
88
+ name = case self['priority']
89
+ when %r{Reapet / Missing}i then 'Repeat / Missing'
90
+ else self['priority']
91
+ end
92
+
93
+ ConceptName.find_by_name!(name).concept_id
89
94
  end
90
95
 
91
96
  def lab_program
@@ -16,6 +16,7 @@ module Lab
16
16
  serialized_order = Lims::Utils.structify(Lab::LabOrderSerializer.serialize_order(order))
17
17
 
18
18
  Lims::OrderDTO.new(
19
+ _id: Lab::LimsOrderMapping.find_by(order: order)&.lims_id || serialized_order.accession_number,
19
20
  tracking_number: serialized_order.accession_number,
20
21
  sending_facility: current_facility_name,
21
22
  receiving_facility: serialized_order.target_lab,
@@ -63,7 +64,7 @@ module Lab
63
64
  first_name: name&.given_name,
64
65
  last_name: name&.family_name,
65
66
  id: national_id&.identifier,
66
- phone_number: phone_number&.value,
67
+ phone_number: phone_number&.value || 'Unknown',
67
68
  gender: person.gender,
68
69
  email: nil
69
70
  }
@@ -82,9 +83,7 @@ module Lab
82
83
  end
83
84
 
84
85
  def format_sample_status_trail(order)
85
- if order.concept_id == ConceptName.find_by_name!('Unknown').concept_id
86
- return []
87
- end
86
+ return [] if order.concept_id == ConceptName.find_by_name!('Unknown').concept_id
88
87
 
89
88
  user = User.find(order.discontinued_by || order.creator)
90
89
  drawn_by = PersonName.find_by_person_id(user.user_id)
@@ -176,7 +176,7 @@ module Lab
176
176
  def update_order(patient, order_id, order_dto)
177
177
  logger.debug("Updating order ##{order_dto['_id']}")
178
178
  order = OrdersService.update_order(order_id, order_dto.to_order_service_params(patient_id: patient.patient_id)
179
- .merge(force_update: true))
179
+ .merge(force_update: 'true'))
180
180
  unless order_dto['test_results'].empty?
181
181
  update_results(order, order_dto['test_results'])
182
182
  end
@@ -194,7 +194,7 @@ module Lab
194
194
  next
195
195
  end
196
196
 
197
- next unless test_results['results']
197
+ next if test.result || test_results['results'].blank?
198
198
 
199
199
  measures = test_results['results'].map do |indicator, value|
200
200
  measure = find_measure(order, indicator, value)
@@ -17,7 +17,12 @@ module Lab
17
17
  loop do
18
18
  logger.info('Looking for new orders to push to LIMS...')
19
19
  orders = orders_pending_sync(batch_size).all
20
- orders.each { |order| push_order(order) }
20
+ orders.each do |order|
21
+ push_order(order)
22
+ rescue GatewayError => e
23
+ logger.error("Failed to push order ##{order.accession_number}: #{e.class} - #{e.message}")
24
+ sleep(Lab::Lims::Config.updates_poll_frequency)
25
+ end
21
26
 
22
27
  # Doing this after .each above to stop ActiveRecord from executing
23
28
  # an extra request to the database (ActiveRecord's lazy evaluation
@@ -56,7 +61,8 @@ module Lab
56
61
  else
57
62
  Rails.logger.info("Creating order ##{order_dto['accession_number']} in LIMS")
58
63
  update = lims_api.create_order(order_dto)
59
- Lab::LimsOrderMapping.create!(order: order, lims_id: update['id'], revision: update['rev'], pushed_at: Time.now)
64
+ Lab::LimsOrderMapping.create!(order: order, lims_id: update['id'], revision: update['rev'],
65
+ pushed_at: Time.now)
60
66
  end
61
67
  end
62
68
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'logger_multiplexor'
4
4
 
5
+ require_relative './api/couchdb_api'
6
+
5
7
  module Lab
6
8
  module Lims
7
9
  ##
@@ -19,8 +21,7 @@ module Lab
19
21
 
20
22
  def self.start_push_worker
21
23
  start_worker('push_worker') do
22
- api = Lims::Api::RestApi.new(Lab::Lims::Config.rest_api)
23
- worker = PushWorker.new(api)
24
+ worker = PushWorker.new(lims_api)
24
25
 
25
26
  worker.push_orders # (wait: true)
26
27
  end
@@ -28,8 +29,7 @@ module Lab
28
29
 
29
30
  def self.start_pull_worker
30
31
  start_worker('pull_worker') do
31
- api = Lims::Api::RestApi.new(Lab::Lims::Config.rest_api)
32
- worker = PullWorker.new(api)
32
+ worker = PullWorker.new(lims_api)
33
33
 
34
34
  worker.pull_orders
35
35
  end
@@ -37,8 +37,7 @@ module Lab
37
37
 
38
38
  def self.start_realtime_pull_worker
39
39
  start_worker('realtime_pull_worker') do
40
- api = Lims::Api::WsApi.new(Lab::Lims::Config.updates_socket)
41
- worker = PullWorker.new(api)
40
+ worker = PullWorker.new(Lims::Api::WsApi.new(Lab::Lims::Config.updates_socket))
42
41
 
43
42
  worker.pull_orders
44
43
  end
@@ -71,6 +70,14 @@ module Lab
71
70
  Rails.logger.warn("Check for realtime updates failed: #{e.message}")
72
71
  false
73
72
  end
73
+
74
+ def self.lims_api
75
+ case Lims::Config.preferred_api
76
+ when /couchdb/i then Api::CouchDbApi.new(config: Lab::Lims::Config.couchdb)
77
+ when /rest/i then Api::RestApi.new(Lab::Lims::Config.rest_api)
78
+ else raise "Invalid LIMS API in application.yml, expected 'rest' or 'couchdb'"
79
+ end
80
+ end
74
81
  end
75
82
  end
76
83
  end
@@ -10,6 +10,7 @@ module Lab
10
10
  TEST_RESULT_CONCEPT_NAME = 'Lab test result'
11
11
  TEST_RESULT_INDICATOR_CONCEPT_NAME = 'Lab test result indicator'
12
12
  TEST_TYPE_CONCEPT_NAME = 'Test type'
13
+ UNKNOWN_SPECIMEN = 'Unknown'
13
14
 
14
15
  # Encounter
15
16
  ENCOUNTER_TYPE_NAME = 'Lab'
@@ -26,8 +26,10 @@ module Lab
26
26
  end
27
27
 
28
28
  def find_orders_without_results(patient_id: nil)
29
- query = Lab::LabOrder.where
30
- .not(order_id: Lab::LabResult.all.select(:order_id))
29
+ results_query = Lab::LabResult.all
30
+ results_query = results_query.where(person_id: patient_id) if patient_id
31
+
32
+ query = Lab::LabOrder.where.not(order_id: results_query.select(:order_id))
31
33
  query = query.where(patient_id: patient_id) if patient_id
32
34
 
33
35
  query
@@ -66,20 +66,27 @@ module Lab
66
66
 
67
67
  def update_order(order_id, params)
68
68
  specimen_id = params.dig(:specimen, :concept_id)
69
- unless specimen_id
70
- raise ::InvalidParameterError, 'Specimen concept_id is required'
71
- end
69
+ raise ::InvalidParameterError, 'Specimen concept_id is required' unless specimen_id
72
70
 
73
71
  order = Lab::LabOrder.find(order_id)
74
- unless order.concept_id == unknown_concept_id || params[:force_update]&.to_s&.casecmp?('true')
75
- raise ::UnprocessableEntityError
72
+ if order.concept_id != unknown_concept_id && !params[:force_update]&.casecmp?('true')
73
+ raise ::UnprocessableEntityError, "Can't change order specimen once set"
74
+ end
75
+
76
+ if specimen_id.to_i != order.concept_id
77
+ Rails.logger.debug("Updating order ##{order.order_id}")
78
+ order.update!(concept_id: specimen_id,
79
+ discontinued: true,
80
+ discontinued_by: User.current.user_id,
81
+ discontinued_date: params[:date]&.to_date || Time.now,
82
+ discontinued_reason_non_coded: 'Sample drawn/updated')
83
+ end
84
+
85
+ if params[:reason_for_test_id]
86
+ Rails.logger.debug("Updating reason for test on order ##{order.order_id}")
87
+ update_reason_for_test(order, params[:reason_for_test_id])
76
88
  end
77
89
 
78
- order.update!(concept_id: specimen_id,
79
- discontinued: true,
80
- discontinued_by: User.current.user_id,
81
- discontinued_date: params[:date]&.to_date || Time.now,
82
- discontinued_reason_non_coded: 'Sample drawn/updated')
83
90
  Lab::LabOrderSerializer.serialize_order(order)
84
91
  end
85
92
 
@@ -107,13 +114,9 @@ module Lab
107
114
  # a 'Lab' encounter is created using the provided program_id and
108
115
  # patient_id.
109
116
  def find_encounter(order_params)
110
- if order_params[:encounter_id]
111
- return Encounter.find(order_params[:encounter_id])
112
- end
117
+ return Encounter.find(order_params[:encounter_id]) if order_params[:encounter_id]
113
118
 
114
- unless order_params[:patient_id]
115
- raise InvalidParameterError, 'encounter_id or patient_id required'
116
- end
119
+ raise InvalidParameterError, 'encounter_id or patient_id required' unless order_params[:patient_id]
117
120
 
118
121
  program_id = order_params[:program_id] || Program.find_by_name!(Lab::Metadata::LAB_PROGRAM_NAME).program_id
119
122
 
@@ -159,7 +162,7 @@ module Lab
159
162
  order,
160
163
  Lab::Metadata::REASON_FOR_TEST_CONCEPT_NAME,
161
164
  params[:date],
162
- value_coded: params['reason_for_test_id']
165
+ value_coded: params[:reason_for_test_id]
163
166
  )
164
167
  end
165
168
 
@@ -192,6 +195,17 @@ module Lab
192
195
  def unknown_concept_id
193
196
  ConceptName.find_by_name!('Unknown').concept_id
194
197
  end
198
+
199
+ def update_reason_for_test(order, concept_id)
200
+ raise InvalidParameterError, "Reason for test can't be blank" if concept_id.blank?
201
+
202
+ return if order.reason_for_test&.value_coded == concept_id
203
+
204
+ raise InvalidParameterError, "Can't change reason for test once set" if order.reason_for_test&.value_coded
205
+
206
+ order.reason_for_test&.delete
207
+ add_reason_for_test(order, date: order.start_date, reason_for_test_id: concept_id)
208
+ end
195
209
  end
196
210
  end
197
211
  end
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.1'
4
+ VERSION = '1.1.5'
5
5
  end
@@ -3,4 +3,5 @@
3
3
  "Repeat / Missing"
4
4
  "Targeted"
5
5
  "Confirmatory"
6
+ "Stat"
6
7
  "Other"
@@ -86,8 +86,6 @@ Blood,HbA1c,"2019-11-19 14:05:31"
86
86
  Blood,Microalbumin,"2019-11-19 14:05:31"
87
87
  Blood,Microprotein,"2019-11-19 14:05:31"
88
88
  Blood,"Von Willebrand Factor","2019-11-19 14:05:31"
89
- Blood,"HIV_viral_load","2021-04-13 00:00:00"
90
- Blood,"Viral laod","2021-04-11 00:00:00"
91
89
  Blood,"Viral Load","2019-11-19 14:05:31"
92
90
  Blood,"Urine Lam","2019-11-19 14:05:31"
93
91
  Blood,"Protein and Sugar","2021-04-16"
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.1
4
+ version: 1.1.5
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: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: couchrest