Module: Lab::OrdersService
- Defined in:
- app/services/lab/orders_service.rb
Overview
Manage lab orders.
Lab orders are just ordinary openmrs orders with extra metadata that separates them from other orders. Lab orders have an order type of ‘Lab’ with the order’s test type as the order’s concept. The order’s start date is the day the order is made. Additional information pertaining to the order is stored as observations that point to the order. The specimen types, requesting clinician, target lab, and reason for test are saved as observations to the order. Refer to method #order_test for more information.
Class Method Summary collapse
- .check_tracking_number(tracking_number) ⇒ Object
- .lab_orders(start_date, end_date, concept_id = nil, include_data: false) ⇒ Object
-
.order_test(order_params) ⇒ Object
Create a lab order.
- .update_order(order_id, params) ⇒ Object
- .update_order_result(order_params) ⇒ Object
- .update_order_status(order_params) ⇒ Object
- .void_order(order_id, reason) ⇒ Object
Class Method Details
.check_tracking_number(tracking_number) ⇒ Object
109 110 111 |
# File 'app/services/lab/orders_service.rb', line 109 def check_tracking_number(tracking_number) accession_number_exists?(tracking_number) || nlims_accession_number_exists?(tracking_number) end |
.lab_orders(start_date, end_date, concept_id = nil, include_data: false) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'app/services/lab/orders_service.rb', line 139 def lab_orders(start_date, end_date, concept_id = nil, include_data: false) tests = Lab::LabTest.where('date_created >= ? AND date_created <= ?', start_date, end_date) tests = tests.where(value_coded: concept_id) if concept_id orders = Lab::LabOrder.where(order_id: tests.pluck(:order_id)) data = { count: orders.count, last_order_date: Lab::LabOrder.last&.start_date&.to_date, lab_orders: [] } data[:lab_orders] = orders.map do |order| Lab::LabOrderSerializer.serialize_order( order, requesting_clinician: order.requesting_clinician, reason_for_test: order.reason_for_test, target_lab: order.target_lab ) end if include_data data end |
.order_test(order_params) ⇒ Object
Create a lab order.
Parameters schema:
{
encounter_id: {
type: :integer,
required: :false,
description: 'Attach order to this if program_id and patient_id are not provided'
},
program_id: { type: :integer, required: false },
patient_id: { type: :integer, required: false }
specimen: { type: :object, properties: { concept_id: :integer }, required: i[concept_id] },
test_type_ids: {
type: :array,
items: {
type: :object,
properties: { concept_id: :integer },
required: i[concept_id]
}
},
start_date: { type: :datetime }
accession_number: { type: :string }
target_lab: { type: :string },
reason_for_test_id: { type: :integer },
requesting_clinician: { type: :string }
}
encounter_id: is an ID of the encounter the lab order is to be created under test_type_id: is a concept_id of the name of test being ordered specimen_type_id: is a list of IDs for the specimens to be tested (can be ommited) target_lab: is the name of the lab where test will be carried out reason_for_test_id: is a concept_id for a (standard) reason of why the test is being carried out requesting_clinician: Name of the clinician requesting the test (defaults to current user)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/services/lab/orders_service.rb', line 52 def order_test(order_params) Order.transaction do encounter = find_encounter(order_params) if order_params[:accession_number].present? && check_tracking_number(order_params[:accession_number]) raise 'Accession number already exists' end order = create_order(encounter, order_params) Lab::TestsService.create_tests(order, order_params[:date], order_params[:tests]) Lab::LabOrderSerializer.serialize_order( order, requesting_clinician: add_requesting_clinician(order, order_params), reason_for_test: add_reason_for_test(order, order_params), target_lab: add_target_lab(order, order_params) ) end end |
.update_order(order_id, params) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'app/services/lab/orders_service.rb', line 71 def update_order(order_id, params) specimen_id = params.dig(:specimen, :concept_id) raise ::InvalidParameterError, 'Specimen concept_id is required' unless specimen_id order = Lab::LabOrder.find(order_id) if order.concept_id != unknown_concept_id && !params[:force_update]&.casecmp?('true') raise ::UnprocessableEntityError, "Can't change order specimen once set" end if specimen_id.to_i != order.concept_id Rails.logger.debug("Updating order ##{order.order_id}") order.update!(concept_id: specimen_id, discontinued: true, discontinued_by: User.current.user_id, discontinued_date: params[:date]&.to_date || Time.now, discontinued_reason_non_coded: 'Sample drawn/updated') end if params[:reason_for_test_id] Rails.logger.debug("Updating reason for test on order ##{order.order_id}") update_reason_for_test(order, params[:reason_for_test_id]) end Lab::LabOrderSerializer.serialize_order(order) end |
.update_order_result(order_params) ⇒ Object
132 133 134 135 136 137 |
# File 'app/services/lab/orders_service.rb', line 132 def update_order_result(order_params) order = find_order(order_params['tracking_number']) order_dto = Lab::Lims::OrderSerializer.serialize_order(order) patch_order_dto_with_lims_results!(order_dto, order_params['results']) Lab::Lims::PullWorker.new(nil).process_order(order_dto) end |
.update_order_status(order_params) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/services/lab/orders_service.rb', line 113 def update_order_status(order_params) # find the order order = find_order(order_params['tracking_number']) concept = ConceptName.find_by_name Lab::Metadata::LAB_ORDER_STATUS_CONCEPT_NAME ActiveRecord::Base.transaction do void_order_status(order, concept) Observation.create!( person_id: order.patient_id, encounter_id: order.encounter_id, concept_id: concept.concept_id, order_id: order.id, obs_datetime: order_params['status_time'] || Time.now, value_text: order_params['status'], creator: User.current.id ) end create_rejection_notification(order_params) if order_params['status'] == 'test-rejected' end |
.void_order(order_id, reason) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 |
# File 'app/services/lab/orders_service.rb', line 97 def void_order(order_id, reason) order = Lab::LabOrder.includes(i[requesting_clinician reason_for_test target_lab], tests: [:result]) .find(order_id) order.requesting_clinician&.void(reason) order.reason_for_test&.void(reason) order.target_lab&.void(reason) order.tests.each { |test| test.void(reason) } order.void(reason) end |