REX12 0.1.3 → 0.1.4

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.
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: