his_emr_api_lab 2.1.4.pre.beta → 2.1.5.streaming

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: 2cb84913a3c09866a51aa40a98812803bfee6f66a36c3e5c7ea4bdcb9a530724
4
- data.tar.gz: 833074b20f473b97b515a11392fc768dabc0b3289b1717474e08b903120c6216
3
+ metadata.gz: 4aeefd371ffd0e3a4c9d460b7d7bd280b3d65868438b0760f992cf66dced202b
4
+ data.tar.gz: 48ca67bb59e2daebe7776f62fdafa6bc158d18351bbb161690a9a598a442b905
5
5
  SHA512:
6
- metadata.gz: fa6487f57604f5ee24b2fc15e730dfc765cea9eff12051d1875560aa49832e36dc7ffab4320517eeb1f6ffe0ccb706b0e40e4bffc0bcb56d3055b77c9f72c650
7
- data.tar.gz: 02a6a0b02074c8fcec8c3d9dbeaeee0a29ea6f96a62f30459f96ee904720c72a854d8251bfb111c5e6e80ae6552a658dabb409547b92119062ada27723d2d0bf
6
+ metadata.gz: fabfe624347d8724f40a063266d04619057111f92f512be9e847587c53d1d435caaf46dda9055cf8adde7af5d791091bc5898c54a1a4857b5a4536e11e5f723e
7
+ data.tar.gz: b24da9322346b8efdf05b3e671e550d3d6b6b59c8cd02b52415747acdd2b968e9f30eba0ef7b4df63e6cf9e25b4811189114f074139eac7fdaf967954569dc3c
@@ -6,6 +6,7 @@ module Lab
6
6
  class ProcessLabResultJob < ApplicationJob
7
7
  queue_as :default
8
8
  def perform(results_obs_id, serializer, result_enter_by)
9
+ Rails.logger.info("Lab::ProcessLabResultJob: Processing result completion for #{serializer}")
9
10
  results_obs = Lab::LabResult.find(results_obs_id)
10
11
  Lab::ResultsService.process_result_completion(results_obs, serializer, result_enter_by)
11
12
  end
@@ -7,11 +7,11 @@ module Lab
7
7
  def self.serialize(result)
8
8
  result.children.map do |measure|
9
9
  value, value_type = read_value(measure)
10
- concept_name = ConceptName.find_by_concept_id(measure.concept_id)
11
-
12
- program_id = ""
10
+ # Get the test catalog name instead of any random concept name
11
+ concept_name = get_test_catalog_concept_name(measure.concept_id)
12
+ program_id = ''
13
13
  if measure.obs_id.present?
14
- obs = Observation.find(measure.obs_id)
14
+ obs = Observation.unscope(where: :obs_group_id).find(measure.obs_id)
15
15
  encounter = Encounter.find(obs.encounter_id)
16
16
  program_id = encounter.program_id
17
17
  end
@@ -19,8 +19,8 @@ module Lab
19
19
  {
20
20
  id: measure.obs_id,
21
21
  indicator: {
22
- concept_id: concept_name&.concept_id,
23
- name: concept_name&.name
22
+ concept_id: measure.concept_id,
23
+ name: concept_name
24
24
  },
25
25
  date: measure.obs_datetime,
26
26
  value:,
@@ -31,6 +31,12 @@ module Lab
31
31
  end
32
32
  end
33
33
 
34
+ def self.get_test_catalog_concept_name(concept_id)
35
+ return nil unless concept_id
36
+
37
+ ::ConceptAttribute.find_by(concept_id:, attribute_type: ConceptAttributeType.test_catalogue_name)&.value_reference
38
+ end
39
+
34
40
  def self.read_value(measure)
35
41
  %w[value_numeric value_coded value_boolean value_text].each do |field|
36
42
  value = measure.send(field) if measure.respond_to?(field)
@@ -61,7 +61,7 @@ module Lab
61
61
  INNER JOIN concept_attribute ca2 ON ca.concept_id = ca2.concept_id
62
62
  AND ca2.attribute_type_id = #{ConceptAttributeType.nlims_code.concept_attribute_type_id}
63
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})
64
+ AND ca.concept_id IN (#{concept_set.select(:concept_set).to_sql})
65
65
  GROUP BY ca.concept_id
66
66
  SQL
67
67
  end
@@ -4,7 +4,7 @@ module Lab
4
4
  # This class is used to encode and decode the JWT token
5
5
  module JsonWebTokenService
6
6
  class << self
7
- SECRET_KEY = Rails.application.secrets.secret_key_base.to_s
7
+ SECRET_KEY = Rails.application.credentials[:secret_key_base].to_s
8
8
 
9
9
  def encode(payload, request_ip, exp = 18.hours.from_now)
10
10
  payload[:exp] = exp.to_i
@@ -341,7 +341,7 @@ module Lab
341
341
  def nlims_order_exists?(tracking_number)
342
342
  response = in_authenticated_session do |headers|
343
343
  Rails.logger.info("Verifying order ##{tracking_number}")
344
- RestClient.get(expand_uri("orders/#{tracking_number}", api_version: 'v2'), headers)
344
+ RestClient.get(expand_uri("orders/#{tracking_number}/exists", api_version: 'v2'), headers)
345
345
  end
346
346
 
347
347
  Rails.logger.info("Order ##{tracking_number} verified... Parsing...")
@@ -216,7 +216,7 @@ module Lab
216
216
  end
217
217
 
218
218
  next if test.result || test_results['results'].blank?
219
-
219
+
220
220
  result_date = Time.now
221
221
  measures = test_results['results'].map do |indicator, value|
222
222
  measure = find_measure(order, indicator, value)
@@ -78,8 +78,12 @@ module Lab
78
78
  end
79
79
 
80
80
  def self.find_concept_by_name(name)
81
- ConceptName.joins("INNER JOIN concept_attribute ON concept_attribute.concept_id = concept_name.concept_id")
82
- .where("concept_attribute.value_reference = ?", CGI.unescapeHTML(name))
81
+ unescaped_name = CGI.unescapeHTML(name)
82
+ attribute_type_id = ConceptAttributeType.test_catalogue_name.concept_attribute_type_id
83
+
84
+ ConceptName.joins('INNER JOIN concept_attribute ON concept_attribute.concept_id = concept_name.concept_id')
85
+ .where('concept_attribute.attribute_type_id = ? AND concept_attribute.value_reference = ? AND concept_name.name = ?',
86
+ attribute_type_id, unescaped_name, unescaped_name)
83
87
  .first
84
88
  end
85
89
  end
@@ -20,7 +20,11 @@ module Lab
20
20
  serializer = {}
21
21
  results_obs = {}
22
22
  ActiveRecord::Base.transaction do
23
- test = Lab::LabTest.find(test_id) rescue nil
23
+ test = begin
24
+ Lab::LabTest.find(test_id)
25
+ rescue StandardError
26
+ nil
27
+ end
24
28
  test = Lab::LabTest.find_by_uuid(test_id) if test.blank?
25
29
  encounter = find_encounter(test, encounter_id: params[:encounter_id],
26
30
  encounter_uuid: params[:encounter],
@@ -37,9 +41,9 @@ module Lab
37
41
 
38
42
  # force commit all transactions
39
43
  ActiveRecord::Base.connection.commit_db_transaction
40
-
41
- # delay job by a second
42
- ProcessLabResultJob.set(wait: 1.second).perform_later(results_obs.id, serializer, result_enter_by)
44
+
45
+ # Execute job synchronously
46
+ ProcessLabResultJob.perform_now(results_obs.id, serializer, result_enter_by)
43
47
 
44
48
  Rails.logger.info("Lab::ResultsService: Result created for test #{test_id} #{serializer}")
45
49
  serializer
@@ -55,10 +59,10 @@ module Lab
55
59
  def precess_notification_message(result, values, result_enter_by)
56
60
  order = Order.find(result.order_id)
57
61
  data = { Type: result_enter_by,
58
- Specimen: ConceptName.find_by(concept_id: order.concept_id)&.name,
59
- 'Test type': ConceptName.find_by(concept_id: result.test.value_coded)&.name,
62
+ Specimen: get_test_catalog_name(order.concept_id) || ConceptName.find_by(concept_id: order.concept_id)&.name,
63
+ 'Test type': get_test_catalog_name(result.test.value_coded) || ConceptName.find_by(concept_id: result.test.value_coded)&.name,
60
64
  'Accession number': order&.accession_number,
61
- 'Orde date': Order.columns.include?('start_date') ? order.start_date : order.date_created,
65
+ order_date: Order.columns.include?('start_date') ? order.start_date : order.date_created,
62
66
  'ARV-Number': find_arv_number(result.person_id),
63
67
  PatientID: result.person_id,
64
68
  'Ordered By': Order.columns.include?('provider_id') ? order&.provider&.person&.name : Person.find(order.creator)&.name,
@@ -82,19 +86,21 @@ module Lab
82
86
  def find_encounter(test, encounter_id: nil, encounter_uuid: nil, date: nil, provider_id: nil)
83
87
  return Encounter.find(encounter_id) if encounter_id
84
88
  return Encounter.find_by_uuid(encounter_uuid) if encounter_uuid
85
- encounter_type = EncounterType.find_by_name!(Lab::Metadata::ENCOUNTER_TYPE_NAME)
89
+
90
+ lab_encounter_type = EncounterType.find_by_name!(Lab::Metadata::ENCOUNTER_TYPE_NAME)
86
91
 
87
92
  encounter = Encounter.new
88
93
  encounter.patient_id = test.person_id
89
94
  encounter.program_id = test.encounter.program_id if Encounter.column_names.include?('program_id')
90
95
  encounter.visit_id = test.encounter.visit_id if Encounter.column_names.include?('visit_id')
91
- encounter.type = encounter_type
92
- encounter.encounter_type = encounter_type if (encounter&.encounter_type.nil? || encounter&.type.nil?)
96
+ # Use bracket notation to set the encounter_type column directly (bypasses association)
97
+ # This handles both Integer and EncounterType object
98
+ encounter_type_value = lab_encounter_type.is_a?(Integer) ? lab_encounter_type : lab_encounter_type.encounter_type_id
99
+ encounter[:encounter_type] = encounter_type_value
93
100
  encounter.encounter_datetime = date || Date.today
94
101
  encounter.provider_id = provider_id || User.current.user_id if Encounter.column_names.include?('provider_id')
95
-
96
102
  encounter.save!
97
-
103
+ encounter.reload
98
104
  encounter
99
105
  end
100
106
 
@@ -130,7 +136,8 @@ module Lab
130
136
  def add_measure_to_results(results_obs, params, date)
131
137
  validate_measure_params(params)
132
138
 
133
- concept_id = params[:indicator][:concept_id] || Concept.find_concept_by_uuid(params.dig(:indicator, :concept))&.id
139
+ concept_id = params[:indicator][:concept_id] || Concept.find_concept_by_uuid(params.dig(:indicator,
140
+ :concept))&.id
134
141
 
135
142
  Observation.create!(
136
143
  person_id: results_obs.person_id,
@@ -174,6 +181,13 @@ module Lab
174
181
  else raise InvalidParameterError, "Invalid boolean value: #{string}"
175
182
  end
176
183
  end
184
+
185
+ def get_test_catalog_name(concept_id)
186
+ return nil unless concept_id
187
+
188
+ ::ConceptAttribute.find_by(concept_id:,
189
+ attribute_type: ConceptAttributeType.test_catalogue_name)&.value_reference
190
+ end
177
191
  end
178
192
  end
179
193
  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 = '2.1.4-beta'
4
+ VERSION = '2.1.5.streaming'
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: 2.1.4.pre.beta
4
+ version: 2.1.5.streaming
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: 2026-01-29 00:00:00.000000000 Z
11
+ date: 2026-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: couchrest
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 7.0.6
47
+ version: 8.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 7.0.6
54
+ version: 8.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: socket.io-client-simple
57
57
  requirement: !ruby/object:Gem::Requirement