lis 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
+