hippo 0.4.1 → 0.5.0
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/CHANGELOG +7 -0
- data/Gemfile +3 -1
- data/hippo.gemspec +1 -1
- data/lib/hippo/segments/base.rb +1 -1
- data/lib/hippo/separator.rb +14 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2000B.rb +14 -11
- data/lib/hippo/transaction_sets/base.rb +13 -14
- data/lib/hippo/transaction_sets/component.rb +14 -3
- data/lib/hippo/version.rb +1 -1
- data/test/test_helper.rb +22 -0
- data/test/test_parser.rb +26 -2
- data/test/test_segments_base.rb +6 -0
- metadata +6 -6
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.5.0 - 2012/12/13
|
2
|
+
* Allow parsing of HIPAA_837::L2000B to properly handle the 'floating' L2300
|
3
|
+
loop.
|
4
|
+
* Make segment/loop inclusion conditional (when :parent_context_conditions
|
5
|
+
is used)
|
6
|
+
* Refactor TransactionSets::Base.grouped_components.
|
7
|
+
* Properly handle the removal of empty fields.
|
1
8
|
0.4.1 - 2012/09/14
|
2
9
|
* Fix major issue (stupid typo) with Date parsing.
|
3
10
|
0.4.0 - 2012/09/13
|
data/Gemfile
CHANGED
data/hippo.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "hippo"
|
16
16
|
|
17
17
|
s.add_development_dependency('minitest')
|
18
|
-
s.add_development_dependency('rake', '~>0.
|
18
|
+
s.add_development_dependency('rake', '~>10.0.2')
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
21
21
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/hippo/segments/base.rb
CHANGED
@@ -146,7 +146,7 @@ module Hippo::Segments
|
|
146
146
|
end
|
147
147
|
|
148
148
|
unless self.class.fixed_width
|
149
|
-
output = output
|
149
|
+
output = remove_empty_fields(output)
|
150
150
|
output = output.gsub(repeating_composite_separator_regexp, @field_separator)
|
151
151
|
end
|
152
152
|
|
data/lib/hippo/separator.rb
CHANGED
@@ -56,15 +56,26 @@ module Hippo
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def empty_field_regexp
|
59
|
-
%r{(
|
60
|
-
[
|
59
|
+
%r{([
|
61
60
|
#{Regexp.escape(@composite_separator)}
|
62
61
|
#{Regexp.escape(@field_separator)}
|
63
62
|
#{Regexp.escape(@segment_separator)}
|
64
63
|
])
|
65
64
|
\s+
|
66
|
-
(
|
65
|
+
([
|
66
|
+
#{Regexp.escape(@composite_separator)}
|
67
|
+
#{Regexp.escape(@field_separator)}
|
68
|
+
#{Regexp.escape(@segment_separator)}
|
69
|
+
])
|
67
70
|
}x
|
68
71
|
end
|
72
|
+
|
73
|
+
def remove_empty_fields(input)
|
74
|
+
while input =~ empty_field_regexp
|
75
|
+
input = input.gsub(empty_field_regexp, '\1\2')
|
76
|
+
end
|
77
|
+
|
78
|
+
input
|
79
|
+
end
|
69
80
|
end
|
70
81
|
end
|
@@ -55,17 +55,6 @@ module Hippo::TransactionSets
|
|
55
55
|
'NM1.NM108' => ["PI", "XV"]
|
56
56
|
}
|
57
57
|
|
58
|
-
#Patient Hierarchical Level
|
59
|
-
loop Hippo::TransactionSets::HIPAA_837::L2000C,
|
60
|
-
:name => 'Patient Hierarchical Level',
|
61
|
-
:minimum => 0,
|
62
|
-
:maximum => 99999,
|
63
|
-
:position => 10,
|
64
|
-
:identified_by => {
|
65
|
-
'HL.HL03' => '23',
|
66
|
-
'HL.HL04' => '0'
|
67
|
-
}
|
68
|
-
|
69
58
|
#Claim Information
|
70
59
|
loop Hippo::TransactionSets::HIPAA_837::L2300,
|
71
60
|
:name => 'Claim Information',
|
@@ -77,6 +66,20 @@ module Hippo::TransactionSets
|
|
77
66
|
'CLM.CLM07' => ["A", "B", "C"],
|
78
67
|
'CLM.CLM08' => ["N", "W", "Y"],
|
79
68
|
'CLM.CLM09' => ["I", "Y"]
|
69
|
+
},
|
70
|
+
:parent_context_conditions => {
|
71
|
+
'HL.HL04' => '0'
|
72
|
+
}
|
73
|
+
|
74
|
+
#Patient Hierarchical Level
|
75
|
+
loop Hippo::TransactionSets::HIPAA_837::L2000C,
|
76
|
+
:name => 'Patient Hierarchical Level',
|
77
|
+
:minimum => 0,
|
78
|
+
:maximum => 99999,
|
79
|
+
:position => 10,
|
80
|
+
:identified_by => {
|
81
|
+
'HL.HL03' => '23',
|
82
|
+
'HL.HL04' => '0'
|
80
83
|
}
|
81
84
|
|
82
85
|
end
|
@@ -24,29 +24,27 @@ module Hippo::TransactionSets
|
|
24
24
|
|
25
25
|
|
26
26
|
def grouped_components
|
27
|
-
|
28
|
-
|
29
|
-
initial_components = components.dup
|
30
|
-
@grouped_components = []
|
31
|
-
last_entry = nil
|
27
|
+
@grouped_components ||= build_grouped_components
|
28
|
+
end
|
32
29
|
|
33
|
-
|
34
|
-
|
30
|
+
def build_grouped_components
|
31
|
+
output = []
|
32
|
+
last_entry = nil
|
35
33
|
|
34
|
+
components.each do |component|
|
36
35
|
if component.segment?
|
37
|
-
|
38
|
-
|
36
|
+
output << [] if last_entry != :segment
|
37
|
+
output.last << component
|
39
38
|
last_entry = :segment
|
40
39
|
else
|
41
|
-
|
40
|
+
output << component
|
42
41
|
last_entry = :transaction_set
|
43
42
|
end
|
44
|
-
|
45
|
-
initial_components.delete(component)
|
46
43
|
end
|
47
44
|
|
48
|
-
|
45
|
+
output
|
49
46
|
end
|
47
|
+
private :build_grouped_components
|
50
48
|
end
|
51
49
|
|
52
50
|
attr_accessor :values, :parent, :sequences, :ISA, :GS, :GE, :IEA
|
@@ -68,7 +66,6 @@ module Hippo::TransactionSets
|
|
68
66
|
|
69
67
|
grouped_components.each_with_index do |component, component_index|
|
70
68
|
if component.class == Array
|
71
|
-
#binding.pry
|
72
69
|
# segments
|
73
70
|
starting_segment_count = segments.count
|
74
71
|
ending_segment_count = 0
|
@@ -81,6 +78,7 @@ module Hippo::TransactionSets
|
|
81
78
|
|
82
79
|
break unless segment
|
83
80
|
next unless individual_component.valid?(segment)
|
81
|
+
next unless individual_component.conditions_match?(self, segment)
|
84
82
|
|
85
83
|
segment.parent = self
|
86
84
|
|
@@ -103,6 +101,7 @@ module Hippo::TransactionSets
|
|
103
101
|
|
104
102
|
break unless initial_segment
|
105
103
|
break unless component.valid?(initial_segment)
|
104
|
+
break unless component.conditions_match?(self, initial_segment)
|
106
105
|
|
107
106
|
component_matches_found = []
|
108
107
|
starting_index = component.repeating? ? component_index : component_index + 1
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Hippo::TransactionSets
|
2
2
|
class Component
|
3
|
-
attr_reader :options, :klass, :sequence, :maximum, :identified_by
|
3
|
+
attr_reader :options, :klass, :sequence, :maximum, :identified_by, :conditions
|
4
4
|
|
5
5
|
def initialize(options)
|
6
|
-
@identified_by = options.delete(:identified_by)
|
7
|
-
@
|
6
|
+
@identified_by = options.delete(:identified_by) || {}
|
7
|
+
@conditions = options.delete(:parent_context_conditions) || {}
|
8
|
+
@maximum = options.delete(:maximum) || 1
|
8
9
|
@klass = options.delete(:klass)
|
9
10
|
@sequence = options.delete(:sequence)
|
10
11
|
|
@@ -81,5 +82,15 @@ module Hippo::TransactionSets
|
|
81
82
|
segment.identifier == segment_id && Array(value).include?(segment.send(field_name))
|
82
83
|
end
|
83
84
|
end
|
85
|
+
|
86
|
+
def conditions_match?(instance, segment)
|
87
|
+
if conditions.empty?
|
88
|
+
true
|
89
|
+
else
|
90
|
+
conditions.all? do |method, expected|
|
91
|
+
Array(expected).include?(instance.instance_eval("self." + method))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
84
95
|
end
|
85
96
|
end
|
data/lib/hippo/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -77,6 +77,28 @@ module Hippo::TransactionSets
|
|
77
77
|
}
|
78
78
|
end
|
79
79
|
|
80
|
+
class L0004 < Hippo::TransactionSets::Base
|
81
|
+
loop_name 'L0004'
|
82
|
+
|
83
|
+
segment Hippo::Segments::TSS,
|
84
|
+
:name => 'Indicator of Child Location',
|
85
|
+
:identified_by => {'TSS01' => ['HAS CHILD LOOP','HAS NO CHILD LOOP']}
|
86
|
+
|
87
|
+
loop Hippo::TransactionSets::Test::L0001,
|
88
|
+
:name => 'Test Sub-Loop L0001',
|
89
|
+
:identified_by => {
|
90
|
+
'TSS.TSS01' => 'Multiple Parents',
|
91
|
+
},
|
92
|
+
:parent_context_conditions => {
|
93
|
+
'TSS.TSS01' => 'HAS NO CHILD LOOP'
|
94
|
+
}
|
95
|
+
|
96
|
+
segment Hippo::Segments::TSS,
|
97
|
+
:name => 'Indicator of Child Location',
|
98
|
+
:identified_by => {'TSS01' => 'Multiple Parents'}
|
99
|
+
|
100
|
+
end
|
101
|
+
|
80
102
|
class Base < Hippo::TransactionSets::Base
|
81
103
|
|
82
104
|
segment Hippo::Segments::ST,
|
data/test/test_parser.rb
CHANGED
@@ -99,7 +99,31 @@ class TestParser < MiniTest::Unit::TestCase
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def test_parse_l2000a
|
102
|
-
|
103
|
-
|
102
|
+
files = ['samples/837_L2000A_01.edi', 'samples/837_L2000A_02.edi']
|
103
|
+
files.each do |f|
|
104
|
+
l2000a = Hippo::TransactionSets::HIPAA_837::L2000A.new.parse(File.read(f))
|
105
|
+
|
106
|
+
# when L2000B HL04 is '0' we must have a L2000C child
|
107
|
+
if l2000a.L2000B.HL.HL04 == '0'
|
108
|
+
assert_nil l2000a.L2000B.L2000C.HL.HL02
|
109
|
+
else
|
110
|
+
assert_equal l2000a.L2000B.HL.HL01, l2000a.L2000B.L2000C.HL.HL02
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_same_child_exists_in_multiple_levels
|
116
|
+
no_child_loop_string = "TSS*HAS NO CHILD LOOP~TSS*Multiple Parents~"
|
117
|
+
ts = Hippo::TransactionSets::Test::L0004.new
|
118
|
+
|
119
|
+
ts.parse(no_child_loop_string)
|
120
|
+
assert_equal 'TSS*Multiple Parents~', ts.values[1].TSS.to_s
|
121
|
+
|
122
|
+
|
123
|
+
child_loop_string = "TSS*HAS CHILD LOOP~TSS*Multiple Parents~"
|
124
|
+
ts = Hippo::TransactionSets::Test::L0004.new
|
125
|
+
|
126
|
+
ts.parse(child_loop_string)
|
127
|
+
assert_equal 'TSS*Multiple Parents~', ts.values[2].to_s
|
104
128
|
end
|
105
129
|
end
|
data/test/test_segments_base.rb
CHANGED
@@ -181,4 +181,10 @@ class TestSegmentsBase < MiniTest::Unit::TestCase
|
|
181
181
|
|
182
182
|
assert_equal nil, seg.TCS01_01
|
183
183
|
end
|
184
|
+
|
185
|
+
def test_segment_parse_for_composite_fields
|
186
|
+
input_string = "STC*A7:755:87*20121127*U*2200******A3:448**REJECTED AT CLEARINGHOUSE PAY-TO PROVIDER PRIMARY ID# IS NOT USED (1235196510) (59141)"
|
187
|
+
seg = Hippo::Segments::STC.new.parse(input_string)
|
188
|
+
assert_equal input_string + '~', seg.to_s
|
189
|
+
end
|
184
190
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hippo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-12-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: minitest
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
requirements:
|
36
36
|
- - ~>
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version: 0.
|
38
|
+
version: 10.0.2
|
39
39
|
type: :development
|
40
40
|
prerelease: false
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.
|
46
|
+
version: 10.0.2
|
47
47
|
description: HIPAA Transaction Set Generator/Parser
|
48
48
|
email:
|
49
49
|
- robertj@promedicalinc.com
|
@@ -341,7 +341,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
341
341
|
version: '0'
|
342
342
|
segments:
|
343
343
|
- 0
|
344
|
-
hash:
|
344
|
+
hash: -2604370158452349682
|
345
345
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
346
346
|
none: false
|
347
347
|
requirements:
|
@@ -350,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
350
350
|
version: '0'
|
351
351
|
segments:
|
352
352
|
- 0
|
353
|
-
hash:
|
353
|
+
hash: -2604370158452349682
|
354
354
|
requirements: []
|
355
355
|
rubyforge_project: hippo
|
356
356
|
rubygems_version: 1.8.24
|