his_emr_api_lab 0.0.5.pre.p1 → 0.0.10

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: fa64a790eb8ca474b8505b496671e5462c055ab42cc646a2e5788579f5fe0d79
4
- data.tar.gz: c1b23bc070e065aafb50b4b36e68c125c96c02499648c55135f811ad378fc829
3
+ metadata.gz: 1820c47a6689d070b7e2d7c15e2fbcea3d66468141865a4aba4f52cc394a5146
4
+ data.tar.gz: 49d92b0a38610d40274555b8fc130834137c2bfd8a278697ceada745cecf8fc2
5
5
  SHA512:
6
- metadata.gz: 9b988f69ecc23eddd265e0f67a40f2014ed630aeca9346eef44ebbb7a7faea1e27c58dae0cfd2c45bd38a8e53dee8fcf30315c3dfd98bf9f5c75787357071db6
7
- data.tar.gz: cef9504aaebd53c1f96e9a67d518edafa6226bc07c487b1653ffc97ccc95bb9621080257f8d81f00e8375860703ce482e713466d2aa941a40b752a4e3399bb54
6
+ metadata.gz: f7ba1de5785aaa82cb6471639b7edb8ab59a4972cd289bf9886a1f89c460e17d202479b92460377a66fb55998d45a2ad50f4cc5c48d5fafb04e972bf66802bf5
7
+ data.tar.gz: 932735ff44518d81045456b6c80fde5e488e6971e4bee9180e7943012bd0db5d809d2af38b30da736d858aebf09b3dd8a926c82d23d93224d3451a528e7b2740
@@ -27,7 +27,7 @@ module Lab
27
27
  '',
28
28
  drawer,
29
29
  '',
30
- specimen,
30
+ tests,
31
31
  reason_for_test,
32
32
  order.accession_number,
33
33
  order.accession_number)
@@ -36,7 +36,7 @@ module Lab
36
36
  def reason_for_test
37
37
  return 'Unknown' unless order.reason_for_test
38
38
 
39
- ConceptName.find_by_concept_id(order.reason_for_test.value_coded)&.name || 'Unknown'
39
+ short_concept_name(order.reason_for_test.value_coded) || 'Unknown'
40
40
  end
41
41
 
42
42
  def patient
@@ -73,6 +73,24 @@ module Lab
73
73
  ConceptName.find_by_concept_id(order.concept_id)&.name || 'Unknown'
74
74
  end
75
75
 
76
+ def tests
77
+ tests = order.tests.map do |test|
78
+ name = short_concept_name(test.value_coded) || 'Unknown'
79
+
80
+ next 'VL' if name.match?(/Viral load/i)
81
+
82
+ name.size > 7 ? name[0..6] : name
83
+ end
84
+
85
+ tests.join(', ')
86
+ end
87
+
88
+ def short_concept_name(concept_id)
89
+ ConceptName.where(concept_id: concept_id)
90
+ .min_by { |concept| concept.name.size }
91
+ &.name
92
+ end
93
+
76
94
  def unknown_concept
77
95
  ConceptName.find_by_name('Unknown')
78
96
  end
@@ -142,9 +142,10 @@ module Lab
142
142
  MIGRATION_REJECTIONS_CSV_PATH = LIMS_LOG_PATH.join('migration-rejections.csv')
143
143
 
144
144
  def self.export_rejections(rejections)
145
- headers = ['Accession number', 'NHID', 'First name', 'Last name', 'Reason']
145
+ headers = ['doc_id', 'Accession number', 'NHID', 'First name', 'Last name', 'Reason']
146
146
  rows = (rejections || []).map do |rejection|
147
147
  [
148
+ rejection.order[:_id],
148
149
  rejection.order[:tracking_number],
149
150
  rejection.order[:patient][:id],
150
151
  rejection.order[:patient][:first_name],
@@ -159,9 +160,10 @@ module Lab
159
160
  MIGRATION_FAILURES_CSV_PATH = LIMS_LOG_PATH.join('migration-failures.csv')
160
161
 
161
162
  def self.export_failures
162
- headers = ['Accession number', 'NHID', 'Reason', 'Difference']
163
+ headers = ['doc_id', 'Accession number', 'NHID', 'Reason', 'Difference']
163
164
  rows = Lab::LimsFailedImport.all.map do |failure|
164
165
  [
166
+ failure.lims_id,
165
167
  failure.tracking_number,
166
168
  failure.patient_nhid,
167
169
  failure.reason,
@@ -30,9 +30,9 @@ module Lab
30
30
 
31
31
  # Translates a LIMS specimen name to an OpenMRS concept_id
32
32
  def specimen_type_id
33
- lims_specimen_name = self['sample_type']
33
+ lims_specimen_name = self['sample_type']&.strip&.downcase
34
34
 
35
- if %w[specimen_not_collected not_assigned].include?(lims_specimen_name)
35
+ if %w[specimen_not_collected not_assigned not_specified].include?(lims_specimen_name)
36
36
  return ConceptName.select(:concept_id).find_by_name!('Unknown').concept_id
37
37
  end
38
38
 
@@ -53,6 +53,8 @@ module Lab
53
53
 
54
54
  # Extract requesting clinician name from LIMS
55
55
  def requesting_clinician
56
+ return 'Unknown' unless self['who_order_test']
57
+
56
58
  # TODO: Extend requesting clinician to an obs tree having extra parameters
57
59
  # like phone number and ID to closely match the lims user.
58
60
  first_name = self['who_order_test']['first_name'] || ''
@@ -67,6 +69,10 @@ module Lab
67
69
  end
68
70
 
69
71
  def start_date
72
+ if self['date_created'].blank?
73
+ raise LimsException, 'Order missing created date'
74
+ end
75
+
70
76
  Utils.parse_date(self['date_created'])
71
77
  end
72
78
 
@@ -66,6 +66,8 @@ module Lab
66
66
  Date.strptime(str_date, '%d-%m-%Y').strftime('%Y-%m-%d')
67
67
  elsif str_date.match?(/(\d{4}\d{2}\d{2})\d+/)
68
68
  Date.strptime(str_date, '%Y%m%d').strftime('%Y-%m-%d')
69
+ elsif str_date.match?(%r{\d{2}/\d{2}/\d{4}})
70
+ str_date.to_date.to_s
69
71
  else
70
72
  Rails.logger.warn("Invalid date: #{str_date}")
71
73
  parse_date(fallback_date)
@@ -28,7 +28,9 @@ module Lab
28
28
  fout.write("Worker ##{Process.pid} started at #{Time.now}")
29
29
  worker = new(Api.new)
30
30
  worker.pull_orders
31
- worker.push_orders
31
+ # TODO: Verify that names being pushed to LIMS are of the correct format (ie matching
32
+ # LIMS naming conventions). Enable pushing when that is done
33
+ # worker.push_orders
32
34
  end
33
35
  end
34
36
 
@@ -5,44 +5,54 @@ module Lab
5
5
  module OrdersSearchService
6
6
  class << self
7
7
  def find_orders(filters)
8
- date = filters.delete(:date)
9
- status = filters.delete(:status)
8
+ extra_filters = pop_filters(filters, :date, :end_date, :status)
10
9
 
11
10
  orders = Lab::LabOrder.prefetch_relationships
12
11
  .where(filters)
13
12
  .order(start_date: :desc)
14
13
 
15
- orders = filter_orders_by_date(orders, date) if date
16
- orders = filter_orders_by_status(orders, status) if status
14
+ orders = filter_orders_by_status(orders, pop_filters(extra_filters, :status))
15
+ orders = filter_orders_by_date(orders, extra_filters)
17
16
 
18
17
  orders.map { |order| Lab::LabOrderSerializer.serialize_order(order) }
19
18
  end
20
19
 
21
- def filter_orders_by_date(orders, date)
22
- orders.where('start_date < DATE(?)', date.to_date + 1.day)
23
- end
20
+ def filter_orders_by_date(orders, date: nil, end_date: nil)
21
+ date = date&.to_date
22
+ end_date = end_date&.to_date
24
23
 
25
- def filter_orders_by_status(orders, status)
26
- case status.downcase
27
- when 'ordered' then orders.where(concept_id: unknown_concept_id)
28
- when 'drawn' then orders.where.not(concept_id: unknown_concept_id)
24
+ if date && end_date
25
+ return orders.where('start_date BETWEEN ? AND ?', date, end_date + 1.day)
29
26
  end
30
- end
31
27
 
32
- def unknown_concept_id
33
- ConceptName.find_by_name!('Unknown').concept_id
28
+ if date
29
+ return orders.where('start_date BETWEEN ? AND ?', date, date + 1.day)
30
+ end
31
+
32
+ return orders.where('start_date < ?', end_date + 1.day) if end_date
33
+
34
+ orders
34
35
  end
35
36
 
36
- def filter_orders_by_status(orders, status)
37
- case status.downcase
37
+ def filter_orders_by_status(orders, status: nil)
38
+ case status&.downcase
38
39
  when 'ordered' then orders.where(concept_id: unknown_concept_id)
39
40
  when 'drawn' then orders.where.not(concept_id: unknown_concept_id)
41
+ else orders
40
42
  end
41
43
  end
42
44
 
43
45
  def unknown_concept_id
44
46
  ConceptName.find_by_name!('Unknown').concept_id
45
47
  end
48
+
49
+ def pop_filters(params, *filters)
50
+ filters.each_with_object({}) do |filter, popped_params|
51
+ next unless params.key?(filter)
52
+
53
+ popped_params[filter.to_sym] = params.delete(filter)
54
+ end
55
+ end
46
56
  end
47
57
  end
48
58
  end
@@ -175,6 +175,12 @@ paths:
175
175
  description: 'Filter by sample status: ordered, drawn'
176
176
  schema:
177
177
  type: string
178
+ - name: end_date
179
+ in: query
180
+ required: false
181
+ description: Select all results before this date
182
+ schema:
183
+ type: date
178
184
  responses:
179
185
  '200':
180
186
  description: Success
@@ -396,6 +402,32 @@ paths:
396
402
  responses:
397
403
  '204':
398
404
  description: No Content
405
+ "/api/v1/lab/reasons_for_test":
406
+ get:
407
+ summary: Reasons for test
408
+ description: Retrieve default reasons for test concept set
409
+ tags:
410
+ - Concepts
411
+ security:
412
+ - api_key: []
413
+ responses:
414
+ '200':
415
+ description: Success
416
+ content:
417
+ application/json:
418
+ schema:
419
+ type: array
420
+ items:
421
+ type: object
422
+ properties:
423
+ concept_id:
424
+ type: integer
425
+ name:
426
+ type: string
427
+ example: Routine
428
+ required:
429
+ - concept_id
430
+ - name
399
431
  "/api/v1/lab/tests/{test_id}/results":
400
432
  post:
401
433
  summary: Add results to order
data/lib/lab/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lab
4
- VERSION = '0.0.5-p1'
4
+ VERSION = '0.0.10'
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: 0.0.5.pre.p1
4
+ version: 0.0.10
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-04-21 00:00:00.000000000 Z
11
+ date: 2021-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: couchrest
@@ -304,9 +304,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
304
304
  version: '0'
305
305
  required_rubygems_version: !ruby/object:Gem::Requirement
306
306
  requirements:
307
- - - ">"
307
+ - - ">="
308
308
  - !ruby/object:Gem::Version
309
- version: 1.3.1
309
+ version: '0'
310
310
  requirements: []
311
311
  rubygems_version: 3.0.8
312
312
  signing_key: