Module: Lab::LabOrderSerializer

Defined in:
app/serializers/lab/lab_order_serializer.rb

Class Method Summary collapse

Class Method Details

.concept_name(concept_id) ⇒ Object



71
72
73
74
75
# File 'app/serializers/lab/lab_order_serializer.rb', line 71

def self.concept_name(concept_id)
  return concept_id unless concept_id

  ::ConceptAttribute.find_by(concept_id:, attribute_type: ConceptAttributeType.test_catalogue_name)&.value_reference
end

.latest_order_status(order) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/serializers/lab/lab_order_serializer.rb', line 83

def self.latest_order_status(order)
  # Query obs table for latest order status
  latest_obs = order.status_trail_observations.last
  return nil unless latest_obs

  updated_by = parse_comments_json(latest_obs.comments)

  {
    status_id: 0, # status_id not used with text values
    status: latest_obs.value_text,
    timestamp: latest_obs.obs_datetime,
    updated_by: updated_by
  }
end

.latest_test_status(test) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/serializers/lab/lab_order_serializer.rb', line 112

def self.latest_test_status(test)
  # Query obs table for latest test status
  latest_obs = test.status_trail_observations.last
  return nil unless latest_obs

  updated_by = parse_comments_json(latest_obs.comments)

  {
    status_id: 0, # status_id not used with text values
    status: latest_obs.value_text,
    timestamp: latest_obs.obs_datetime,
    updated_by: updated_by
  }
end

.parse_comments_json(comments) ⇒ Object

Helper to parse updated_by from obs comments field



142
143
144
145
146
147
148
# File 'app/serializers/lab/lab_order_serializer.rb', line 142

def self.parse_comments_json(comments)
  return {} if comments.blank?

  JSON.parse(comments)
rescue JSON::ParserError
  {}
end

.serialize_order(order, tests: nil, requesting_clinician: nil, reason_for_test: nil, target_lab: nil, comment_to_fulfiller: nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/serializers/lab/lab_order_serializer.rb', line 5

def self.serialize_order(order, tests: nil, requesting_clinician: nil, reason_for_test: nil, target_lab: nil, comment_to_fulfiller: nil)
  tests ||= order.voided == 1 ? voided_tests(order) : order.tests
  requesting_clinician ||= order.requesting_clinician
  comment_to_fulfiller ||= order.comment_to_fulfiller
  reason_for_test ||= order.reason_for_test
  target_lab = target_lab&.value_text || order.target_lab&.value_text || Location.current_health_center&.name

  encounter = Encounter.find_by_encounter_id(order.encounter_id)
  program = Program.find_by_program_id(encounter&.program_id)

  ActiveSupport::HashWithIndifferentAccess.new(
    {
      id: order.order_id,
      order_type_id: order.order_type_id,
      order_id: order.order_id, # Deprecated: Link to :id
      encounter_id: order.encounter_id,
      **(Encounter.column_names.include?('visit_id') ? { visit_id: encounter&.visit_id } : {}),
      order_date: order.start_date,
      location_id: encounter&.location_id,
      program_id: encounter&.program_id,
      program_name: program&.name,
      patient_id: order.patient_id,
      accession_number: order.accession_number,
      specimen: {
        concept_id: order.concept_id,
        name: concept_name(order.concept_id)
      },
      requesting_clinician: requesting_clinician&.value_text,
      target_lab: target_lab,
      comment_to_fulfiller: comment_to_fulfiller.respond_to?(:value_text) ? comment_to_fulfiller.value_text : comment_to_fulfiller,
      reason_for_test: {
        concept_id: reason_for_test&.value_coded,
        name: concept_name(reason_for_test&.value_coded)
      },
      delivery_mode: order&.lims_acknowledgement_status&.acknowledgement_type,
      order_status: latest_order_status(order),
      order_status_trail: serialize_order_status_trail(order),
      tests: tests.map do |test|
        result_obs = test.result

        {
          id: test.obs_id,
          concept_id: test.value_coded,
          uuid: test.uuid,
          name: concept_name(test.value_coded),
          test_method: test_method(order, test.value_coded),
          result: result_obs && ResultSerializer.serialize(result_obs),
          test_status: latest_test_status(test),
          test_status_trail: serialize_test_status_trail(test)
        }
      end
    }
  )
end

.serialize_order_status_trail(order) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/serializers/lab/lab_order_serializer.rb', line 98

def self.serialize_order_status_trail(order)
  # Query obs table for order status trail
  order.status_trail_observations.map do |obs|
    updated_by = parse_comments_json(obs.comments)

    {
      status_id: 0, # status_id not used with text values
      status: obs.value_text,
      timestamp: obs.obs_datetime,
      updated_by: updated_by
    }
  end
end

.serialize_test_status_trail(test) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'app/serializers/lab/lab_order_serializer.rb', line 127

def self.serialize_test_status_trail(test)
  # Query obs table for test status trail
  test.status_trail_observations.map do |obs|
    updated_by = parse_comments_json(obs.comments)

    {
      status_id: 0, # status_id not used with text values
      status: obs.value_text,
      timestamp: obs.obs_datetime,
      updated_by: updated_by
    }
  end
end

.test_method(order, _concept_id) ⇒ Object



60
61
62
63
64
65
66
67
68
69
# File 'app/serializers/lab/lab_order_serializer.rb', line 60

def self.test_method(order, _concept_id)
  obs = ::Observation
        .select(:value_coded)
        .where(concept_id: ConceptName.find_by_name(Metadata::TEST_METHOD_CONCEPT_NAME).concept_id, order_id: order.id)
        .first
  {
    concept_id: obs&.value_coded,
    name: ConceptName.find_by_concept_id(obs&.value_coded)&.name
  }
end

.voided_tests(order) ⇒ Object



77
78
79
80
81
# File 'app/serializers/lab/lab_order_serializer.rb', line 77

def self.voided_tests(order)
  concept = ConceptName.where(name: Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
                       .select(:concept_id)
  LabTest.unscoped.where(concept:, order:, voided: true)
end