hippo 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -5
- data/README.md +10 -5
- data/lib/hippo/parser.rb +19 -9
- data/lib/hippo/transaction_sets/HIPAA_276/L2000A.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_276/L2000B.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_276/L2000C.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_276/L2000D.rb +15 -8
- data/lib/hippo/transaction_sets/HIPAA_276/L2000E.rb +12 -7
- data/lib/hippo/transaction_sets/HIPAA_276/L2100A.rb +3 -2
- data/lib/hippo/transaction_sets/HIPAA_276/L2100B.rb +2 -1
- data/lib/hippo/transaction_sets/HIPAA_276/L2100C.rb +4 -2
- data/lib/hippo/transaction_sets/HIPAA_276/L2100D.rb +4 -2
- data/lib/hippo/transaction_sets/HIPAA_276/L2100E.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_276/L2200D.rb +13 -12
- data/lib/hippo/transaction_sets/HIPAA_276/L2200E.rb +13 -12
- data/lib/hippo/transaction_sets/HIPAA_276/L2210D.rb +4 -3
- data/lib/hippo/transaction_sets/HIPAA_276/L2210E.rb +4 -3
- data/lib/hippo/transaction_sets/HIPAA_276/base.rb +31 -27
- data/lib/hippo/transaction_sets/HIPAA_277/L2000A.rb +11 -4
- data/lib/hippo/transaction_sets/HIPAA_277/L2000B.rb +13 -6
- data/lib/hippo/transaction_sets/HIPAA_277/L2000C.rb +13 -6
- data/lib/hippo/transaction_sets/HIPAA_277/L2000D.rb +12 -6
- data/lib/hippo/transaction_sets/HIPAA_277/L2000E.rb +11 -6
- data/lib/hippo/transaction_sets/HIPAA_277/L2100A.rb +4 -2
- data/lib/hippo/transaction_sets/HIPAA_277/L2100B.rb +2 -1
- data/lib/hippo/transaction_sets/HIPAA_277/L2100C.rb +4 -2
- data/lib/hippo/transaction_sets/HIPAA_277/L2100D.rb +3 -2
- data/lib/hippo/transaction_sets/HIPAA_277/L2100E.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_277/L2200A.rb +3 -3
- data/lib/hippo/transaction_sets/HIPAA_277/L2200B.rb +10 -7
- data/lib/hippo/transaction_sets/HIPAA_277/L2200C.rb +14 -8
- data/lib/hippo/transaction_sets/HIPAA_277/L2200D.rb +13 -9
- data/lib/hippo/transaction_sets/HIPAA_277/L2200E.rb +12 -11
- data/lib/hippo/transaction_sets/HIPAA_277/L2220D.rb +7 -6
- data/lib/hippo/transaction_sets/HIPAA_277/L2220E.rb +5 -4
- data/lib/hippo/transaction_sets/HIPAA_277/base.rb +23 -20
- data/lib/hippo/transaction_sets/HIPAA_835/L1000A.rb +9 -6
- data/lib/hippo/transaction_sets/HIPAA_835/L1000B.rb +12 -5
- data/lib/hippo/transaction_sets/HIPAA_835/L2000.rb +6 -2
- data/lib/hippo/transaction_sets/HIPAA_835/L2100.rb +55 -24
- data/lib/hippo/transaction_sets/HIPAA_835/L2110.rb +30 -9
- data/lib/hippo/transaction_sets/HIPAA_835/base.rb +23 -13
- data/lib/hippo/transaction_sets/HIPAA_837/L1000A.rb +5 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L1000B.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_837/L2000A.rb +30 -9
- data/lib/hippo/transaction_sets/HIPAA_837/L2000B.rb +42 -7
- data/lib/hippo/transaction_sets/HIPAA_837/L2000C.rb +17 -5
- data/lib/hippo/transaction_sets/HIPAA_837/L2010AA.rb +14 -6
- data/lib/hippo/transaction_sets/HIPAA_837/L2010AB.rb +3 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2010AC.rb +8 -4
- data/lib/hippo/transaction_sets/HIPAA_837/L2010BA.rb +9 -7
- data/lib/hippo/transaction_sets/HIPAA_837/L2010BB.rb +11 -4
- data/lib/hippo/transaction_sets/HIPAA_837/L2010CA.rb +10 -6
- data/lib/hippo/transaction_sets/HIPAA_837/L2300.rb +116 -56
- data/lib/hippo/transaction_sets/HIPAA_837/L2310A.rb +6 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2310B.rb +8 -4
- data/lib/hippo/transaction_sets/HIPAA_837/L2310C.rb +6 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2310D.rb +5 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2310E.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_837/L2310F.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_837/L2320.rb +54 -19
- data/lib/hippo/transaction_sets/HIPAA_837/L2330A.rb +5 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2330B.rb +12 -8
- data/lib/hippo/transaction_sets/HIPAA_837/L2330C.rb +6 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2330D.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2330E.rb +5 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2330F.rb +5 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2330G.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2400.rb +122 -60
- data/lib/hippo/transaction_sets/HIPAA_837/L2410.rb +8 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2420A.rb +8 -4
- data/lib/hippo/transaction_sets/HIPAA_837/L2420B.rb +7 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2420C.rb +5 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2420D.rb +5 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2420E.rb +8 -4
- data/lib/hippo/transaction_sets/HIPAA_837/L2420F.rb +6 -2
- data/lib/hippo/transaction_sets/HIPAA_837/L2420G.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_837/L2420H.rb +1 -1
- data/lib/hippo/transaction_sets/HIPAA_837/L2430.rb +6 -3
- data/lib/hippo/transaction_sets/HIPAA_837/L2440.rb +4 -1
- data/lib/hippo/transaction_sets/HIPAA_837/base.rb +23 -32
- data/lib/hippo/transaction_sets/HIPAA_999/L2000AK2.rb +9 -3
- data/lib/hippo/transaction_sets/HIPAA_999/L2100AK2.rb +9 -3
- data/lib/hippo/transaction_sets/HIPAA_999/L2110AK2.rb +4 -1
- data/lib/hippo/transaction_sets/HIPAA_999/base.rb +6 -3
- data/lib/hippo/transaction_sets/base.rb +87 -72
- data/lib/hippo/transaction_sets/component.rb +80 -0
- data/lib/hippo/transaction_sets/repeating_component.rb +30 -0
- data/lib/hippo/transaction_sets.rb +8 -6
- data/lib/hippo/version.rb +1 -1
- data/samples/005010X221A1_business_scenario_1.edi +1 -0
- data/samples/005010X221A1_tmhp_example.edi +1 -0
- data/samples/005010X222A1_anesthesia.edi +1 -0
- data/samples/005010X222A1_commercial_health_insurance.edi +1 -0
- data/test/test_helper.rb +6 -6
- data/test/test_hipaa_835.rb +229 -0
- data/test/test_hipaa_837.rb +263 -63
- data/test/test_parser.rb +26 -0
- data/test/test_segments_base.rb +1 -1
- data/test/test_transaction_sets_base.rb +21 -1
- metadata +17 -16
- data/bin/demo_270.rb +0 -280
- data/bin/demo_276.rb +0 -296
- data/bin/demo_835.rb +0 -170
- data/lib/hippo/samples/835.edi +0 -88
- data/lib/hippo/samples/sample_835_with.rb +0 -272
- data/lib/hippo/samples/sample_parsed.rb +0 -1162
@@ -16,7 +16,10 @@ module Hippo::TransactionSets
|
|
16
16
|
:name => 'Line Adjustment',
|
17
17
|
:minimum => 0,
|
18
18
|
:maximum => 5,
|
19
|
-
:position => 5450
|
19
|
+
:position => 5450,
|
20
|
+
:identified_by => {
|
21
|
+
'CAS01' => ["CO", "CR", "OA", "PI", "PR"]
|
22
|
+
}
|
20
23
|
|
21
24
|
#Line Check or Remittance Date
|
22
25
|
segment Hippo::Segments::DTP,
|
@@ -24,7 +27,7 @@ module Hippo::TransactionSets
|
|
24
27
|
:minimum => 1,
|
25
28
|
:maximum => 1,
|
26
29
|
:position => 5500,
|
27
|
-
:
|
30
|
+
:identified_by => {
|
28
31
|
'DTP01' => '573',
|
29
32
|
'DTP02' => 'D8'
|
30
33
|
}
|
@@ -35,7 +38,7 @@ module Hippo::TransactionSets
|
|
35
38
|
:minimum => 0,
|
36
39
|
:maximum => 1,
|
37
40
|
:position => 5505,
|
38
|
-
:
|
41
|
+
:identified_by => {
|
39
42
|
'AMT01' => 'EAF'
|
40
43
|
}
|
41
44
|
|
@@ -9,7 +9,10 @@ module Hippo::TransactionSets
|
|
9
9
|
:name => 'Form Identification Code',
|
10
10
|
:minimum => 0,
|
11
11
|
:maximum => 1,
|
12
|
-
:position => 5510
|
12
|
+
:position => 5510,
|
13
|
+
:identified_by => {
|
14
|
+
'LQ01' => ["AS", "UT"]
|
15
|
+
}
|
13
16
|
|
14
17
|
#Supporting Documentation
|
15
18
|
segment Hippo::Segments::FRM,
|
@@ -9,7 +9,7 @@ module Hippo::TransactionSets
|
|
9
9
|
:minimum => 1,
|
10
10
|
:maximum => 1,
|
11
11
|
:position => 50,
|
12
|
-
:
|
12
|
+
:identified_by => {
|
13
13
|
'ST01' => '837'
|
14
14
|
}
|
15
15
|
|
@@ -19,55 +19,46 @@ module Hippo::TransactionSets
|
|
19
19
|
:minimum => 1,
|
20
20
|
:maximum => 1,
|
21
21
|
:position => 100,
|
22
|
-
:
|
23
|
-
'BHT01' => '0019'
|
22
|
+
:identified_by => {
|
23
|
+
'BHT01' => '0019',
|
24
|
+
'BHT02' => ["00", "18"],
|
25
|
+
'BHT06' => ["31", "CH", "RP"]
|
24
26
|
}
|
25
27
|
|
26
28
|
#Submitter Name
|
27
29
|
loop Hippo::TransactionSets::HIPAA_837::L1000A,
|
28
30
|
:name => 'Submitter Name',
|
29
|
-
:identified_by => {'NM1.NM101' => '41'},
|
30
31
|
:minimum => 1,
|
31
32
|
:maximum => 1,
|
32
|
-
:position => 200
|
33
|
+
:position => 200,
|
34
|
+
:identified_by => {
|
35
|
+
'NM1.NM101' => '41',
|
36
|
+
'NM1.NM102' => ["1", "2"],
|
37
|
+
'NM1.NM108' => '46'
|
38
|
+
}
|
33
39
|
|
34
40
|
#Receiver Name
|
35
41
|
loop Hippo::TransactionSets::HIPAA_837::L1000B,
|
36
42
|
:name => 'Receiver Name',
|
37
|
-
:identified_by => {'NM1.NM101' => '40'},
|
38
43
|
:minimum => 1,
|
39
44
|
:maximum => 1,
|
40
|
-
:position => 500
|
45
|
+
:position => 500,
|
46
|
+
:identified_by => {
|
47
|
+
'NM1.NM101' => '40',
|
48
|
+
'NM1.NM102' => '2',
|
49
|
+
'NM1.NM108' => '46'
|
50
|
+
}
|
41
51
|
|
42
52
|
#Billing Provider Hierarchical Level
|
43
53
|
loop Hippo::TransactionSets::HIPAA_837::L2000A,
|
44
54
|
:name => 'Billing Provider Hierarchical Level',
|
45
|
-
:identified_by => {
|
46
|
-
'HL.HL03' => '20'
|
47
|
-
},
|
48
|
-
:minimum => 1,
|
49
|
-
:maximum => nil,
|
50
|
-
:position => 10
|
51
|
-
|
52
|
-
#Subscriber Hierarchical Level
|
53
|
-
loop Hippo::TransactionSets::HIPAA_837::L2000B,
|
54
|
-
:name => 'Subscriber Hierarchical Level',
|
55
|
-
:identified_by => {
|
56
|
-
'HL.HL03' => '22'
|
57
|
-
},
|
58
55
|
:minimum => 1,
|
59
|
-
:maximum =>
|
60
|
-
:position => 10
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
:identified_by => {
|
66
|
-
'HL.HL03' => '23'
|
67
|
-
},
|
68
|
-
:minimum => 0,
|
69
|
-
:maximum => nil,
|
70
|
-
:position => 10
|
56
|
+
:maximum => 99999,
|
57
|
+
:position => 10,
|
58
|
+
:identified_by => {
|
59
|
+
'HL.HL03' => '20',
|
60
|
+
'HL.HL04' => '1'
|
61
|
+
}
|
71
62
|
|
72
63
|
#Transaction Set Trailer
|
73
64
|
segment Hippo::Segments::SE,
|
@@ -15,15 +15,21 @@ module Hippo::TransactionSets
|
|
15
15
|
loop Hippo::TransactionSets::HIPAA_999::L2100AK2,
|
16
16
|
:name => 'Error Identification',
|
17
17
|
:minimum => 0,
|
18
|
-
:maximum =>
|
19
|
-
:position => 400
|
18
|
+
:maximum => 99999,
|
19
|
+
:position => 400,
|
20
|
+
:identified_by => {
|
21
|
+
'IK3.IK304' => ["1", "2", "3", "4", "5", "6", "7", "8", "I4", "I6", "I7", "I8", "I9"]
|
22
|
+
}
|
20
23
|
|
21
24
|
#Transaction Set Response Trailer
|
22
25
|
segment Hippo::Segments::IK5,
|
23
26
|
:name => 'Transaction Set Response Trailer',
|
24
27
|
:minimum => 1,
|
25
28
|
:maximum => 1,
|
26
|
-
:position => 800
|
29
|
+
:position => 800,
|
30
|
+
:identified_by => {
|
31
|
+
'IK501' => ["A", "E", "M", "R", "W", "X"]
|
32
|
+
}
|
27
33
|
|
28
34
|
end
|
29
35
|
end
|
@@ -9,7 +9,10 @@ module Hippo::TransactionSets
|
|
9
9
|
:name => 'Error Identification',
|
10
10
|
:minimum => 0,
|
11
11
|
:maximum => 1,
|
12
|
-
:position => 400
|
12
|
+
:position => 400,
|
13
|
+
:identified_by => {
|
14
|
+
'IK304' => ["1", "2", "3", "4", "5", "6", "7", "8", "I4", "I6", "I7", "I8", "I9"]
|
15
|
+
}
|
13
16
|
|
14
17
|
#Segment Context
|
15
18
|
segment Hippo::Segments::CTX,
|
@@ -29,8 +32,11 @@ module Hippo::TransactionSets
|
|
29
32
|
loop Hippo::TransactionSets::HIPAA_999::L2110AK2,
|
30
33
|
:name => 'Implementation Data Element Note',
|
31
34
|
:minimum => 0,
|
32
|
-
:maximum =>
|
33
|
-
:position => 600
|
35
|
+
:maximum => 99999,
|
36
|
+
:position => 600,
|
37
|
+
:identified_by => {
|
38
|
+
'IK4.IK403' => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "13", "I10", "I11", "I12", "I13", "I6", "I9"]
|
39
|
+
}
|
34
40
|
|
35
41
|
end
|
36
42
|
end
|
@@ -9,7 +9,10 @@ module Hippo::TransactionSets
|
|
9
9
|
:name => 'Implementation Data Element Note',
|
10
10
|
:minimum => 0,
|
11
11
|
:maximum => 1,
|
12
|
-
:position => 600
|
12
|
+
:position => 600,
|
13
|
+
:identified_by => {
|
14
|
+
'IK403' => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "13", "I10", "I11", "I12", "I13", "I6", "I9"]
|
15
|
+
}
|
13
16
|
|
14
17
|
#Element Context
|
15
18
|
segment Hippo::Segments::CTX,
|
@@ -9,7 +9,7 @@ module Hippo::TransactionSets
|
|
9
9
|
:minimum => 1,
|
10
10
|
:maximum => 1,
|
11
11
|
:position => 100,
|
12
|
-
:
|
12
|
+
:identified_by => {
|
13
13
|
'ST01' => '999'
|
14
14
|
}
|
15
15
|
|
@@ -24,7 +24,7 @@ module Hippo::TransactionSets
|
|
24
24
|
loop Hippo::TransactionSets::HIPAA_999::L2000AK2,
|
25
25
|
:name => 'Transaction Set Response Header',
|
26
26
|
:minimum => 0,
|
27
|
-
:maximum =>
|
27
|
+
:maximum => 99999,
|
28
28
|
:position => 300
|
29
29
|
|
30
30
|
#Functional Group Response Trailer
|
@@ -32,7 +32,10 @@ module Hippo::TransactionSets
|
|
32
32
|
:name => 'Functional Group Response Trailer',
|
33
33
|
:minimum => 1,
|
34
34
|
:maximum => 1,
|
35
|
-
:position => 900
|
35
|
+
:position => 900,
|
36
|
+
:identified_by => {
|
37
|
+
'AK901' => ["A", "E", "M", "P", "R", "W", "X"]
|
38
|
+
}
|
36
39
|
|
37
40
|
#Transaction Set Trailer
|
38
41
|
segment Hippo::Segments::SE,
|
@@ -12,24 +12,101 @@ module Hippo::TransactionSets
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def add_component(klass, options={})
|
15
|
-
options
|
16
|
-
|
17
|
-
components << options.merge(:class => klass, :sequence => components.length)
|
15
|
+
components << Component.new(options.merge(:klass => klass, :sequence => components.length))
|
18
16
|
end
|
19
17
|
alias segment add_component
|
20
18
|
alias loop add_component
|
21
19
|
end
|
22
20
|
|
23
|
-
attr_accessor :values, :parent
|
21
|
+
attr_accessor :values, :parent, :sequences
|
24
22
|
|
25
23
|
def initialize(options = {})
|
26
24
|
@parent = options.delete(:parent)
|
25
|
+
|
26
|
+
if options[:segments]
|
27
|
+
pp options[:segments]
|
28
|
+
populate options[:segments]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def populate(segments)
|
33
|
+
self.class.components.each_with_index do |component, component_index|
|
34
|
+
if component.klass.ancestors.include? Hippo::Segments::Base
|
35
|
+
# segments
|
36
|
+
segments_found = []
|
37
|
+
|
38
|
+
segments.each do |segment|
|
39
|
+
next unless component.valid? segment
|
40
|
+
|
41
|
+
if component.repeating?
|
42
|
+
values[component.sequence] ||= component.initialize_component(self)
|
43
|
+
values[component.sequence] << segment
|
44
|
+
else
|
45
|
+
values[component.sequence] = segment
|
46
|
+
end
|
47
|
+
|
48
|
+
segments_found << segment
|
49
|
+
end
|
50
|
+
|
51
|
+
segments -= segments_found
|
52
|
+
else
|
53
|
+
# loops
|
54
|
+
while true do
|
55
|
+
found_next_segment = false
|
56
|
+
starting_index = nil
|
57
|
+
length = 0
|
58
|
+
|
59
|
+
segments.each_with_index do |segment, segment_index|
|
60
|
+
next unless component.valid? segment
|
61
|
+
|
62
|
+
starting_index = segment_index
|
63
|
+
end
|
64
|
+
|
65
|
+
# if we don't find anything break out of the loop
|
66
|
+
break unless starting_index
|
67
|
+
|
68
|
+
remaining_components = self.class.components.slice(component_index + 1, self.class.components.length - 1)
|
69
|
+
|
70
|
+
remaining_components.each do |next_component|
|
71
|
+
break if found_next_segment
|
72
|
+
length = 0
|
73
|
+
|
74
|
+
segments.each_with_index do |segment, segment_index|
|
75
|
+
found_next_segment = next_component.valid? segment
|
76
|
+
break if found_next_segment
|
77
|
+
|
78
|
+
length += 1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
length = segments.length - starting_index if length == 0
|
83
|
+
|
84
|
+
subcomponent = component.initialize_component(self)
|
85
|
+
subcomponent.populate(segments.slice!(starting_index, length))
|
86
|
+
|
87
|
+
if component.repeating?
|
88
|
+
values[component.sequence] = component.initialize_component(self)
|
89
|
+
values[component.sequence] << subcomponent
|
90
|
+
else
|
91
|
+
values[component.sequence] = subcomponent
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
puts "Remaining Segments(#{self.class.identifier}): " + segments.inspect unless segments.empty?
|
27
98
|
end
|
28
99
|
|
29
100
|
def values
|
30
101
|
@values ||= {}
|
31
102
|
end
|
32
103
|
|
104
|
+
def increment(segment_identifier)
|
105
|
+
@sequences ||= Hash.new(0)
|
106
|
+
|
107
|
+
@sequences[segment_identifier] += 1
|
108
|
+
end
|
109
|
+
|
33
110
|
def segment_count
|
34
111
|
values.values.map(&:segment_count).inject(&:+)
|
35
112
|
end
|
@@ -52,85 +129,23 @@ module Hippo::TransactionSets
|
|
52
129
|
end
|
53
130
|
|
54
131
|
self.class.components.select do |c|
|
55
|
-
c
|
132
|
+
c.identifier == identifier
|
56
133
|
end[sequence]
|
57
134
|
end
|
58
135
|
|
59
|
-
def populate_component(component, defaults)
|
60
|
-
defaults ||= {}
|
61
|
-
|
62
|
-
defaults.each do |key, value|
|
63
|
-
if key =~ /(\w+)\.(.+)/
|
64
|
-
next_component, next_component_value = component.send($1.to_sym), {$2 => value}
|
65
|
-
|
66
|
-
populate_component(next_component, next_component_value)
|
67
|
-
else
|
68
|
-
component.send((key + '=').to_sym, value)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
component
|
73
|
-
end
|
74
|
-
|
75
|
-
def initialize_component(component_entry)
|
76
|
-
component = component_entry[:class].new :parent => self
|
77
|
-
|
78
|
-
# iterate through the hash of defaults
|
79
|
-
# and assign them to the component before
|
80
|
-
# adding to @values
|
81
|
-
populate_component(component, component_entry[:defaults])
|
82
|
-
populate_component(component, component_entry[:identified_by])
|
83
|
-
end
|
84
|
-
|
85
136
|
def method_missing(method_name, *args)
|
86
137
|
component_name, component_sequence = method_name.to_s.split('_')
|
87
|
-
|
138
|
+
component = get_component(component_name, component_sequence)
|
88
139
|
|
89
|
-
if
|
140
|
+
if component.nil?
|
90
141
|
raise Hippo::Exceptions::InvalidSegment.new "Invalid segment specified: '#{method_name.to_s}'."
|
91
142
|
end
|
92
143
|
|
93
|
-
|
94
|
-
|
95
|
-
component = if component_entry[:maximum] > 1
|
96
|
-
RepeatingComponent.new(component_entry, self)
|
97
|
-
else
|
98
|
-
initialize_component(component_entry)
|
99
|
-
end
|
100
|
-
|
101
|
-
values[component_entry[:sequence]] = component
|
102
|
-
end
|
103
|
-
|
104
|
-
yield values[component_entry[:sequence]] if block_given?
|
105
|
-
return values[component_entry[:sequence]]
|
106
|
-
end
|
144
|
+
values[component.sequence] ||= component.initialize_component(self)
|
107
145
|
|
108
|
-
|
109
|
-
def initialize(component_entry, parent)
|
110
|
-
@component_entry = component_entry
|
111
|
-
@parent = parent
|
112
|
-
end
|
113
|
-
|
114
|
-
def build
|
115
|
-
self.push(@parent.initialize_component(@component_entry))
|
116
|
-
|
117
|
-
yield self[-1] if block_given?
|
118
|
-
self[-1]
|
119
|
-
end
|
146
|
+
yield values[component.sequence] if block_given?
|
120
147
|
|
121
|
-
|
122
|
-
self.map(&:to_s).join
|
123
|
-
end
|
124
|
-
|
125
|
-
def segment_count
|
126
|
-
self.map(&:segment_count).inject(&:+)
|
127
|
-
end
|
128
|
-
|
129
|
-
def method_missing(method_name, *args, &block)
|
130
|
-
build if self.length == 0
|
131
|
-
|
132
|
-
self.first.send(method_name, *args, &block)
|
133
|
-
end
|
148
|
+
values[component.sequence]
|
134
149
|
end
|
135
150
|
end
|
136
151
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Hippo::TransactionSets
|
2
|
+
class Component
|
3
|
+
attr_reader :options, :klass, :sequence, :maximum, :identified_by
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@identified_by = options.delete(:identified_by) || {}
|
7
|
+
@maximum = options.delete(:maximum) || 1
|
8
|
+
@klass = options.delete(:klass)
|
9
|
+
@sequence = options.delete(:sequence)
|
10
|
+
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def repeating?
|
15
|
+
@maximum > 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def loop?
|
19
|
+
@klass.ancestors.include? Hippo::TransactionSets::Base
|
20
|
+
end
|
21
|
+
|
22
|
+
def identifier
|
23
|
+
@klass.identifier
|
24
|
+
end
|
25
|
+
|
26
|
+
def populate_component(component, defaults = nil)
|
27
|
+
defaults ||= identified_by
|
28
|
+
|
29
|
+
defaults.each do |key, value|
|
30
|
+
value = Array(value)
|
31
|
+
|
32
|
+
if key =~ /(\w+)\.(.+)/
|
33
|
+
next_component, next_component_value = component.send($1.to_sym), {$2 => value}
|
34
|
+
|
35
|
+
populate_component(next_component, next_component_value)
|
36
|
+
else
|
37
|
+
next if value.length > 1
|
38
|
+
|
39
|
+
component.send((key + '=').to_sym, value)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
component
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize_component(parent)
|
47
|
+
if repeating?
|
48
|
+
RepeatingComponent.new(self, parent)
|
49
|
+
else
|
50
|
+
populate_component(@klass.new(:parent => parent))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid?(segment)
|
55
|
+
if klass.ancestors.include? Hippo::Segments::Base
|
56
|
+
valid_segment?(segment)
|
57
|
+
else
|
58
|
+
valid_entry_segment?(segment)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid_segment?(segment)
|
63
|
+
segment.identifier == identifier && identified_by.all? {|k, v| Array(v).include?(segment.send(k.to_sym))}
|
64
|
+
end
|
65
|
+
|
66
|
+
def valid_entry_segment?(segment)
|
67
|
+
if identified_by.empty?
|
68
|
+
initial_segment_id = @klass.components.first.identifier
|
69
|
+
|
70
|
+
segment.identifier == initial_segment_id
|
71
|
+
else
|
72
|
+
path, value = identified_by.first
|
73
|
+
# TODO: handle arbitrary depth in loop identified_by parsing
|
74
|
+
segment_id, field_name = path.split('.')
|
75
|
+
|
76
|
+
segment.identifier == segment_id && Array(value).include?(segment.send(field_name))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hippo::TransactionSets
|
2
|
+
class RepeatingComponent < Array
|
3
|
+
def initialize(component_entry, parent)
|
4
|
+
@component_entry = component_entry
|
5
|
+
@parent = parent
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
component = @component_entry.populate_component(@component_entry.klass.new(:parent => @parent))
|
10
|
+
|
11
|
+
push(component)
|
12
|
+
yield component if block_given?
|
13
|
+
component
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
self.map(&:to_s).join
|
18
|
+
end
|
19
|
+
|
20
|
+
def segment_count
|
21
|
+
self.map(&:segment_count).inject(&:+)
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(method_name, *args, &block)
|
25
|
+
build if self.length == 0
|
26
|
+
|
27
|
+
self.first.send(method_name, *args, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module Hippo
|
2
2
|
module TransactionSets
|
3
3
|
|
4
|
-
autoload :Base,
|
5
|
-
autoload :
|
6
|
-
autoload :
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
4
|
+
autoload :Base, 'hippo/transaction_sets/base'
|
5
|
+
autoload :Component, 'hippo/transaction_sets/component'
|
6
|
+
autoload :RepeatingComponent, 'hippo/transaction_sets/repeating_component'
|
7
|
+
autoload :HIPAA_276, 'hippo/transaction_sets/HIPAA_276'
|
8
|
+
autoload :HIPAA_277, 'hippo/transaction_sets/HIPAA_277'
|
9
|
+
autoload :HIPAA_835, 'hippo/transaction_sets/HIPAA_835'
|
10
|
+
autoload :HIPAA_837, 'hippo/transaction_sets/HIPAA_837'
|
11
|
+
autoload :HIPAA_999, 'hippo/transaction_sets/HIPAA_999'
|
10
12
|
end
|
11
13
|
end
|
data/lib/hippo/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
ST*835*1234~BPR*C*150000*C*ACH*CTX*01*999999992*DA*123456*1512345678**01*999988880*DA*98765*20020913~TRN*1*12345*1512345678~DTM*405*20020916~N1*PR*INSURANCE COMPANY OF TIMBUCKTU~N3*1 MAIN STREET~N4*TIMBUCKTU*AK*89111~REF*2U*999~N1*PE*REGIONAL HOPE HOSPITAL*XX*6543210903~LX*110212~TS3*6543210903*11*20021231*1*211366.97****138018.4**73348.57~TS2*2178.45*1919.71**56.82*197.69*4.23~CLP*666123*1*211366.97*138018.4**MA*1999999444444*11*1~CAS*CO*45*73348.57~NM1*QC*1*JONES*SAM*O***HN*666666666A~MIA*0***138018.4~DTM*232*20020816~DTM*233*20020824~QTY*CA*8~LX*130212~TS3*6543210909*13*19961231*1*15000****11980.33**3019.67~CLP*777777*1*15000*11980.33**MB*1999999444445*13*1~CAS*CO*45*3019.67~NM1*QC*1*BORDER*LIZ*E***HN*996669999B~MOA***MA02~DTM*232*20020512~PLB*6543210903*20021231*CV:CP*-1.27~SE*28*1234~
|
@@ -0,0 +1 @@
|
|
1
|
+
ST*835*0001~BPR*I*40.80*C*CHK************20110707~TRN*1*020961585*1123456789~REF*EV*745276163~REF*F2*0001~DTM*405*20110701~N1*PR*TEXASMEDICAIDHEALTHCARESERVICES~N3*12365ARIATATRACEPARKWAY~N4*ARSTIN*TX*787276524~PER*BL*JOHNWAYNE*TE*8005551212*EX*123~N1*PE*PROV2*XX*1234567891~N3*ADDRESS2~N4*CITY2*TX*77210~REF*TJ*999999999~LX*1~CLP*PATACCTNTMBER11111*1*40.8*40.8**MC*111111*12*A**10*123456789012345*99999999.99~NM1*QC*1*SHEPHARD*SAM*O***HN*666666666A~NM1*74*1******C*555555555~NM1*PR*2*OHTERINSTRANCENAME2*****PI*9876543210~REF*EA*777~REF*SY*645507788~REF*F8*222222~REF*G1*444~DTM*232*20110103~DTM*233*20110105~PER*CX*1234*TE*5125125122~AMT*DY*9999.89~AMT*T*89988.01~QTY*CA*2222.2~SVC*HC:99215*40.8*40.8~DTM*472*20110223~REF*G3*12345678~REF*1D*749999999~REF*HPI*1234567890~SE*35*0001~ST*835*0002~BPR*I*40.8*C*CHK************20110707~TRN*1*020961585*1123456789~REF*F2*0001~DTM*405*20110301~N1*PR*TEXASMEDICAIDHEALTHCARESERVICES~N3*12365ATRACEPARKWAY~N4*ARSTIN*TX*787276524~PER*BL*JOHNWAYNE*TE*8005551212*EX*123~N1*PE*PROV2*XX*1234567899~N3*ADDRESS2~N4*CITY2*TX*77210~REF*TJ*999999999~LX*1~CLP*PATACCTNTMBER11111*1*40.8*40.8**MC*111111*12*A**10*123456789012345*99999999.99~NM1*QC*1*5PATIENTLASTNAME*PATFTNAM*N**PATSTFFIX*MI*444444444~NM1*74*1******C*555555555~NM1*PR*2*OHTERINSTRANCENAME2*****PI*9876543210~REF*EA*777~REF*SY*645507788~REF*F8*222222~REF*G1*444~DTM*232*20110103~DTM*233*20110107~PER*CX*1234*TE*5125125122~AMT*DY*9999.89~AMT*T*89988.01~QTY*CA*2222.2~SVC*HC:99215*40.8*40.8~DTM*472*20110223~REF*G3*12345678~REF*1D*749999999~REF*HPI*9999999990~SE*34*0002~
|
@@ -0,0 +1 @@
|
|
1
|
+
ST*837*0001*005010X222A1~BHT*0019*00*0123*20050117*1023*CH~NM1*41*2*PROVIDER MEDICAL GROUP*****46*N305~PER*IC*NINA*TE*6155551212*EX*911~NM1*40*2*ABC PAYER*****46*05440~HL*1**20*1~NM1*85*2*PROVIDER MEDICAL GROUP*****XX*2366554859~N3*1234 WEST END AVE~N4*NASHVILLE*TN*37232~REF*EI*756473826~HL*2*1*22*0~SBR*P*18*******MB~NM1*IL*1*JONES*MARGARET****MI*123456789A~N3*123 RAINBOW ROAD~N4*NASHVILLE*TN*37232~DMG*D8*19740303*F~NM1*PR*2*ABC PAYER*****PI*05440~CLM*153829140*827***22:B:1*Y*A*Y*Y~HI*BK:36616~NM1*82*1*TOWNSEND*JACOB*E***XX*5678912345~PRV*PE*ZZ*207L00000X~NM1*77*2*PROVIDER OP HOSP*****XX*432198765~N3*345 MAIN DRIVE~N4*NASHVILLE*TN*37232~LX*1~SV1*HC:00142:QK:QS:P1*827*MJ*61***1~DTP*472*D8*20050112~SE*28*0001~
|
@@ -0,0 +1 @@
|
|
1
|
+
ST*837*0021*005010X222A1~BHT*0019*00*244579*20061015*1023*CH~NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~PER*IC*JERRY*TE*3055552222*EX*231~NM1*40*2*KEY INSURANCE COMPANY*****46*66783JJT~HL*1**20*1~PRV*BI*PXC*203BF0100Y~NM1*85*2*BEN KILDARE SERVICE*****XX*9876543210~N3*234 SEAWAY ST~N4*MIAMI*FL*33111~REF*EI*587654321~NM1*87*2~N3*2345 OCEAN BLVD~N4*MIAMI*FL*33111~HL*2*1*22*1~SBR*P**2222-SJ******CI~NM1*IL*1*SMITH*JANE****MI*JS00111223333~DMG*D8*19430501*F~NM1*PR*2*KEY INSURANCE COMPANY*****PI*999996666~REF*G2*KA6663~HL*3*2*23*0~PAT*19~NM1*QC*1*SMITH*TED~N3*236 N MAIN ST~N4*MIAMI*FL*33413~DMG*D8*19730501*M~CLM*26463774*100***11:B:1*Y*A*Y*I~REF*D9*17312345600006351~HI*BK:0340*BF:V7389~LX*1~SV1*HC:99213*40*UN*1***1~DTP*472*D8*20061003~LX*2~SV1*HC:87070*15*UN*1***1~DTP*472*D8*20061003~LX*3~SV1*HC:99214*35*UN*1***2~DTP*472*D8*20061010~LX*4~SV1*HC:86663*10*UN*1***2~DTP*472*D8*20061010~SE*42*0021~
|
data/test/test_helper.rb
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
gem 'minitest'
|
3
3
|
require 'minitest/autorun'
|
4
4
|
|
5
|
-
|
5
|
+
require File.expand_path(File.join('..','lib','hippo'), File.dirname(__FILE__))
|
6
6
|
require 'pp'
|
7
7
|
|
8
8
|
module Hippo::Segments
|
@@ -58,7 +58,7 @@ module Hippo::TransactionSets
|
|
58
58
|
:minimum => 1,
|
59
59
|
:maximum => 1,
|
60
60
|
:position => 100,
|
61
|
-
:
|
61
|
+
:identified_by => {
|
62
62
|
'Field7' => 'Preset Field 7'
|
63
63
|
}
|
64
64
|
|
@@ -67,7 +67,7 @@ module Hippo::TransactionSets
|
|
67
67
|
:minimum => 1,
|
68
68
|
:maximum => 1,
|
69
69
|
:position => 50,
|
70
|
-
:
|
70
|
+
:identified_by => {
|
71
71
|
'TSS01' => 'Last Segment'
|
72
72
|
}
|
73
73
|
end
|
@@ -79,7 +79,7 @@ module Hippo::TransactionSets
|
|
79
79
|
:minimum => 1,
|
80
80
|
:maximum => 5,
|
81
81
|
:position => 50,
|
82
|
-
:
|
82
|
+
:identified_by => {
|
83
83
|
'TSS01' => 'Blah'
|
84
84
|
}
|
85
85
|
|
@@ -88,7 +88,7 @@ module Hippo::TransactionSets
|
|
88
88
|
:minimum => 1,
|
89
89
|
:maximum => 1,
|
90
90
|
:position => 100,
|
91
|
-
:
|
91
|
+
:identified_by => {
|
92
92
|
'Field7' => 'Preset Field 7'
|
93
93
|
}
|
94
94
|
|
@@ -97,7 +97,7 @@ module Hippo::TransactionSets
|
|
97
97
|
:minimum => 1,
|
98
98
|
:maximum => 1,
|
99
99
|
:position => 50,
|
100
|
-
:
|
100
|
+
:identified_by => {
|
101
101
|
'TSS01' => 'Last Segment'
|
102
102
|
}
|
103
103
|
|