his_emr_api_lab 1.1.19 → 1.1.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +8 -86
- data/MIT-LICENSE +0 -20
- data/README.md +0 -71
- data/Rakefile +0 -32
- data/app/controllers/lab/application_controller.rb +0 -6
- data/app/controllers/lab/labels_controller.rb +0 -17
- data/app/controllers/lab/orders_controller.rb +0 -38
- data/app/controllers/lab/reasons_for_test_controller.rb +0 -9
- data/app/controllers/lab/results_controller.rb +0 -19
- data/app/controllers/lab/specimen_types_controller.rb +0 -15
- data/app/controllers/lab/test_result_indicators_controller.rb +0 -9
- data/app/controllers/lab/test_types_controller.rb +0 -15
- data/app/controllers/lab/tests_controller.rb +0 -26
- data/app/jobs/lab/application_job.rb +0 -4
- data/app/jobs/lab/push_order_job.rb +0 -12
- data/app/jobs/lab/update_patient_orders_job.rb +0 -32
- data/app/jobs/lab/void_order_job.rb +0 -17
- data/app/mailers/lab/application_mailer.rb +0 -6
- data/app/models/lab/application_record.rb +0 -5
- data/app/models/lab/lab_accession_number_counter.rb +0 -13
- data/app/models/lab/lab_encounter.rb +0 -7
- data/app/models/lab/lab_order.rb +0 -54
- data/app/models/lab/lab_result.rb +0 -31
- data/app/models/lab/lab_test.rb +0 -19
- data/app/models/lab/lims_failed_import.rb +0 -4
- data/app/models/lab/lims_order_mapping.rb +0 -10
- data/app/serializers/lab/lab_order_serializer.rb +0 -55
- data/app/serializers/lab/result_serializer.rb +0 -36
- data/app/serializers/lab/test_serializer.rb +0 -29
- data/app/services/lab/accession_number_service.rb +0 -77
- data/app/services/lab/concepts_service.rb +0 -82
- data/app/services/lab/labelling_service/order_label.rb +0 -106
- data/app/services/lab/lims/api/blackhole_api.rb +0 -21
- data/app/services/lab/lims/api/couchdb_api.rb +0 -53
- data/app/services/lab/lims/api/mysql_api.rb +0 -316
- data/app/services/lab/lims/api/rest_api.rb +0 -413
- data/app/services/lab/lims/api/ws_api.rb +0 -121
- data/app/services/lab/lims/api_factory.rb +0 -19
- data/app/services/lab/lims/config.rb +0 -100
- data/app/services/lab/lims/exceptions.rb +0 -11
- data/app/services/lab/lims/migrator.rb +0 -216
- data/app/services/lab/lims/order_dto.rb +0 -105
- data/app/services/lab/lims/order_serializer.rb +0 -216
- data/app/services/lab/lims/pull_worker.rb +0 -289
- data/app/services/lab/lims/push_worker.rb +0 -144
- data/app/services/lab/lims/utils.rb +0 -91
- data/app/services/lab/lims/worker.rb +0 -86
- data/app/services/lab/metadata.rb +0 -24
- data/app/services/lab/orders_search_service.rb +0 -66
- data/app/services/lab/orders_service.rb +0 -212
- data/app/services/lab/results_service.rb +0 -122
- data/app/services/lab/tests_service.rb +0 -93
- data/config/routes.rb +0 -17
- data/db/migrate/20210126092910_create_lab_lab_accession_number_counters.rb +0 -12
- data/db/migrate/20210310115457_create_lab_lims_order_mappings.rb +0 -15
- data/db/migrate/20210323080140_change_lims_id_to_string_in_lims_order_mapping.rb +0 -15
- data/db/migrate/20210326195504_add_order_revision_to_lims_order_mapping.rb +0 -5
- data/db/migrate/20210407071728_create_lab_lims_failed_imports.rb +0 -19
- data/db/migrate/20210610095024_fix_numeric_results_value_type.rb +0 -20
- data/db/migrate/20210807111531_add_default_to_lims_order_mapping.rb +0 -7
- data/lib/auto12epl.rb +0 -201
- data/lib/couch_bum/couch_bum.rb +0 -92
- data/lib/generators/lab/install/USAGE +0 -9
- data/lib/generators/lab/install/install_generator.rb +0 -19
- data/lib/generators/lab/install/templates/rswag-ui-lab.rb +0 -5
- data/lib/generators/lab/install/templates/start_worker.rb +0 -32
- data/lib/generators/lab/install/templates/swagger.yaml +0 -714
- data/lib/his_emr_api_lab.rb +0 -5
- data/lib/lab/engine.rb +0 -15
- data/lib/lab/version.rb +0 -5
- data/lib/logger_multiplexor.rb +0 -38
- data/lib/tasks/lab_tasks.rake +0 -25
- data/lib/tasks/loaders/data/reasons-for-test.csv +0 -7
- data/lib/tasks/loaders/data/test-measures.csv +0 -225
- data/lib/tasks/loaders/data/tests.csv +0 -161
- data/lib/tasks/loaders/loader_mixin.rb +0 -53
- data/lib/tasks/loaders/metadata_loader.rb +0 -26
- data/lib/tasks/loaders/reasons_for_test_loader.rb +0 -23
- data/lib/tasks/loaders/specimens_loader.rb +0 -65
- data/lib/tasks/loaders/test_result_indicators_loader.rb +0 -54
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
module LabOrderSerializer
|
5
|
-
def self.serialize_order(order, tests: nil, requesting_clinician: nil, reason_for_test: nil, target_lab: nil)
|
6
|
-
tests ||= order.voided == 1 ? voided_tests(order) : order.tests
|
7
|
-
requesting_clinician ||= order.requesting_clinician
|
8
|
-
reason_for_test ||= order.reason_for_test
|
9
|
-
target_lab = target_lab&.value_text || order.target_lab&.value_text || Location.current_health_center&.name
|
10
|
-
|
11
|
-
ActiveSupport::HashWithIndifferentAccess.new(
|
12
|
-
{
|
13
|
-
id: order.order_id,
|
14
|
-
order_id: order.order_id, # Deprecated: Link to :id
|
15
|
-
encounter_id: order.encounter_id,
|
16
|
-
order_date: order.start_date,
|
17
|
-
patient_id: order.patient_id,
|
18
|
-
accession_number: order.accession_number,
|
19
|
-
specimen: {
|
20
|
-
concept_id: order.concept_id,
|
21
|
-
name: concept_name(order.concept_id)
|
22
|
-
},
|
23
|
-
requesting_clinician: requesting_clinician&.value_text,
|
24
|
-
target_lab: target_lab,
|
25
|
-
reason_for_test: {
|
26
|
-
concept_id: reason_for_test&.value_coded,
|
27
|
-
name: concept_name(reason_for_test&.value_coded)
|
28
|
-
},
|
29
|
-
tests: tests.map do |test|
|
30
|
-
result_obs = test.children.first
|
31
|
-
|
32
|
-
{
|
33
|
-
id: test.obs_id,
|
34
|
-
concept_id: test.value_coded,
|
35
|
-
name: concept_name(test.value_coded),
|
36
|
-
result: result_obs && ResultSerializer.serialize(result_obs)
|
37
|
-
}
|
38
|
-
end
|
39
|
-
}
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.concept_name(concept_id)
|
44
|
-
return concept_id unless concept_id
|
45
|
-
|
46
|
-
ConceptName.select(:name).find_by_concept_id(concept_id)&.name
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.voided_tests(order)
|
50
|
-
concept = ConceptName.where(name: Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
51
|
-
.select(:concept_id)
|
52
|
-
LabTest.unscoped.where(concept: concept, order: order, voided: true)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
##
|
5
|
-
# Serialize a Lab order result
|
6
|
-
module ResultSerializer
|
7
|
-
def self.serialize(result)
|
8
|
-
result.children.map do |measure|
|
9
|
-
value, value_type = read_value(measure)
|
10
|
-
concept_name = ConceptName.find_by_concept_id(measure.concept_id)
|
11
|
-
|
12
|
-
{
|
13
|
-
id: measure.obs_id,
|
14
|
-
indicator: {
|
15
|
-
concept_id: concept_name&.concept_id,
|
16
|
-
name: concept_name&.name
|
17
|
-
},
|
18
|
-
date: measure.obs_datetime,
|
19
|
-
value: value,
|
20
|
-
value_type: value_type,
|
21
|
-
value_modifier: measure.value_modifier
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.read_value(measure)
|
27
|
-
%w[value_numeric value_coded value_boolean value_text].each do |field|
|
28
|
-
value = measure.send(field)
|
29
|
-
|
30
|
-
return [value, field.split('_')[1]] if value
|
31
|
-
end
|
32
|
-
|
33
|
-
[nil, 'unknown']
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
module TestSerializer
|
5
|
-
def self.serialize(test, order: nil, result: nil)
|
6
|
-
order ||= test.order
|
7
|
-
result ||= test.result
|
8
|
-
|
9
|
-
{
|
10
|
-
id: test.obs_id,
|
11
|
-
concept_id: test.value_coded,
|
12
|
-
name: ConceptName.find_by_concept_id(test.value_coded)&.name,
|
13
|
-
order: {
|
14
|
-
id: order.order_id,
|
15
|
-
concept_id: order.concept_id,
|
16
|
-
name: ConceptName.find_by_concept_id(order.concept_id)&.name,
|
17
|
-
accession_number: order.accession_number
|
18
|
-
},
|
19
|
-
result: if result
|
20
|
-
{
|
21
|
-
id: result.obs_id,
|
22
|
-
modifier: result.value_modifier,
|
23
|
-
value: result.value_text
|
24
|
-
}
|
25
|
-
end
|
26
|
-
}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
# Responsible for the generation of tracking numbers
|
5
|
-
module AccessionNumberService
|
6
|
-
class << self
|
7
|
-
# Returns the next accession number on the given date or today.
|
8
|
-
#
|
9
|
-
# Throws:
|
10
|
-
# RangeError - If date is greater than system date
|
11
|
-
def next_accession_number(date = nil)
|
12
|
-
date = validate_date(date || Date.today)
|
13
|
-
counter = find_counter(date)
|
14
|
-
|
15
|
-
counter.with_lock do
|
16
|
-
accession_number = format_accession_number(date, counter.value)
|
17
|
-
counter.value += 1
|
18
|
-
counter.save!
|
19
|
-
|
20
|
-
return accession_number
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def find_counter(date)
|
27
|
-
counter = Lab::LabAccessionNumberCounter.find_by(date: date)
|
28
|
-
return counter if counter
|
29
|
-
|
30
|
-
Lab::LabAccessionNumberCounter.create(date: date, value: 1)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Checks if date does not exceed system date
|
34
|
-
def validate_date(date)
|
35
|
-
return date unless date > Date.today
|
36
|
-
|
37
|
-
raise RangeError, "Specified date exceeds system date: #{date} > #{Date.today}"
|
38
|
-
end
|
39
|
-
|
40
|
-
def format_accession_number(date, counter)
|
41
|
-
year = format_year(date.year)
|
42
|
-
month = format_month(date.month)
|
43
|
-
day = format_day(date.day)
|
44
|
-
|
45
|
-
"X#{site_code}#{year}#{month}#{day}#{counter}"
|
46
|
-
end
|
47
|
-
|
48
|
-
def format_year(year)
|
49
|
-
(year % 100).to_s.rjust(2, '0')
|
50
|
-
end
|
51
|
-
|
52
|
-
# It's base 32 that uses letters for values 10+ but the letters
|
53
|
-
# are ordered in a way that seems rather arbitrary
|
54
|
-
# (see #get_day in https://github.com/HISMalawi/nlims_controller/blob/3c0faf1cb6572a11cb3b9bd1ea8444f457d01fd7/lib/tracking_number_service.rb#L58)
|
55
|
-
DAY_NUMBERING_SYSTEM = %w[1 2 3 4 5 6 7 8 9 A B C E F G H Y J K Z M N O P Q R S T V W X].freeze
|
56
|
-
|
57
|
-
def format_day(day)
|
58
|
-
DAY_NUMBERING_SYSTEM[day - 1]
|
59
|
-
end
|
60
|
-
|
61
|
-
def format_month(month)
|
62
|
-
# Months use a base 13 numbering system that's just a subset of the
|
63
|
-
# numbering system used for days
|
64
|
-
format_day(month)
|
65
|
-
end
|
66
|
-
|
67
|
-
def site_code
|
68
|
-
property = GlobalProperty.find_by(property: 'site_prefix')
|
69
|
-
value = property&.property_value&.strip
|
70
|
-
|
71
|
-
raise "Global property 'site_prefix' not set" unless value
|
72
|
-
|
73
|
-
value
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
# A read-only repository of sort for all lab-centric concepts.
|
5
|
-
module ConceptsService
|
6
|
-
def self.test_types(name: nil, specimen_type: nil)
|
7
|
-
test_types = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
8
|
-
test_types = test_types.filter_members(name: name) if name
|
9
|
-
|
10
|
-
unless specimen_type
|
11
|
-
return test_types.joins('INNER JOIN concept_name ON concept_set.concept_id = concept_name.concept_id')
|
12
|
-
.select('concept_name.name, concept_name.concept_id')
|
13
|
-
.group('concept_name.concept_id')
|
14
|
-
end
|
15
|
-
|
16
|
-
# Filter out only those test types that have the specified specimen
|
17
|
-
# type.
|
18
|
-
specimen_types = ConceptSet.find_members_by_name(Lab::Metadata::SPECIMEN_TYPE_CONCEPT_NAME)
|
19
|
-
.filter_members(name: specimen_type)
|
20
|
-
.select(:concept_id)
|
21
|
-
|
22
|
-
concept_set = ConceptSet.where(
|
23
|
-
concept_id: specimen_types,
|
24
|
-
concept_set: test_types.select(:concept_id)
|
25
|
-
)
|
26
|
-
|
27
|
-
concept_set.joins('INNER JOIN concept_name ON concept_set.concept_set = concept_name.concept_id')
|
28
|
-
.select('concept_name.concept_id, concept_name.name')
|
29
|
-
.group('concept_name.concept_id')
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.specimen_types(name: nil, test_type: nil)
|
33
|
-
specimen_types = ConceptSet.find_members_by_name(Lab::Metadata::SPECIMEN_TYPE_CONCEPT_NAME)
|
34
|
-
specimen_types = specimen_types.filter_members(name: name) if name
|
35
|
-
|
36
|
-
unless test_type
|
37
|
-
return specimen_types.select('concept_name.concept_id, concept_name.name')
|
38
|
-
.joins('INNER JOIN concept_name ON concept_name.concept_id = concept_set.concept_id')
|
39
|
-
.group('concept_name.concept_id')
|
40
|
-
end
|
41
|
-
|
42
|
-
# Retrieve only those specimen types that belong to concept
|
43
|
-
# set of the selected test_type
|
44
|
-
test_types = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
45
|
-
.filter_members(name: test_type)
|
46
|
-
.select(:concept_id)
|
47
|
-
|
48
|
-
concept_set = ConceptSet.where(
|
49
|
-
concept_id: specimen_types.select(:concept_id),
|
50
|
-
concept_set: test_types
|
51
|
-
)
|
52
|
-
|
53
|
-
concept_set.select('concept_name.concept_id, concept_name.name')
|
54
|
-
.joins('INNER JOIN concept_name ON concept_name.concept_id = concept_set.concept_id')
|
55
|
-
.group('concept_name.concept_id')
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.test_result_indicators(test_type_id)
|
59
|
-
# Verify that the specified test_type is indeed a test_type
|
60
|
-
test = ConceptSet.find_members_by_name(Lab::Metadata::TEST_TYPE_CONCEPT_NAME)
|
61
|
-
.where(concept_id: test_type_id)
|
62
|
-
.select(:concept_id)
|
63
|
-
|
64
|
-
# From the members above, filter out only those concepts that are result indicators
|
65
|
-
measures = ConceptSet.find_members_by_name(Lab::Metadata::TEST_RESULT_INDICATOR_CONCEPT_NAME)
|
66
|
-
.select(:concept_id)
|
67
|
-
|
68
|
-
ConceptSet.where(concept_set: measures, concept_id: test)
|
69
|
-
.joins('INNER JOIN concept_name AS measure ON measure.concept_id = concept_set.concept_set')
|
70
|
-
.select('measure.concept_id, measure.name')
|
71
|
-
.group('measure.concept_id')
|
72
|
-
.map { |concept| { name: concept.name, concept_id: concept.concept_id } }
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.reasons_for_test
|
76
|
-
ConceptSet.find_members_by_name(Lab::Metadata::REASON_FOR_TEST_CONCEPT_NAME)
|
77
|
-
.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 } }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'auto12epl'
|
4
|
-
|
5
|
-
module Lab
|
6
|
-
module LabellingService
|
7
|
-
##
|
8
|
-
# Prints an order label for order with given accession number.
|
9
|
-
class OrderLabel
|
10
|
-
attr_reader :order
|
11
|
-
|
12
|
-
def initialize(order_id)
|
13
|
-
@order = Lab::LabOrder.find(order_id)
|
14
|
-
end
|
15
|
-
|
16
|
-
def print
|
17
|
-
# NOTE: The arguments are passed into the method below not in the order
|
18
|
-
# the method expects (eg patient_id is passed to middle_name field)
|
19
|
-
# to retain compatibility with labels generated by the `lab test controller`
|
20
|
-
# application of the NLIMS suite.
|
21
|
-
auto12epl.generate_epl(patient.given_name,
|
22
|
-
patient.family_name,
|
23
|
-
patient.nhid,
|
24
|
-
patient.birthdate.strftime('%d/%^b/%Y'),
|
25
|
-
'',
|
26
|
-
patient.gender,
|
27
|
-
'',
|
28
|
-
drawer,
|
29
|
-
'',
|
30
|
-
tests,
|
31
|
-
reason_for_test,
|
32
|
-
order.accession_number,
|
33
|
-
order.accession_number)
|
34
|
-
end
|
35
|
-
|
36
|
-
def reason_for_test
|
37
|
-
return 'Unknown' unless order.reason_for_test
|
38
|
-
|
39
|
-
short_concept_name(order.reason_for_test.value_coded) || 'Unknown'
|
40
|
-
end
|
41
|
-
|
42
|
-
def patient
|
43
|
-
return @patient if @patient
|
44
|
-
|
45
|
-
person = Person.find(order.patient_id)
|
46
|
-
person_name = PersonName.find_by_person_id(order.patient_id)
|
47
|
-
patient_identifier = PatientIdentifier.where(type: PatientIdentifierType.where(name: 'National id'),
|
48
|
-
patient_id: order.patient_id)
|
49
|
-
.first
|
50
|
-
|
51
|
-
@patient = OpenStruct.new(
|
52
|
-
given_name: person_name.given_name,
|
53
|
-
family_name: person_name.family_name,
|
54
|
-
birthdate: person.birthdate,
|
55
|
-
gender: person.gender,
|
56
|
-
nhid: patient_identifier&.identifier || 'Unknown'
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
def drawer
|
61
|
-
return 'N/A' if order.concept_id == unknown_concept.concept_id
|
62
|
-
|
63
|
-
drawer_id = User.find(order.discontinued_by || order.creator).person_id
|
64
|
-
draw_date = (order.discontinued_date || order.start_date).strftime('%d/%^b/%Y %H:%M:%S')
|
65
|
-
|
66
|
-
name = PersonName.find_by_person_id(drawer_id)
|
67
|
-
return "#{name.given_name} #{name.family_name} #{draw_date}" if name
|
68
|
-
|
69
|
-
user = User.find_by_user_id(drawer_id)
|
70
|
-
user ? "#{user.username} #{draw_date}" : 'N/A'
|
71
|
-
end
|
72
|
-
|
73
|
-
def specimen
|
74
|
-
return 'N/A' if order.concept_id == unknown_concept.concept_id
|
75
|
-
|
76
|
-
ConceptName.find_by_concept_id(order.concept_id)&.name || 'Unknown'
|
77
|
-
end
|
78
|
-
|
79
|
-
def tests
|
80
|
-
tests = order.tests.map do |test|
|
81
|
-
name = short_concept_name(test.value_coded) || 'Unknown'
|
82
|
-
|
83
|
-
next 'VL' if name.match?(/Viral load/i)
|
84
|
-
|
85
|
-
name.size > 7 ? name[0..6] : name
|
86
|
-
end
|
87
|
-
|
88
|
-
tests.join(', ')
|
89
|
-
end
|
90
|
-
|
91
|
-
def short_concept_name(concept_id)
|
92
|
-
ConceptName.where(concept_id: concept_id)
|
93
|
-
.min_by { |concept| concept.name.size }
|
94
|
-
&.name
|
95
|
-
end
|
96
|
-
|
97
|
-
def unknown_concept
|
98
|
-
ConceptName.find_by_name('Unknown')
|
99
|
-
end
|
100
|
-
|
101
|
-
def auto12epl
|
102
|
-
Auto12Epl.new
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lab
|
4
|
-
module Lims
|
5
|
-
module Api
|
6
|
-
##
|
7
|
-
# A LIMS Api wrappper that does nothing really.
|
8
|
-
#
|
9
|
-
# Primarily meant as a dummy for testing environments.
|
10
|
-
class BlackholeApi
|
11
|
-
def create_order(order_dto); end
|
12
|
-
|
13
|
-
def update_order(order_dto); end
|
14
|
-
|
15
|
-
def void_order(order_dto); end
|
16
|
-
|
17
|
-
def consume_orders(&_block); end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'couch_bum/couch_bum'
|
4
|
-
|
5
|
-
require_relative '../config'
|
6
|
-
|
7
|
-
module Lab
|
8
|
-
module Lims
|
9
|
-
module Api
|
10
|
-
##
|
11
|
-
# Talk to LIMS like a boss
|
12
|
-
class CouchDbApi
|
13
|
-
attr_reader :bum
|
14
|
-
|
15
|
-
def initialize(config: nil)
|
16
|
-
config ||= Config.couchdb
|
17
|
-
|
18
|
-
@bum = CouchBum.new(protocol: config['protocol'],
|
19
|
-
host: config['host'],
|
20
|
-
port: config['port'],
|
21
|
-
database: "#{config['prefix']}_order_#{config['suffix']}",
|
22
|
-
username: config['username'],
|
23
|
-
password: config['password'])
|
24
|
-
end
|
25
|
-
|
26
|
-
##
|
27
|
-
# Consume orders from the LIMS queue.
|
28
|
-
#
|
29
|
-
# Retrieves orders from the LIMS queue and passes each order to
|
30
|
-
# given block until the queue is empty or connection is terminated
|
31
|
-
# by calling method +choke+.
|
32
|
-
def consume_orders(from: 0, limit: 30)
|
33
|
-
bum.binge_changes(since: from, limit: limit, include_docs: true) do |change|
|
34
|
-
next unless change['doc']['type']&.casecmp?('Order')
|
35
|
-
|
36
|
-
yield OrderDTO.new(change['doc']), self
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def create_order(order)
|
41
|
-
order = order.dup
|
42
|
-
order.delete('_id')
|
43
|
-
|
44
|
-
bum.couch_rest :post, '/', order
|
45
|
-
end
|
46
|
-
|
47
|
-
def update_order(id, order)
|
48
|
-
bum.couch_rest :put, "/#{id}", order
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|