REX12 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/lib/REX12/version.rb +1 -1
- data/lib/rex12/document.rb +62 -7
- data/lib/rex12/transaction.rb +20 -0
- data/lib/rex12.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74edc4cb8982b9426d2c97b67495eb2d0dda6b8f
|
4
|
+
data.tar.gz: dd6178322ddf0fe3642937607c595f55fac96aa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00f1778963481c83eeb234510718d4c6397fa22eeb1a0453186bf244b7c4efa0b4dbd84729e03b28c282dca12e2f841800ede8a72612df4a594bd1fae4f3a1bd
|
7
|
+
data.tar.gz: f6b4e7a3b970eecf9299b6060b9d6784241490e7260476e7783c1cc061b6fa1e099700404858c5f212d5b833d96c854e5ce0177bf59e93a949d2e7078e4f935e
|
data/.rspec
CHANGED
data/lib/REX12/version.rb
CHANGED
data/lib/rex12/document.rb
CHANGED
@@ -4,26 +4,29 @@
|
|
4
4
|
# but if you use the block form of the methods, then the subsequent ruby objects
|
5
5
|
# are created within the block loops so they can be garbage collected
|
6
6
|
module REX12; class Document
|
7
|
+
|
7
8
|
# Parse the EDI document from file
|
8
9
|
#
|
9
10
|
# @return (see #parse)
|
10
|
-
def self.read
|
11
|
+
def self.read path_or_io
|
11
12
|
if block_given?
|
12
|
-
parse(
|
13
|
+
parse(file_text(path_or_io)) {|s| yield s}
|
13
14
|
return nil
|
14
15
|
else
|
15
|
-
return parse(
|
16
|
+
return parse(file_text(path_or_io))
|
16
17
|
end
|
17
18
|
end
|
18
|
-
|
19
|
+
|
20
|
+
# Parse the EDI document from text or IO object
|
19
21
|
#
|
20
|
-
# @return [
|
22
|
+
# @return [Array<REX12::Segment>,nil] all segments or nil for block form
|
21
23
|
def self.parse text
|
22
24
|
validate_isa(text)
|
23
25
|
element_separator = text[3]
|
24
26
|
segment_terminator = determine_segment_terminator(text)
|
25
27
|
sub_element_separator = text[104]
|
26
28
|
r = []
|
29
|
+
|
27
30
|
text.split(segment_terminator).each_with_index do |seg_text,pos|
|
28
31
|
next if seg_text.length == 0
|
29
32
|
seg = REX12::Segment.new(seg_text,element_separator,sub_element_separator,pos)
|
@@ -33,6 +36,7 @@ module REX12; class Document
|
|
33
36
|
r << seg
|
34
37
|
end
|
35
38
|
end
|
39
|
+
|
36
40
|
if block_given?
|
37
41
|
return nil
|
38
42
|
else
|
@@ -40,7 +44,52 @@ module REX12; class Document
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
47
|
+
# Parses the EDI document from text or IO object, returning or yielding every transaction from the
|
48
|
+
# document.
|
49
|
+
#
|
50
|
+
# @return [Array<REX12::Transaction>,nil] all transactions or nil for block form
|
51
|
+
def self.each_transaction text
|
52
|
+
isa = nil
|
53
|
+
current_gs = nil
|
54
|
+
current_segments = []
|
55
|
+
transactions = []
|
56
|
+
|
57
|
+
parse(text) do |segment|
|
58
|
+
segment_type = segment.segment_type
|
59
|
+
case segment_type
|
60
|
+
when "ISA"
|
61
|
+
isa = segment
|
62
|
+
when "GS"
|
63
|
+
current_gs = segment
|
64
|
+
when "IEA", "GE"
|
65
|
+
# Do nothing, we don't care about the trailer segments
|
66
|
+
else
|
67
|
+
current_segments << segment
|
68
|
+
|
69
|
+
# If we found the transaction trailer, it means we can take all the current segments we have and process them
|
70
|
+
if segment_type == "SE"
|
71
|
+
transaction = REX12::Transaction.new(isa, current_gs, current_segments)
|
72
|
+
|
73
|
+
if block_given?
|
74
|
+
yield transaction
|
75
|
+
else
|
76
|
+
transactions << transaction
|
77
|
+
end
|
78
|
+
|
79
|
+
current_gs = nil
|
80
|
+
current_segments = []
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
block_given? ? nil : transactions
|
86
|
+
end
|
87
|
+
|
43
88
|
def self.determine_segment_terminator text
|
89
|
+
# Technically, allowing multi-character terminators is not valid EDI, but you
|
90
|
+
# see it happen ALL the time with EDI that's been hand editted from a client (especially on Windows).
|
91
|
+
# It's a valid enough use-case that we're accounting for it.
|
92
|
+
|
44
93
|
# no segement terminator, just CRLF
|
45
94
|
return "\r\n" if text[105..106]=="\r\n"
|
46
95
|
# no segement terminator, just CR or LF
|
@@ -50,15 +99,21 @@ module REX12; class Document
|
|
50
99
|
# segment terminator with CRLF
|
51
100
|
return text[105..107] if text[106..107]=="\r\n"
|
52
101
|
return text[105..106] if ["\r","\n"].include?(text[106]) && text[107]=="G"
|
53
|
-
raise REX12::ParseError, "
|
102
|
+
raise REX12::ParseError, "Invalid ISA / GS segements. Could not determine segment terminator."
|
54
103
|
end
|
55
104
|
private_class_method :determine_segment_terminator
|
56
105
|
|
57
106
|
def self.validate_isa text
|
58
107
|
raise REX12::ParseError, "EDI file must be at least 191 characters to include a valid envelope." unless text.length > 191
|
59
108
|
str = text[0..2]
|
60
|
-
raise REX12::ParseError, "First 3 characters must be ISA
|
109
|
+
raise REX12::ParseError, "First 3 characters must be ISA. They were '#{str}'." unless str=='ISA'
|
61
110
|
return
|
62
111
|
end
|
63
112
|
private_class_method :validate_isa
|
113
|
+
|
114
|
+
# Allow reading from an object that responds to #read or assume the given param is a string file path and read with IO
|
115
|
+
def self.file_text path_or_io
|
116
|
+
path_or_io.respond_to?(:read) ? path_or_io.read : IO.read(path_or_io)
|
117
|
+
end
|
118
|
+
private_class_method :file_text
|
64
119
|
end; end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Represents a collection of all EDI elements between the ST/SE segments of a single EDI document transaction.
|
2
|
+
# An EDI document may have multiple transactions in it.
|
3
|
+
module REX12; class Transaction
|
4
|
+
|
5
|
+
# @return REX12::Segment - The ISA segment from the EDI document this transaction belongs to
|
6
|
+
attr_reader :isa_segment
|
7
|
+
|
8
|
+
# @return REX12::Segment - The GS segment from the EDI document this transaction belongs to
|
9
|
+
attr_reader :gs_segment
|
10
|
+
|
11
|
+
# @return Array<REX12::Segment> - All the segments that comprise this EDI Transaction
|
12
|
+
attr_reader :segments
|
13
|
+
|
14
|
+
def initialize(isa_segment, gs_segment, segments)
|
15
|
+
@isa_segment = isa_segment
|
16
|
+
@gs_segment = gs_segment
|
17
|
+
@segments = segments
|
18
|
+
end
|
19
|
+
|
20
|
+
end; end
|
data/lib/rex12.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: REX12
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Glick
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/rex12/element.rb
|
90
90
|
- lib/rex12/parse_error.rb
|
91
91
|
- lib/rex12/segment.rb
|
92
|
+
- lib/rex12/transaction.rb
|
92
93
|
- rex12.gemspec
|
93
94
|
homepage: https://github.com/Vandegrift/rex12
|
94
95
|
licenses:
|