lis 0.2.1 → 0.2.2

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.
data/README.markdown CHANGED
@@ -1,9 +1,19 @@
1
1
  # LIS
2
2
 
3
- A simple interface to medical laboratory instruments. It implments a rough subset of ASTM E1394-97 (or, possibly CLSI LIS02-A2)
3
+ A simple interface to medical laboratory instruments. It implements a rough subset of ASTM E1394-97 (or, possibly CLSI LIS02-A2)
4
4
 
5
5
  It listens for test requests and results and forwards them via HTTP. It is intended to interface with the [worklist_manager](http://github.com/levinalex/worklist_manager) web application.
6
6
 
7
+
8
+ Developed for and tested with [DPC Immulite I2500][immulite] ([user manual][manual]) using the LIS specification version **600129-H** (not available online, but a [similar version might be
9
+ available][spec])
10
+
11
+ [immulite]: http://www.google.com/search?q=dpc+immulite+I2500
12
+ [manual]: http://sky2.ch/Doc/I2500.pdf
13
+ [spec]: http://www.google.com/search?q=dpc+lis+immulite+2000+filetype:pdf
14
+
15
+
16
+
7
17
  ## Copyright
8
18
 
9
- Copyright (c) 2010 Levin Alexander. See LICENSE for details.
19
+ Copyright (c) 2010-2011 Levin Alexander. See LICENSE for details.
data/Rakefile CHANGED
@@ -15,5 +15,8 @@ end
15
15
  require 'cucumber/rake/task'
16
16
  Cucumber::Rake::Task.new(:features)
17
17
 
18
- task :default => [:test, :features]
18
+ require 'yard'
19
+ YARD::Rake::YardocTask.new
19
20
 
21
+ task :doc => :yard
22
+ task :default => [:test, :features]
data/bin/lis2http CHANGED
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env ruby1.9
1
+ #!/usr/bin/env ruby
2
2
 
3
- require 'lib/lis.rb'
3
+ require 'lis'
4
4
  require 'lis/commands/application.rb'
5
5
 
6
6
  LIS::Application.new(ARGV).run!
data/features/lis.feature CHANGED
@@ -1,50 +1,75 @@
1
1
  Feature:
2
- In order to value
3
- As a role
4
- I want feature
2
+ In order to diagnose patients correctly
3
+ As a doctor
4
+ I want to be able to receive test results via LIS
5
+
6
+ Scenario: LIS asking for pending requests
7
+ Given LIS Interface listening for messages
8
+ And the following requests are pending for DPC:
9
+ | id | patient_id | last_name | first_name | test_names |
10
+ | 123ABC | 98 | Sierra | Rudolph | TSH, FT3, FT4, FOO, BAR, BAZ |
11
+ When receiving data
12
+ """
13
+ 1H|\^&||PASSWORD|DPC||Randolph^New^Jersey^07869||(201)927-2828|N81|Your System||P|1|19940407120613 51
14
+ 2Q|1|^123ABC||ALL||||||||O 76
15
+ 3L|1
16
+ """
17
+ Then LIS should have sent test orders to client:
18
+ """
19
+ 1H|\^&|||LIS||||8N1|DPC||P|1|
20
+ 2P|1||||Sierra^Rudolph||||||||
21
+ 3O|1|123ABC||^^^TSH
22
+ 4O|1|123ABC||^^^FT3
23
+ 5O|1|123ABC||^^^FT4
24
+ 6O|1|123ABC||^^^FOO
25
+ 7O|1|123ABC||^^^BAR
26
+ 0O|1|123ABC||^^^BAZ
27
+ 1L|1|N
28
+ """
5
29
 
6
30
  Scenario: sending results from Immulite to LIS
7
31
  Given LIS Interface listening for messages
8
- When receiving
32
+ When receiving data
9
33
  """
10
- H|\^||PASSWORD|DPC||||SYSTEM||P|1|19940407085426
11
- P|1|119813;TGH|||Last 1^First 1|||F|||||
12
- O|1|130000445||^^^TT4|||19950118085700
13
- R|1|^^^TT4|10.3|ug/dL|4.5\.4^12.5\24|N|N|F||test|19950119084508|19950119092826|SenderID
14
- O|2|130000445||^^^TU|||19950118085700
15
- R|1|^^^TU|26.6|Percnt|23\10^35\70|N|N|F||test|19950119084508|19950119092756|SenderID
16
- P|2|325031;AH|||Last 2^First 2|||F|||||
17
- O|1|130000617||^^^FER|||19950118103000
18
- R|1|^^^FER|173.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084641|19950119092858|SenderID
19
- P|3|326829;AH|||Last 3^First 3|||F|||||
20
- O|1|130000722||^^^FER|||19950118102000
21
- R|1|^^^FER|490.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084741|19950119092928|SenderID
22
- P|4|124462;TGH|||Last 4^First 4|||F|||||
23
- O|1|130000724||^^^E2|||19950118122000
24
- R|1|^^^E2|25.3|pg/mL|12\12^2000\2000|N|N|F||test|19950119084815|19950119100049|SenderID
25
- O|2|130000724||^^^FSH|||19950118122000
26
- R|1|^^^FSH|60.6|mIU/mL|.1\.1^170\170|N|N|F||test|19950119084815|19950119093030|SenderID
27
- O|3|130000724||^^^LH|||19950118122000
28
- R|1|^^^LH|24.4|mIU/mL|.7\.7^400\400|N|N|F||test|19950119084815|19950119093101|SenderID
29
- P|5|556395;AH|||Last 5^First 5|||M|||||
30
- O|1|130000741||^^^FER|||19950118115500
31
- R|1|^^^FER|238.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084949|19950119093132|SenderID
32
- P|6|556357;MB|||Last 6^First 6|||M|||||
33
- O|1|130000790||^^^IGE|||19950118120000
34
- R|1|^^^IGE|517.|IU/mL|.01\.01^600\600|N|N|F||test|19950119085018|19950119093202|SenderID
35
- P|7|141053;TGH|||Last 7^First 7|||F|||||
36
- O|1|130000805||^^^FER|||19950118120000
37
- R|1|^^^FER|21.0|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119085049|19950119093233|SenderID
38
- P|8|320439;TGH|||Last 8^First 8|||F|||||
39
- O|1|130000890||^^^FER|||19950118130000
40
- R|1|^^^FER|12.9|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119085254|19950119093609|SenderID
41
- P|9||||Last 9^First 9||||||||
42
- O|1|130000911||^^^E2
43
- R|1|^^^E2|71.3|pg/mL|12\12^2000\2000|N|N|F||test|19950119085423|19950119100800|SenderID
44
- P|10|358069;TGH|||Last 10^First 10|||F|||||
45
- O|1|130000929||^^^FER|||19950118123000
46
- R|1|^^^FER|219.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119085628|19950119093843|SenderID
47
- L|1
34
+ 1H|\^||PASSWORD|DPC||||SYSTEM||P|1|19940407085426
35
+ 2P|1|119813;TGH|||Last 1^First 1|||F|||||
36
+ 3O|1|130000445||^^^TT4|||19950118085700
37
+ 4R|1|^^^TT4|10.3|ug/dL|4.5\.4^12.5\24|N|N|F||test|19950119084508|19950119092826|SenderID
38
+ 5O|2|130000445||^^^TU|||19950118085700
39
+ 6R|1|^^^TU|26.6|Percnt|23\10^35\70|N|N|F||test|19950119084508|19950119092756|SenderID
40
+ 7P|2|325031;AH|||Last 2^First 2|||F|||||
41
+ 1O|1|130000617||^^^FER|||19950118103000
42
+ 2R|1|^^^FER|173.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084641|19950119092858|SenderID
43
+ 3P|3|326829;AH|||Last 3^First 3|||F|||||
44
+ 4O|1|130000722||^^^FER|||19950118102000
45
+ 5R|1|^^^FER|490.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084741|19950119092928|SenderID
46
+ 6P|4|124462;TGH|||Last 4^First 4|||F|||||
47
+ 7O|1|130000724||^^^E2|||19950118122000
48
+ 1R|1|^^^E2|25.3|pg/mL|12\12^2000\2000|N|N|F||test|19950119084815|19950119100049|SenderID
49
+ 2O|2|130000724||^^^FSH|||19950118122000
50
+ 3R|1|^^^FSH|60.6|mIU/mL|.1\.1^170\170|N|N|F||test|19950119084815|19950119093030|SenderID
51
+ 4O|3|130000724||^^^LH|||19950118122000
52
+ 5R|1|^^^LH|24.4|mIU/mL|.7\.7^400\400|N|N|F||test|19950119084815|19950119093101|SenderID
53
+ 6P|5|556395;AH|||Last 5^First 5|||M|||||
54
+ 7O|1|130000741||^^^FER|||19950118115500
55
+ 1R|1|^^^FER|238.|ng/mL|.5\.5^1500\1500|N|N|F||test|19950119084949|19950119093132|SenderID
56
+ 2P|6|556357;MB|||Last 6^First 6|||M|||||
57
+ 3O|1|130000790||^^^IGE|||19950118120000
58
+ 4R|1|^^^IGE|517.|IU/mL|.01\.01^600\600|N|N|F||test|19950119085018|19950119093202|SenderID
59
+ 5L|1
48
60
  """
49
- Then should have posted results:
50
- | device_name | barcode |
61
+ Then the server should have acknowledged 27 packets
62
+ And should have posted results:
63
+ | id | test_name | value | unit | status | flags | result_timestamp |
64
+ | DPC-130000445 | TT4 | 10.3 | ug/dL | F | N | 1995-01-19T09:28:26+00:00 |
65
+ | DPC-130000445 | TU | 26.6 | Percnt | F | N | 1995-01-19T09:27:56+00:00 |
66
+ | DPC-130000617 | FER | 173. | ng/mL | F | N | 1995-01-19T09:28:58+00:00 |
67
+ | DPC-130000722 | FER | 490. | ng/mL | F | N | 1995-01-19T09:29:28+00:00 |
68
+ | DPC-130000724 | E2 | 25.3 | pg/mL | F | N | 1995-01-19T10:00:49+00:00 |
69
+ | DPC-130000724 | FSH | 60.6 | mIU/mL | F | N | 1995-01-19T09:30:30+00:00 |
70
+ | DPC-130000724 | LH | 24.4 | mIU/mL | F | N | 1995-01-19T09:31:01+00:00 |
71
+ | DPC-130000741 | FER | 238. | ng/mL | F | N | 1995-01-19T09:31:32+00:00 |
72
+ | DPC-130000790 | IGE | 517. | IU/mL | F | N | 1995-01-19T09:32:02+00:00 |
73
+
74
+
75
+
@@ -0,0 +1,80 @@
1
+ require 'mocha'
2
+ require 'yaml'
3
+
4
+
5
+ Given /^LIS Interface listening for messages$/ do
6
+ @client, @r, @w = PacketIO::Test::MockServer.build
7
+ @io = PacketIO::IOListener.new(@r, @w)
8
+ @server = LIS::InterfaceServer.create(@io, "http://localhost/lis/")
9
+
10
+ stub_request(:post, /http:\/\/localhost\/lis\/result\/.*/).
11
+ with(:body => /.*/, :headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
12
+ to_return(:status => 200, :body => "", :headers => {})
13
+
14
+ @t = Thread.new do
15
+ @server.run!
16
+ end
17
+ @t.abort_on_exception = true
18
+ end
19
+
20
+ When /^receiving data$/ do |string|
21
+ @client.wait(0.2)
22
+ @client.write("\005")
23
+ string.each_line do |l|
24
+ line, checksum = l.strip.split(/\s*,\s*/)
25
+ checksum = line.each_byte.inject(16) { |a,b| (a+b) % 0x100 }.to_s(16) if checksum.nil?
26
+
27
+ @client.write("\002#{line}\015\003#{checksum}\015\012")
28
+ end
29
+ @client.write("\004")
30
+ @client.eof
31
+ @t.join
32
+ end
33
+
34
+ Then /^should have posted results:$/ do |table|
35
+ table.hashes.each do |row|
36
+ expected_body = ["test_name", "value", "unit", "status", "flags", "result_timestamp"].inject({}) { |h,k| h[k] = row[k]; h }
37
+ assert_requested(:post, "http://localhost/lis/result/#{row["id"]}", :times => 1, :body => expected_body)
38
+ end
39
+ end
40
+
41
+ Then /^the server should have acknowledged (\d+) packets$/ do |packet_count|
42
+ @data = @client.read_all
43
+ assert_equal packet_count.to_i, @data.split(//).length
44
+ assert @data.match(/^\006{#{packet_count}}$/), "should contain #{packet_count.to_i} ACKs, was #{@data.inspect}"
45
+ end
46
+
47
+
48
+ # FIXME: test following redirects
49
+ #
50
+ Given /^the following requests are pending for (\w+):$/ do |device_name, table|
51
+ table.hashes.each do |patient|
52
+ p patient
53
+
54
+ body = { "patient" => { "last_name" => patient["last_name"],
55
+ "first_name" => patient["first_name"],
56
+ "id" => patient["patient_id"]},
57
+ "id" => patient["id"],
58
+ "types" => patient["test_names"].strip.split(/\s+/) }
59
+ p body
60
+
61
+ stub_request(:get, "http://localhost/lis/find_requests/#{device_name}-#{patient["id"]}").
62
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
63
+ to_return(:status => 200, :body => body.to_yaml, :headers => {})
64
+
65
+ end
66
+
67
+ end
68
+
69
+
70
+ Then /^LIS should have sent test orders to client:$/ do |text|
71
+ @data = @client.read_all
72
+ @packets = @data.split("\002").select { |s| s =~ /^\d[A-Z]/ }
73
+ @packets.zip(text.lines) do |actual, expected|
74
+ rx = Regexp.new("^" + Regexp.escape(expected.strip))
75
+ assert_match(rx, actual.gsub(/\r\003.*$/, "").strip)
76
+ end
77
+ end
78
+
79
+
80
+
@@ -1,6 +1,9 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
2
  require 'lis'
3
3
 
4
+ require 'packet_io/test/mock_server'
4
5
  require 'test/unit/assertions'
6
+ require 'webmock/cucumber'
5
7
 
6
8
  World(Test::Unit::Assertions)
9
+
@@ -48,8 +48,8 @@ module LIS
48
48
  def run!
49
49
  warn "listening on: #{@options[:port]}"
50
50
  port = File.open(@options[:port], "w+")
51
- LIS::InterfaceServer.new(port, @options[:uri]).run!
51
+ LIS::InterfaceServer.listen(port, @options[:uri]).run!
52
52
  end
53
53
  end
54
54
 
55
- end
55
+ end
@@ -1,16 +1,25 @@
1
1
  module LIS
2
2
  class InterfaceServer
3
- def initialize(port, http_endpoint)
4
- @server = LIS::Transfer::IOListener.new(port)
5
- @packets = LIS::Transfer::PacketizedProtocol.new(@server)
3
+ def self.listen(port, http_endpoint)
4
+ interface = PacketIO::IOListener.new(port)
5
+ new(interface, http_endpoint)
6
+ end
7
+
8
+ def self.create(*args)
9
+ new(*args)
10
+ end
11
+
12
+
13
+ def initialize(server, http_endpoint, protocol_stack = [LIS::Transfer::ASTM::E1394, LIS::Transfer::ApplicationProtocol])
14
+ @server = server
15
+ protocol = protocol_stack.inject(server) { |i,klass| klass.new(i) }
16
+ interface = WorklistManagerInterface.new(http_endpoint)
6
17
 
7
- app_protocol = LIS::Transfer::ApplicationProtocol.new(@packets)
8
- interface = WorklistManagerInterface.new(http_endpoint)
9
18
 
10
- app_protocol.on_request do |device_name, barcode|
19
+ protocol.on_request do |device_name, barcode|
11
20
  interface.load_requests(device_name, barcode)
12
21
  end
13
- app_protocol.on_result do |*args|
22
+ protocol.on_result do |*args|
14
23
  interface.send_result(*args)
15
24
  end
16
25
  end
@@ -19,5 +28,11 @@ module LIS
19
28
  warn "listener started" if $VERBOSE
20
29
  @server.run!
21
30
  end
31
+
32
+
33
+ class << self
34
+ private :new
35
+ end
22
36
  end
23
37
  end
38
+
@@ -1,4 +1,7 @@
1
1
  module LIS::Message
2
+
3
+ # = Comment Message
4
+ #
2
5
  class Comment < Base
3
6
  type_id "C"
4
7
  has_field 3, :message
@@ -1,4 +1,30 @@
1
1
  module LIS::Message
2
+
3
+ # = Header Message
4
+ #
5
+ # First message sent in any transaction, contains system information such as sender ID, receiver ID, address, etc.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 1H|\^&||PASSWORD|DPC CIRRUS||Flanders^New^Jersey^07836||973-927-2828|N81|Your System||P|1|19940407120613
10
+ #
11
+ # == Message Structure
12
+ #
13
+ # 1. Record Type (H)
14
+ # 2. Delimiter Def.
15
+ # 3. Message Control ID
16
+ # 4. Password
17
+ # 5. Sending systems company name
18
+ # 6. Sending Systems address
19
+ # 7. Reserved
20
+ # 8. Senders Phone#
21
+ # 9. Communication parameters
22
+ # 10. Receiver ID
23
+ # 11. Comments/special instructions
24
+ # 12. Processing ID
25
+ # 13. Version#
26
+ # 14. Message Date + Time
27
+ #
2
28
  class Header < Base
3
29
  type_id "H"
4
30
  has_field 2, :delimiter_definition, :default => "\\^&"
@@ -21,3 +47,4 @@ module LIS::Message
21
47
  end
22
48
  end
23
49
  end
50
+
@@ -1,4 +1,54 @@
1
1
  module LIS::Message
2
+
3
+ # = Order Message
4
+ #
5
+ # Defines which test, such as TSH or HCG, should be performed on the sample for a particular accession number.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 3O|1|1550623||^^^LH|R|19931011091233|19931011091233
10
+ #
11
+ # 6O|1|130000724||^^^E2|||19950118122000
12
+ #
13
+ # 6O|1|66412558||^^^HCG|||200011081530||||||Normal|||||||||||E0872
14
+ #
15
+ # 1O|1|09861081||^^^TSH|R|||||||||||||||||||E0872
16
+ #
17
+ # == Message Structure
18
+ #
19
+ # 1. Record Type (O)
20
+ # 2. Sequence#
21
+ # 3. Specimen ID (Accession#)
22
+ # 4. Instrument Specimen ID
23
+ # 5. Universal Test ID
24
+ # 6. Priority
25
+ # 7. Order Date/Time
26
+ # 8. Collection Date/Time
27
+ # 9. Collection End Time
28
+ # 10. Collection Volume
29
+ # 11. Collector ID
30
+ # 12. Action Code
31
+ # 13. Danger Code
32
+ # 14. Relevant Clinical Info
33
+ # 15. Date/Time Specimen Received
34
+ # 16. Specimen Descriptor,Specimen Type,Specimen Source
35
+ # 17. Ordering Physician
36
+ # 18. Physician's Telephone Number
37
+ # 19. User Field No.1
38
+ # 20. User Field No.2
39
+ # 21. Lab Field No.1
40
+ # 22. Lab Field No.2
41
+ # 23. Date/Time results reported or last modified
42
+ # 24. Instrument Charge to Computer System
43
+ # 25. Instrument Section ID
44
+ # 26. Report Types
45
+ # 27. Reserved Field
46
+ # 28. Location or ward of Specimen Collection
47
+ # 29. Nosocomial Infection Flag
48
+ # 30. Specimen Service
49
+ # 31. Specimen Institution
50
+ #
51
+
2
52
  class Order < Base
3
53
  type_id "O"
4
54
 
@@ -33,3 +83,4 @@ module LIS::Message
33
83
  end
34
84
  end
35
85
  end
86
+
@@ -1,4 +1,60 @@
1
1
  module LIS::Message
2
+
3
+ # = Patient Message
4
+ #
5
+ # Contains patient information, patient ID, name.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 2P|1|101|||Riker^Al||19611102|F|||||Bashere
10
+ #
11
+ # 2P|3|326829;AH|||Last 3^First 3|||F|||||
12
+ #
13
+ # 2P|1|119813;TGH|||Last 1^First 1|||F|||||
14
+ #
15
+ # 5P|2|66412558|||||||||||
16
+ #
17
+ # == Message Structure
18
+ #
19
+ # 1. Record Type (P)
20
+ # 2. Sequence #
21
+ # 3. Practice Assigned Patient ID
22
+ # 4. Laboratory Assigned Patient ID
23
+ # 5. Patient ID
24
+ # 6. Patient Name
25
+ # (Last^First^Initial; maximum of 20 characters for Last Name; maximum of 15 characters for First Name)
26
+ # 7. Mother's Maiden Name
27
+ # 8. BirthDate
28
+ # (YYYYMMDD; maximum of 8 characters)
29
+ # 9. Patient Sex
30
+ # (M or F; maximum of 1 character)
31
+ # 10. Patient Race
32
+ # 11. Patient Address
33
+ # 12. Reserved
34
+ # 13. Patient Phone #
35
+ # 14. Attending Physician ID
36
+ # 15. Special Field 1
37
+ # 16. Special Field 2
38
+ # 17. Patient Height
39
+ # 18. Patient Weight
40
+ # 19. Patients Known or Suspected Diagnosis
41
+ # 20. Patient active medications
42
+ # 21. Patients Diet
43
+ # 22. Practice Field #1
44
+ # 23. Practice Field #2
45
+ # 24. Admission and Discharge Dates
46
+ # 25. Admission Status
47
+ # 26. Location
48
+ # 27. Nature of Alternative Diagnostic Code and Classification
49
+ # 28. Alternative Diagnostic Code and Classification
50
+ # 29. Patient Religion
51
+ # 30. Marital Status
52
+ # 31. Isolation Status
53
+ # 32. Language
54
+ # 33. Hospital Service
55
+ # 34. Hospital Institution
56
+ # 35. Dosage Category
57
+ #
2
58
  class Patient < Base
3
59
  type_id "P"
4
60
 
@@ -21,3 +77,4 @@ module LIS::Message
21
77
 
22
78
  end
23
79
  end
80
+
@@ -1,4 +1,41 @@
1
1
  module LIS::Message
2
+
3
+ # = Query Message
4
+ #
5
+ # A request to the LIS for patient information and test orders. Contains the primary tube accession number.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 2Q|1|^1234ABC||ALL|||||||O
10
+ #
11
+ # == Message Structure
12
+ #
13
+ # 1. Record Type ID (Q)
14
+ # 2. Sequence #
15
+ # 3. Starting Range
16
+ # 4. Ending Range
17
+ # 5. Test ID
18
+ # 6. Request Time Limits
19
+ # 7. Beginning request results date and time
20
+ # 8. Ending request results date and time
21
+ # 9. Physician name
22
+ # 10. Physician Phone Number
23
+ # 11. User Field 1
24
+ # 12. User Field 2
25
+ # 13. Status Codes
26
+ # C - Correction of previous results
27
+ # P - Preliminary Results
28
+ # F - Final Results
29
+ # X - Results cannot be done, cancel
30
+ # I - Request Results Pending
31
+ # S - Request partial results
32
+ # M - Result is a MIC level
33
+ # R - Result previously transmitted
34
+ # A - Abort/cancel last request
35
+ # N - Requesting new results only
36
+ # O - Requesting orders and demographics
37
+ # D - Requesting demographics only
38
+ #
2
39
  class Query < Base
3
40
  type_id "Q"
4
41
  has_field 3, :starting_range_id_internal
@@ -11,3 +48,4 @@ module LIS::Message
11
48
  end
12
49
  end
13
50
  end
51
+
@@ -1,4 +1,30 @@
1
1
  module LIS::Message
2
+
3
+ # = Result Message
4
+ #
5
+ # Contains test results and additional information, such as Test Code and the units in which the results are delivered. This message is sent to the LIS.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 4R|1|^^^LH|8.2|mIU/mL|.7\.7^400\400|N|N|F||test|19931011091233|19931011091233|DPCCIRRUS
10
+ #
11
+ # == Message Structure
12
+ #
13
+ # 1. Record Type (R)
14
+ # 2. Sequence #
15
+ # 3. Universal Test ID
16
+ # 4. Data (result)
17
+ # 5. Units
18
+ # 6. ReferenceRanges
19
+ # 7. Result abnormal flags
20
+ # 8. Nature of Abnormality Testing
21
+ # 9. Result Status
22
+ # 10. Date of change in instruments normal values or units
23
+ # 11. Operator ID
24
+ # 12. Date/Time Test Started
25
+ # 13. Date/Time Test Completed
26
+ # 14. Instrument ID
27
+ #
2
28
  class Result < Base
3
29
  type_id "R"
4
30
  has_field 3, :universal_test_id_internal
@@ -18,3 +44,4 @@ module LIS::Message
18
44
  end
19
45
  end
20
46
  end
47
+
@@ -1,4 +1,19 @@
1
1
  module LIS::Message
2
+
3
+ # = Terminator Message
4
+ #
5
+ # Last message sent in a transaction, contains termination codes.
6
+ #
7
+ # == Message Examples
8
+ #
9
+ # 5L|1|N
10
+ #
11
+ # == Message Structure
12
+ #
13
+ # 1. Record Type ID (L)
14
+ # 2. Sequence Number
15
+ # 3. Termination Code
16
+ #
2
17
  class Terminator < Base
3
18
  TERMINATION_CODES = {
4
19
  "N" => "Normal termination",
@@ -14,3 +29,4 @@ module LIS::Message
14
29
  has_field 3, :termination_code, :default => "N"
15
30
  end
16
31
  end
32
+