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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6d86bbf6174fa893327c071e804c0cef6c302d3
4
- data.tar.gz: ded8c3aee01aa03d18398351b16730bbf767bf77
3
+ metadata.gz: 74edc4cb8982b9426d2c97b67495eb2d0dda6b8f
4
+ data.tar.gz: dd6178322ddf0fe3642937607c595f55fac96aa7
5
5
  SHA512:
6
- metadata.gz: 72ac15616a53573b24e72a3ed15cd6a799ea732a8735b24e94228eb7dc408b9d3740a967f8c4e62b5791be77f14a9f15bbdcb5819e2d2cc082ad3d2e59c79b10
7
- data.tar.gz: a735784df455af350effe390ee843fd9c3639dd2ba5625a1faea88fb90ab9ff4dc4b849e565f158bc5faa46862ee4db6c013b8b73c387b59044a6595a66b8965
6
+ metadata.gz: 00f1778963481c83eeb234510718d4c6397fa22eeb1a0453186bf244b7c4efa0b4dbd84729e03b28c282dca12e2f841800ede8a72612df4a594bd1fae4f3a1bd
7
+ data.tar.gz: f6b4e7a3b970eecf9299b6060b9d6784241490e7260476e7783c1cc061b6fa1e099700404858c5f212d5b833d96c854e5ce0177bf59e93a949d2e7078e4f935e
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
+ --require spec_helper
data/lib/REX12/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module REX12
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -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 path
11
+ def self.read path_or_io
11
12
  if block_given?
12
- parse(IO.read(path)) {|s| yield s}
13
+ parse(file_text(path_or_io)) {|s| yield s}
13
14
  return nil
14
15
  else
15
- return parse(IO.read(path))
16
+ return parse(file_text(path_or_io))
16
17
  end
17
18
  end
18
- # Parse the EDI document from text
19
+
20
+ # Parse the EDI document from text or IO object
19
21
  #
20
- # @return [Enumerator<REX12::Segment>,nil] all segments or nil for block form
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, "Cannot determine segment terminator, invalid ISA / GS."
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, they were #{str}" unless str=='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
@@ -3,6 +3,7 @@ require "rex12/parse_error"
3
3
  require "rex12/element"
4
4
  require "rex12/segment"
5
5
  require "rex12/document"
6
+ require 'rex12/transaction'
6
7
 
7
8
  module REX12
8
9
  # Your code goes here...
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.3
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: 2016-12-19 00:00:00.000000000 Z
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: