his_emr_api_lab 0.0.5.pre.p1 → 0.0.10

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