his_emr_api_lab 1.1.1 → 1.1.5

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: 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