his_emr_api_lab 2.1.1 → 2.1.3
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 +4 -4
- data/app/controllers/lab/labels_controller.rb +2 -1
- data/app/controllers/lab/orders_controller.rb +14 -25
- data/app/controllers/lab/results_controller.rb +2 -1
- data/app/controllers/lab/specimen_types_controller.rb +0 -1
- data/app/controllers/lab/test_methods_controller.rb +9 -0
- data/app/controllers/lab/test_types_controller.rb +1 -1
- data/app/controllers/lab/tests_controller.rb +1 -3
- data/app/controllers/lab/users_controller.rb +2 -1
- data/app/models/lab/lab_result.rb +4 -0
- data/app/models/lab/lab_test.rb +1 -1
- data/app/models/lab/order_extension.rb +14 -0
- data/app/serializers/lab/lab_order_serializer.rb +20 -4
- data/app/serializers/lab/result_serializer.rb +1 -1
- data/app/serializers/lab/test_serializer.rb +24 -1
- data/app/services/lab/acknowledgement_service.rb +4 -1
- data/app/services/lab/concepts_service.rb +77 -22
- data/app/services/lab/lims/acknowledgement_worker.rb +1 -1
- data/app/services/lab/lims/api/rest_api.rb +543 -78
- data/app/services/lab/lims/config.rb +7 -2
- data/app/services/lab/lims/exceptions.rb +18 -6
- data/app/services/lab/lims/migrator.rb +3 -3
- data/app/services/lab/lims/order_dto.rb +1 -1
- data/app/services/lab/lims/order_serializer.rb +28 -7
- data/app/services/lab/lims/push_worker.rb +3 -3
- data/app/services/lab/lims/utils.rb +5 -7
- data/app/services/lab/lims/worker.rb +1 -1
- data/app/services/lab/metadata.rb +3 -0
- data/app/services/lab/notification_service.rb +72 -0
- data/app/services/lab/orders_search_service.rb +11 -5
- data/app/services/lab/orders_service.rb +79 -38
- data/app/services/lab/results_service.rb +30 -16
- data/app/services/lab/tests_service.rb +15 -3
- data/config/routes.rb +1 -0
- data/db/migrate/20260119104240_add_fulfiller_fields_to_orders.rb +11 -0
- data/db/migrate/20260119104241_create_comment_to_fulfiller_concept.rb +50 -0
- data/lib/lab/version.rb +1 -1
- data/lib/mahis_emr_api_lab.rb +6 -0
- metadata +11 -5
- /data/app/services/lab/lims/api/{couchdb_api.rb → couch_db_api.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c71682551eb38f2c025993390d6d32f064be0fd35da372dede313882f12c6ad8
|
|
4
|
+
data.tar.gz: f59352b4aceb5d7cf891cb094ef9b213f7e191d453936ca97396101d789e3846
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2db7d3ee59f9cd0e94c2eccc5f7a4514d9c25479e6e31dcce709aa3005934b6c3a2b794fa8e297e86a792f9c311a12628bd1c117d8202aafe49da6c72606643a
|
|
7
|
+
data.tar.gz: 025253b76aa0cb65c237e03aecbcf7010a9a847b7c249d46af7c51330fdbf6ef03b6ee82051aa12271984511091a6d639e46b61c9ca51a3714f1b30b806ba623
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Lab
|
|
4
4
|
class LabelsController < ApplicationController
|
|
5
|
-
|
|
5
|
+
_callbacks = _process_action_callbacks.map(&:filter)
|
|
6
|
+
skip_before_action :authenticate if _callbacks.include?(:authenticate)
|
|
6
7
|
|
|
7
8
|
def print_order_label
|
|
8
9
|
order_id = params.require(:order_id)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Lab
|
|
4
4
|
class OrdersController < ApplicationController
|
|
5
|
-
skip_before_action :authenticate, only: %i[order_status order_result summary]
|
|
6
5
|
before_action :authenticate_request, only: %i[order_status order_result summary]
|
|
7
6
|
|
|
8
7
|
def create
|
|
@@ -25,10 +24,19 @@ module Lab
|
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
def index
|
|
28
|
-
filters = params.
|
|
27
|
+
filters = params.permit(%i[patient_id patient accession_number date status])
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
id = filters[:patient_id] || filters[:patient]
|
|
30
|
+
|
|
31
|
+
patient = Patient.find(id) if filters[:patient_id] || filters[:patient]
|
|
32
|
+
|
|
33
|
+
Lab::UpdatePatientOrdersJob.perform_later(patient.id) if filters[:patient_id] || filters[:patient]
|
|
34
|
+
orders = OrdersSearchService.find_orders(filters)
|
|
35
|
+
begin
|
|
36
|
+
render json: orders.reload, status: :ok
|
|
37
|
+
rescue StandardError
|
|
38
|
+
render json: orders
|
|
39
|
+
end
|
|
32
40
|
end
|
|
33
41
|
|
|
34
42
|
def verify_tracking_number
|
|
@@ -68,27 +76,8 @@ module Lab
|
|
|
68
76
|
private
|
|
69
77
|
|
|
70
78
|
def authenticate_request
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
auth_scheme = content.first
|
|
74
|
-
unless header
|
|
75
|
-
errors = ['Authorization token required']
|
|
76
|
-
render json: { errors: errors }, status: :unauthorized
|
|
77
|
-
return false
|
|
78
|
-
end
|
|
79
|
-
unless auth_scheme == 'Bearer'
|
|
80
|
-
errors = ['Authorization token bearer scheme required']
|
|
81
|
-
render json: { errors: errors }, status: :unauthorized
|
|
82
|
-
return false
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
process_token(content.last)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def process_token(token)
|
|
89
|
-
browser = Browser.new(request.user_agent)
|
|
90
|
-
decoded = Lab::JsonWebTokenService.decode(token, request.remote_ip + browser.name + browser.version)
|
|
91
|
-
user(decoded)
|
|
79
|
+
decoded_user = authorize_request
|
|
80
|
+
user(decoded_user)
|
|
92
81
|
end
|
|
93
82
|
|
|
94
83
|
def user(decoded)
|
|
@@ -5,11 +5,12 @@ module Lab
|
|
|
5
5
|
def create
|
|
6
6
|
result_params = params.require(:result)
|
|
7
7
|
.permit([:encounter_id,
|
|
8
|
+
:encounter,
|
|
8
9
|
:date,
|
|
9
10
|
{ measures: [:value,
|
|
10
11
|
:value_type,
|
|
11
12
|
:value_modifier,
|
|
12
|
-
{ indicator: [
|
|
13
|
+
{ indicator: %i[concept_id concept] }] }])
|
|
13
14
|
|
|
14
15
|
result = Lab::ResultsService.create_results(params[:test_id], result_params, 'user entered')
|
|
15
16
|
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
module Lab
|
|
4
4
|
class TestsController < ApplicationController
|
|
5
5
|
def index
|
|
6
|
-
filters = params.
|
|
7
|
-
:pending_results)
|
|
8
|
-
|
|
6
|
+
filters = params.permit(%i[order_date accession_number patient patient_id test_type_id specimen_type_id pending_results])
|
|
9
7
|
tests = service.find_tests(filters)
|
|
10
8
|
render json: tests
|
|
11
9
|
end
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
# This controller handles creation and authentication of LIMS User
|
|
4
4
|
module Lab
|
|
5
5
|
class UsersController < ::ApplicationController
|
|
6
|
-
|
|
6
|
+
_callbacks = _process_action_callbacks.map(&:filter)
|
|
7
|
+
skip_before_action :authenticate if _callbacks.include?(:authenticate)
|
|
7
8
|
# create a LIMS User that will be responsible for sending lab results
|
|
8
9
|
def create
|
|
9
10
|
user_params = params.permit(:username, :password)
|
data/app/models/lab/lab_test.rb
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# model managing extra details for orders
|
|
4
|
+
class Lab::OrderExtension < ApplicationRecord
|
|
5
|
+
include Voidable
|
|
6
|
+
self.table_name = :order_extension
|
|
7
|
+
self.primary_key = :order_extension_id
|
|
8
|
+
|
|
9
|
+
default_scope { where(voided: 0) }
|
|
10
|
+
scope :voided, -> { unscoped.where.not(voided: 0) }
|
|
11
|
+
|
|
12
|
+
belongs_to :order, foreign_key: :order_id
|
|
13
|
+
belongs_to :creator, class_name: 'User', foreign_key: :creator
|
|
14
|
+
end
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Lab
|
|
4
4
|
module LabOrderSerializer
|
|
5
|
-
def self.serialize_order(order, tests: nil, requesting_clinician: nil, reason_for_test: nil, target_lab: nil)
|
|
5
|
+
def self.serialize_order(order, tests: nil, requesting_clinician: nil, reason_for_test: nil, target_lab: nil, comment_to_fulfiller: nil)
|
|
6
6
|
tests ||= order.voided == 1 ? voided_tests(order) : order.tests
|
|
7
7
|
requesting_clinician ||= order.requesting_clinician
|
|
8
|
+
comment_to_fulfiller ||= order.comment_to_fulfiller
|
|
8
9
|
reason_for_test ||= order.reason_for_test
|
|
9
10
|
target_lab = target_lab&.value_text || order.target_lab&.value_text || Location.current_health_center&.name
|
|
10
11
|
|
|
@@ -17,10 +18,11 @@ module Lab
|
|
|
17
18
|
order_type_id: order.order_type_id,
|
|
18
19
|
order_id: order.order_id, # Deprecated: Link to :id
|
|
19
20
|
encounter_id: order.encounter_id,
|
|
21
|
+
order_date: order.date_created,
|
|
20
22
|
location_id: encounter.location_id,
|
|
21
23
|
program_id: encounter.program_id,
|
|
22
24
|
program_name: program.name,
|
|
23
|
-
order_date: order.start_date,
|
|
25
|
+
# order_date: order.start_date,
|
|
24
26
|
patient_id: order.patient_id,
|
|
25
27
|
accession_number: order.accession_number,
|
|
26
28
|
specimen: {
|
|
@@ -28,7 +30,8 @@ module Lab
|
|
|
28
30
|
name: concept_name(order.concept_id)
|
|
29
31
|
},
|
|
30
32
|
requesting_clinician: requesting_clinician&.value_text,
|
|
31
|
-
target_lab
|
|
33
|
+
target_lab: target_lab,
|
|
34
|
+
comment_to_fulfiller: comment_to_fulfiller.respond_to?(:value_text) ? comment_to_fulfiller.value_text : comment_to_fulfiller,
|
|
32
35
|
reason_for_test: {
|
|
33
36
|
concept_id: reason_for_test&.value_coded,
|
|
34
37
|
name: concept_name(reason_for_test&.value_coded)
|
|
@@ -40,7 +43,9 @@ module Lab
|
|
|
40
43
|
{
|
|
41
44
|
id: test.obs_id,
|
|
42
45
|
concept_id: test.value_coded,
|
|
46
|
+
uuid: test.uuid,
|
|
43
47
|
name: concept_name(test.value_coded),
|
|
48
|
+
test_method: test_method(order, test.value_coded),
|
|
44
49
|
result: result_obs && ResultSerializer.serialize(result_obs)
|
|
45
50
|
}
|
|
46
51
|
end
|
|
@@ -48,10 +53,21 @@ module Lab
|
|
|
48
53
|
)
|
|
49
54
|
end
|
|
50
55
|
|
|
56
|
+
def self.test_method(order, _concept_id)
|
|
57
|
+
obs = ::Observation
|
|
58
|
+
.select(:value_coded)
|
|
59
|
+
.where(concept_id: ConceptName.find_by_name(Metadata::TEST_METHOD_CONCEPT_NAME).concept_id, order_id: order.id)
|
|
60
|
+
.first
|
|
61
|
+
{
|
|
62
|
+
concept_id: obs&.value_coded,
|
|
63
|
+
name: ConceptName.find_by_concept_id(obs&.value_coded)&.name
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
51
67
|
def self.concept_name(concept_id)
|
|
52
68
|
return concept_id unless concept_id
|
|
53
69
|
|
|
54
|
-
|
|
70
|
+
::ConceptAttribute.find_by(concept_id:, attribute_type: ConceptAttributeType.test_catalogue_name)&.value_reference
|
|
55
71
|
end
|
|
56
72
|
|
|
57
73
|
def self.voided_tests(order)
|
|
@@ -33,7 +33,7 @@ module Lab
|
|
|
33
33
|
|
|
34
34
|
def self.read_value(measure)
|
|
35
35
|
%w[value_numeric value_coded value_boolean value_text].each do |field|
|
|
36
|
-
value = measure.send(field)
|
|
36
|
+
value = measure.send(field) if measure.respond_to?(field)
|
|
37
37
|
|
|
38
38
|
return [value, field.split('_')[1]] if value
|
|
39
39
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# rubocop:disable Lint/UnreachableLoop
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Lab
|
|
@@ -5,25 +6,47 @@ module Lab
|
|
|
5
6
|
def self.serialize(test, order: nil, result: nil)
|
|
6
7
|
order ||= test.order
|
|
7
8
|
result ||= test.result
|
|
8
|
-
|
|
9
9
|
{
|
|
10
10
|
id: test.obs_id,
|
|
11
|
+
test_uuid: test.uuid,
|
|
11
12
|
concept_id: test.value_coded,
|
|
13
|
+
concept_uuid: test.value_coded ? Concept.find(test.value_coded)&.uuid : nil,
|
|
12
14
|
name: ConceptName.find_by_concept_id(test.value_coded)&.name,
|
|
13
15
|
order: {
|
|
14
16
|
id: order.order_id,
|
|
15
17
|
concept_id: order.concept_id,
|
|
18
|
+
concept_uuid: order.concept_id ? Concept.find(order.concept_id)&.uuid : nil,
|
|
16
19
|
name: ConceptName.find_by_concept_id(order.concept_id)&.name,
|
|
17
20
|
accession_number: order.accession_number
|
|
18
21
|
},
|
|
22
|
+
measures: result_mesures(result),
|
|
19
23
|
result: if result
|
|
20
24
|
{
|
|
21
25
|
id: result.obs_id,
|
|
26
|
+
uuid: result.uuid,
|
|
22
27
|
modifier: result.value_modifier,
|
|
23
28
|
value: result.value_text
|
|
24
29
|
}
|
|
25
30
|
end
|
|
26
31
|
}
|
|
27
32
|
end
|
|
33
|
+
|
|
34
|
+
def self.result_mesures(result)
|
|
35
|
+
if result&.measures.present?
|
|
36
|
+
return result&.measures&.map do |measure|
|
|
37
|
+
m = {}
|
|
38
|
+
m[:uuid] = measure.uuid
|
|
39
|
+
m[:concept_id] = measure.concept_id
|
|
40
|
+
m[:name] = ConceptName.find_by_concept_id(measure.concept_id)&.name
|
|
41
|
+
m[:modifier] = measure.value_modifier
|
|
42
|
+
m[:value] = measure&.value_text || measure&.value_numeric || measure&.value_boolean || measure&.value_coded || measure&.value_datetime || measure&.value_drug || measure&.value_complex || measure&.value_group
|
|
43
|
+
m
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
28
49
|
end
|
|
29
50
|
end
|
|
51
|
+
|
|
52
|
+
# rubocop:enable Lint/UnreachableLoop
|
|
@@ -6,6 +6,9 @@ module Lab
|
|
|
6
6
|
class << self
|
|
7
7
|
def create_acknowledgement(params)
|
|
8
8
|
order = Order.find(params[:order_id])
|
|
9
|
+
|
|
10
|
+
Lab::LabAcknowledgement.find_by(order_id: order.id, test: params[:test])&.destroy
|
|
11
|
+
|
|
9
12
|
Lab::LabAcknowledgement.create!(order_id: order.id, test: params[:test], pushed: false,
|
|
10
13
|
acknowledgement_type: params[:entered_by] == 'LIMS' ? 'test_results_delivered_to_site_electronically' : 'test_results_delivered_to_site_manually',
|
|
11
14
|
date_received: params[:date_received])
|
|
@@ -27,7 +30,7 @@ module Lab
|
|
|
27
30
|
Rails.logger.info("Updating acknowledgement ##{acknowledgement_dto[:tracking_number]} in LIMS")
|
|
28
31
|
response = lims_api.acknowledge(acknowledgement_dto)
|
|
29
32
|
Rails.logger.info("Info #{response}")
|
|
30
|
-
if
|
|
33
|
+
if ['results already delivered for test name given', 'test result acknowledged successfully', 'test result already acknowledged electronically at facility'].include?(response['message'])
|
|
31
34
|
acknowledgement.pushed = true
|
|
32
35
|
acknowledgement.date_pushed = Time.now
|
|
33
36
|
acknowledgement.save!
|
|
@@ -3,14 +3,45 @@
|
|
|
3
3
|
module Lab
|
|
4
4
|
# A read-only repository of sort for all lab-centric concepts.
|
|
5
5
|
module ConceptsService
|
|
6
|
+
def self.test_methods(nlims_code)
|
|
7
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
8
|
+
SELECT cn.name, cn.concept_id
|
|
9
|
+
FROM concept_set cs
|
|
10
|
+
INNER JOIN concept_name cn ON cn.concept_id = cs.concept_id
|
|
11
|
+
INNER JOIN concept_attribute ca ON ca.value_reference = #{ActiveRecord::Base.connection.quote(nlims_code)}
|
|
12
|
+
AND ca.attribute_type_id = 20
|
|
13
|
+
WHERE cs.concept_id IN (SELECT concept_set.concept_id
|
|
14
|
+
FROM concept_set
|
|
15
|
+
WHERE concept_set.concept_set IN (SELECT concept_name.concept_id
|
|
16
|
+
FROM concept_name
|
|
17
|
+
WHERE concept_name.voided = 0
|
|
18
|
+
AND concept_name.name = 'Recommended test method'))
|
|
19
|
+
AND cs.concept_set IN (SELECT concept_set.concept_id
|
|
20
|
+
FROM concept_set
|
|
21
|
+
WHERE concept_set.concept_set IN (SELECT concept_name.concept_id
|
|
22
|
+
FROM concept_name
|
|
23
|
+
WHERE concept_name.voided = 0
|
|
24
|
+
AND concept_name.name = 'Test type')
|
|
25
|
+
AND concept_set.concept_id = ca.concept_id
|
|
26
|
+
)
|
|
27
|
+
GROUP BY cn.concept_id
|
|
28
|
+
SQL
|
|
29
|
+
end
|
|
30
|
+
|
|
6
31
|
def self.test_types(name: nil, specimen_type: nil)
|
|
7
32
|
test_types = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
|
8
33
|
test_types = test_types.filter_members(name:) if name
|
|
9
34
|
|
|
10
35
|
unless specimen_type
|
|
11
|
-
return
|
|
12
|
-
|
|
13
|
-
|
|
36
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
37
|
+
SELECT ca.concept_id, ca.value_reference as name, ca2.value_reference as nlims_code
|
|
38
|
+
FROM concept_attribute ca
|
|
39
|
+
INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
|
|
40
|
+
AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
|
|
41
|
+
WHERE ca.attribute_type_id = #{ConceptAttributeType.test_catalogue_name.concept_attribute_type_id}
|
|
42
|
+
AND ca.concept_id IN (#{test_types.select(:concept_id).to_sql})
|
|
43
|
+
GROUP BY ca.concept_id
|
|
44
|
+
SQL
|
|
14
45
|
end
|
|
15
46
|
|
|
16
47
|
# Filter out only those test types that have the specified specimen
|
|
@@ -24,25 +55,37 @@ module Lab
|
|
|
24
55
|
concept_set: test_types.select(:concept_id)
|
|
25
56
|
)
|
|
26
57
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
58
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
59
|
+
SELECT ca.concept_id, ca.value_reference as name, ca2.value_reference as nlims_code
|
|
60
|
+
FROM concept_attribute ca
|
|
61
|
+
INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
|
|
62
|
+
AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
|
|
63
|
+
WHERE ca.attribute_type_id = #{ConceptAttributeType.test_catalogue_name.concept_attribute_type_id}
|
|
64
|
+
AND ca.concept_id IN (#{concept_set.select(:concept_id).to_sql})
|
|
65
|
+
GROUP BY ca.concept_id
|
|
66
|
+
SQL
|
|
30
67
|
end
|
|
31
68
|
|
|
32
69
|
def self.specimen_types(name: nil, test_type: nil)
|
|
33
70
|
specimen_types = ConceptSet.find_members_by_name(Lab::Metadata::SPECIMEN_TYPE_CONCEPT_NAME)
|
|
34
|
-
specimen_types = specimen_types.filter_members(name:) if name
|
|
71
|
+
specimen_types = specimen_types.filter_members(name: name) if name
|
|
35
72
|
|
|
36
73
|
unless test_type
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
74
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
75
|
+
SELECT ca.concept_id, ca.value_reference as name, ca2.value_reference as nlims_code
|
|
76
|
+
FROM concept_attribute ca
|
|
77
|
+
INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
|
|
78
|
+
AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
|
|
79
|
+
WHERE ca.attribute_type_id = #{ConceptAttributeType.test_catalogue_name.concept_attribute_type_id}
|
|
80
|
+
AND ca.concept_id IN (#{specimen_types.select(:concept_id).to_sql})
|
|
81
|
+
GROUP BY ca.concept_id
|
|
82
|
+
SQL
|
|
40
83
|
end
|
|
41
84
|
|
|
42
85
|
# Retrieve only those specimen types that belong to concept
|
|
43
86
|
# set of the selected test_type
|
|
44
87
|
test_types = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
|
45
|
-
.filter_members(name: test_type)
|
|
88
|
+
.filter_members(name: test_type&.strip)
|
|
46
89
|
.select(:concept_id)
|
|
47
90
|
|
|
48
91
|
concept_set = ConceptSet.where(
|
|
@@ -50,33 +93,45 @@ module Lab
|
|
|
50
93
|
concept_set: test_types
|
|
51
94
|
)
|
|
52
95
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
96
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
97
|
+
SELECT ca.concept_id, ca.value_reference as name, ca2.value_reference as nlims_code
|
|
98
|
+
FROM concept_attribute ca
|
|
99
|
+
INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
|
|
100
|
+
AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
|
|
101
|
+
WHERE ca.attribute_type_id = #{ConceptAttributeType.test_catalogue_name.concept_attribute_type_id}
|
|
102
|
+
AND ca.concept_id IN (#{concept_set.pluck(:concept_id).push(0).join(',')})
|
|
103
|
+
GROUP BY ca.concept_id
|
|
104
|
+
SQL
|
|
56
105
|
end
|
|
57
106
|
|
|
58
107
|
def self.test_result_indicators(test_type_id)
|
|
59
108
|
# Verify that the specified test_type is indeed a test_type
|
|
60
109
|
test = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
|
61
|
-
.where(concept_id: test_type_id)
|
|
110
|
+
.where(concept_id: Concept.find(test_type_id)&.id)
|
|
62
111
|
.select(:concept_id)
|
|
63
112
|
|
|
64
113
|
# From the members above, filter out only those concepts that are result indicators
|
|
65
114
|
measures = ConceptSet.find_members_by_name(Lab::Metadata::TEST_RESULT_INDICATOR_CONCEPT_NAME)
|
|
66
115
|
.select(:concept_id)
|
|
67
116
|
|
|
68
|
-
ConceptSet.where(concept_set: measures, concept_id: test)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
117
|
+
sets = ConceptSet.where(concept_set: measures, concept_id: test)
|
|
118
|
+
|
|
119
|
+
return ActiveRecord::Base.connection.select_all <<~SQL
|
|
120
|
+
SELECT ca.concept_id, ca.value_reference as name, ca2.value_reference as nlims_code
|
|
121
|
+
FROM concept_attribute ca
|
|
122
|
+
INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
|
|
123
|
+
AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
|
|
124
|
+
WHERE ca.attribute_type_id = #{ConceptAttributeType.test_catalogue_name.concept_attribute_type_id}
|
|
125
|
+
AND ca.concept_id IN (#{sets.pluck(:concept_set).push(0).join(',')})
|
|
126
|
+
GROUP BY ca.concept_id
|
|
127
|
+
SQL
|
|
73
128
|
end
|
|
74
129
|
|
|
75
130
|
def self.reasons_for_test
|
|
76
131
|
ConceptSet.find_members_by_name(Lab::Metadata::REASON_FOR_TEST_CONCEPT_NAME)
|
|
77
132
|
.joins('INNER JOIN concept_name ON concept_name.concept_id = concept_set.concept_id')
|
|
78
|
-
.select('concept_name.concept_id, concept_name.name')
|
|
79
|
-
.map { |concept| { name: concept.name, concept_id: concept.concept_id } }
|
|
133
|
+
.select('concept_name.concept_id, concept_name.name, concept_name.uuid')
|
|
134
|
+
.map { |concept| { name: concept.name, concept_id: concept.concept_id, uuid: concept.uuid } }
|
|
80
135
|
end
|
|
81
136
|
end
|
|
82
137
|
end
|
|
@@ -22,7 +22,7 @@ module Lab
|
|
|
22
22
|
logger.debug("Found #{acknowledgements.size} acknowledgements...")
|
|
23
23
|
acknowledgements.each do |acknowledgement|
|
|
24
24
|
Lab::AcknowledgementService.push_acknowledgement(acknowledgement, @lims_api)
|
|
25
|
-
rescue
|
|
25
|
+
rescue StandardError => e
|
|
26
26
|
logger.error("Failed to push acknowledgement ##{acknowledgement.order_id}: #{e.class} - #{e.message}")
|
|
27
27
|
end
|
|
28
28
|
|