ach 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +1 -2
- data/lib/ach/ach_file.rb +1 -1
- data/lib/ach/batch.rb +7 -12
- data/lib/ach/records/batch_control.rb +1 -3
- data/lib/ach/records/batch_header.rb +1 -3
- data/lib/ach/version.rb +1 -1
- metadata +28 -41
- data/examples/ach/ach_file_example.rb +0 -10
- data/examples/ach/batch_example.rb +0 -129
- data/examples/ach/field_identifiers_example.rb +0 -47
- data/examples/ach/fixtures/return_noc.txt +0 -20
- data/examples/ach/parse_example.rb +0 -70
- data/examples/ach/records/batch_control_example.rb +0 -37
- data/examples/ach/records/batch_header_example.rb +0 -29
- data/examples/ach/records/ctx_entry_detail_example.rb +0 -70
- data/examples/ach/records/ctx_entry_detail_test.rb +0 -78
- data/examples/ach/records/file_header_example.rb +0 -39
- data/examples/ach/records/nines_example.rb +0 -13
- data/examples/ach/records/shared/batch_summaries.rb +0 -43
- data/examples/example_helper.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MTg0YjlhNzMwY2RkODJlY2VlYjY3MjU2NmRmZmQ0ZDMyNTFiOGEzNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTg5OTQ1MjYzNDM4YjJjNjhkMTYzZGVkZmI2NGNjNGJhMzNhNWI5YQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTM0ZDNmMWM2ZjBkMDdiNmUxNWVmOWJhMGE2OGYyNmM1ZmRjOTRiOWJiM2Ez
|
10
|
+
NDMwNzA4YjEwYzI1MTg3MWYwZmY2OWU2YmY4MGQwMDcwZmYyMmI1ZmZmNjg5
|
11
|
+
ZDVmYTE4NTRmMDU2YmJmOTcwNTY4ZWM2YjU4ZTAyMGExOGYxODI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDAyNmExZjE2NjFkY2Q1ZjJlZmUwZGI0NjE5OWYwNzJkNWQxNjI1N2MxZTVm
|
14
|
+
NzJhYTgzN2VjOGViMDFlMmM0MDgxZGM1ODk5YmFhNmI0MDM2NzBkY2JiNjQy
|
15
|
+
ZWIzOGM3ZDQ4OTkxZjZjMTY1NjFiYmRjNWY5ODIzMGE1YjkxMWM=
|
data/README.md
CHANGED
@@ -31,8 +31,7 @@ fh.immediate_origin_name = "BANK NAME"
|
|
31
31
|
batch = ACH::Batch.new
|
32
32
|
bh = batch.header
|
33
33
|
bh.company_name = "Company Name"
|
34
|
-
bh.
|
35
|
-
bh.company_identification = "123456789"
|
34
|
+
bh.company_identification = "123456789" # Use 10 characters if you're not using an EIN
|
36
35
|
bh.standard_entry_class_code = 'PPD'
|
37
36
|
bh.company_entry_description = "DESCRIPTION"
|
38
37
|
bh.company_descriptive_date = Date.today
|
data/lib/ach/ach_file.rb
CHANGED
@@ -89,7 +89,7 @@ module ACH
|
|
89
89
|
batch = ACH::Batch.new
|
90
90
|
bh = batch.header
|
91
91
|
bh.company_name = line[4..19].strip
|
92
|
-
bh.company_identification = line[
|
92
|
+
bh.company_identification = line[40..49].strip.gsub(/\A1/, '')
|
93
93
|
bh.standard_entry_class_code = line[50..52].strip
|
94
94
|
bh.company_entry_description = line[53..62].strip
|
95
95
|
bh.company_descriptive_date = Date.parse(line[63..68]) rescue nil # this can be various formats
|
data/lib/ach/batch.rb
CHANGED
@@ -4,14 +4,14 @@ module ACH
|
|
4
4
|
attr_reader :addendas
|
5
5
|
attr_reader :header
|
6
6
|
attr_reader :control
|
7
|
-
|
7
|
+
|
8
8
|
def initialize
|
9
9
|
@entries = []
|
10
10
|
@addendas = []
|
11
11
|
@header = Records::BatchHeader.new
|
12
12
|
@control = Records::BatchControl.new
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def to_ach
|
16
16
|
@control.entry_count = @entries.length
|
17
17
|
@control.debit_total = 0
|
@@ -19,7 +19,7 @@ module ACH
|
|
19
19
|
@control.entry_hash = 0
|
20
20
|
has_debits = false
|
21
21
|
has_credits = false
|
22
|
-
|
22
|
+
|
23
23
|
@entries.each do |e|
|
24
24
|
if e.debit?
|
25
25
|
@control.debit_total += e.amount
|
@@ -31,7 +31,7 @@ module ACH
|
|
31
31
|
@control.entry_hash +=
|
32
32
|
(e.routing_number.to_i / 10) # Last digit is not part of Receiving DFI
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
# Set service class codes if needed
|
36
36
|
if @header.service_class_code.nil?
|
37
37
|
if has_debits && has_credits
|
@@ -42,20 +42,15 @@ module ACH
|
|
42
42
|
@header.service_class_code = 220
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
if @control.service_class_code.nil?
|
47
|
-
@control.service_class_code = @header.service_class_code
|
48
|
-
end
|
49
|
-
|
50
|
-
if ! @header.company_identification_code_designator.nil?
|
51
|
-
@control.company_identification_code_designator =
|
52
|
-
@header.company_identification_code_designator
|
47
|
+
@control.service_class_code = @header.service_class_code
|
53
48
|
end
|
54
49
|
|
55
50
|
@control.company_identification = @header.company_identification
|
56
51
|
@control.originating_dfi_identification = @header.originating_dfi_identification
|
57
52
|
@control.batch_number = @header.batch_number
|
58
|
-
|
53
|
+
|
59
54
|
[@header] + @entries + @addendas + [@control]
|
60
55
|
end
|
61
56
|
end
|
@@ -13,10 +13,8 @@ module ACH::Records
|
|
13
13
|
field :entry_hash, Integer, lambda { |f| sprintf('%010d', f % (10 ** 10))}
|
14
14
|
field :debit_total, Integer, lambda { |f| sprintf('%012d', f)}
|
15
15
|
field :credit_total, Integer, lambda { |f| sprintf('%012d', f)}
|
16
|
-
field :company_identification_code_designator, String, nil, '1',
|
17
|
-
/\A[0-9 ]\z/
|
18
16
|
field :company_identification, String,
|
19
|
-
|
17
|
+
lambda { |f| f.length == 10 ? f : "1#{f}" }, nil, /\A\d{9,10}\z/
|
20
18
|
|
21
19
|
field :message_authentication_code, String,
|
22
20
|
lambda { |f| left_justify(f, 19)}, ''
|
@@ -11,10 +11,8 @@ module ACH::Records
|
|
11
11
|
field :company_name, String, lambda { |f| left_justify(f, 16)}
|
12
12
|
field :company_discretionary_data, String,
|
13
13
|
lambda { |f| left_justify(f, 20)}, ''
|
14
|
-
field :company_identification_code_designator, String, nil, '1',
|
15
|
-
/\A[0-9 ]\z/
|
16
14
|
field :company_identification, String,
|
17
|
-
|
15
|
+
lambda { |f| f.length == 10 ? f : "1#{f}" }, nil, /\A[a-zA-Z0-9 ]{9,10}\z/
|
18
16
|
# TODO This should be used to determine whether other records are valid for
|
19
17
|
# this code. Should there be a Class for each code?
|
20
18
|
# The default of PPD is purely for my benefit (Jared Morgan)
|
data/lib/ach/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ach
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jared Morgan
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-03-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rake
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - ! '>='
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - ! '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.0'
|
28
42
|
description: ach is a Ruby helper for building and parsing ACH files. In particular,
|
29
43
|
it helps with field order and alignment, and adds padding lines to end of file.
|
30
44
|
email: jmorgan@morgancreative.net
|
@@ -33,34 +47,21 @@ extensions: []
|
|
33
47
|
extra_rdoc_files:
|
34
48
|
- README.md
|
35
49
|
files:
|
50
|
+
- lib/ach.rb
|
51
|
+
- lib/ach/field_identifiers.rb
|
36
52
|
- lib/ach/batch.rb
|
37
|
-
- lib/ach/
|
38
|
-
- lib/ach/records/addendum.rb
|
39
|
-
- lib/ach/records/file_control.rb
|
40
|
-
- lib/ach/records/batch_header.rb
|
41
|
-
- lib/ach/records/record.rb
|
42
|
-
- lib/ach/records/entry_detail.rb
|
53
|
+
- lib/ach/version.rb
|
43
54
|
- lib/ach/records/file_header.rb
|
55
|
+
- lib/ach/records/file_control.rb
|
44
56
|
- lib/ach/records/batch_control.rb
|
57
|
+
- lib/ach/records/entry_detail.rb
|
45
58
|
- lib/ach/records/nines.rb
|
46
|
-
- lib/ach/
|
47
|
-
- lib/ach/
|
48
|
-
- lib/ach.rb
|
59
|
+
- lib/ach/records/addendum.rb
|
60
|
+
- lib/ach/records/record.rb
|
61
|
+
- lib/ach/records/batch_header.rb
|
62
|
+
- lib/ach/ach_file.rb
|
49
63
|
- MIT-LICENSE
|
50
64
|
- README.md
|
51
|
-
- examples/ach/parse_example.rb
|
52
|
-
- examples/ach/records/shared/batch_summaries.rb
|
53
|
-
- examples/ach/records/ctx_entry_detail_test.rb
|
54
|
-
- examples/ach/records/batch_control_example.rb
|
55
|
-
- examples/ach/records/ctx_entry_detail_example.rb
|
56
|
-
- examples/ach/records/batch_header_example.rb
|
57
|
-
- examples/ach/records/nines_example.rb
|
58
|
-
- examples/ach/records/file_header_example.rb
|
59
|
-
- examples/ach/field_identifiers_example.rb
|
60
|
-
- examples/ach/ach_file_example.rb
|
61
|
-
- examples/ach/batch_example.rb
|
62
|
-
- examples/ach/fixtures/return_noc.txt
|
63
|
-
- examples/example_helper.rb
|
64
65
|
homepage: https://github.com/jm81/ach
|
65
66
|
licenses: []
|
66
67
|
metadata: {}
|
@@ -80,22 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
81
|
version: '0'
|
81
82
|
requirements: []
|
82
83
|
rubyforge_project:
|
83
|
-
rubygems_version: 2.
|
84
|
+
rubygems_version: 2.1.10
|
84
85
|
signing_key:
|
85
86
|
specification_version: 4
|
86
87
|
summary: Helper for building ACH files
|
87
|
-
test_files:
|
88
|
-
- examples/ach/parse_example.rb
|
89
|
-
- examples/ach/records/shared/batch_summaries.rb
|
90
|
-
- examples/ach/records/ctx_entry_detail_test.rb
|
91
|
-
- examples/ach/records/batch_control_example.rb
|
92
|
-
- examples/ach/records/ctx_entry_detail_example.rb
|
93
|
-
- examples/ach/records/batch_header_example.rb
|
94
|
-
- examples/ach/records/nines_example.rb
|
95
|
-
- examples/ach/records/file_header_example.rb
|
96
|
-
- examples/ach/field_identifiers_example.rb
|
97
|
-
- examples/ach/ach_file_example.rb
|
98
|
-
- examples/ach/batch_example.rb
|
99
|
-
- examples/ach/fixtures/return_noc.txt
|
100
|
-
- examples/example_helper.rb
|
101
|
-
has_rdoc:
|
88
|
+
test_files: []
|
@@ -1,129 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'example_helper'
|
3
|
-
|
4
|
-
describe ACH::Batch do
|
5
|
-
before(:each) do
|
6
|
-
@credit = ACH::EntryDetail.new
|
7
|
-
@credit.transaction_code = ACH::CHECKING_CREDIT
|
8
|
-
@credit.routing_number = "000000000"
|
9
|
-
@credit.account_number = "00000000000"
|
10
|
-
@credit.amount = 100 # In cents
|
11
|
-
@credit.individual_id_number = "Employee Name"
|
12
|
-
@credit.individual_name = "Employee Name"
|
13
|
-
@credit.originating_dfi_identification = '00000000'
|
14
|
-
|
15
|
-
@debit = @credit.dup
|
16
|
-
@debit.transaction_code = ACH::CHECKING_DEBIT
|
17
|
-
end
|
18
|
-
|
19
|
-
def new_batch
|
20
|
-
batch = ACH::Batch.new
|
21
|
-
bh = batch.header
|
22
|
-
bh.company_name = "Company Name"
|
23
|
-
bh.company_identification = "123456789"
|
24
|
-
bh.standard_entry_class_code = 'PPD'
|
25
|
-
bh.company_entry_description = "DESCRIPTION"
|
26
|
-
bh.company_descriptive_date = Date.today
|
27
|
-
bh.effective_entry_date = (Date.today + 1)
|
28
|
-
bh.originating_dfi_identification = "00000000"
|
29
|
-
return batch
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#to_ach' do
|
33
|
-
it 'should determine BatchHeader#service_class_code if not set' do
|
34
|
-
debits = new_batch
|
35
|
-
debits.entries << @debit << @debit
|
36
|
-
debits.header.service_class_code.should be_nil
|
37
|
-
debits.to_ach
|
38
|
-
debits.header.service_class_code.should == 225
|
39
|
-
|
40
|
-
credits = new_batch
|
41
|
-
credits.entries << @credit << @credit
|
42
|
-
credits.header.service_class_code.should be_nil
|
43
|
-
credits.to_ach
|
44
|
-
credits.header.service_class_code.should == 220
|
45
|
-
|
46
|
-
both = new_batch
|
47
|
-
both.entries << @credit << @debit
|
48
|
-
both.header.service_class_code.should be_nil
|
49
|
-
both.to_ach
|
50
|
-
both.header.service_class_code.should == 200
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should not override BatchHeader#service_class_code if already set' do
|
54
|
-
debits = new_batch
|
55
|
-
debits.header.service_class_code = 200
|
56
|
-
debits.entries << @debit << @debit
|
57
|
-
debits.to_ach
|
58
|
-
debits.header.service_class_code.should == 200
|
59
|
-
|
60
|
-
debits = new_batch
|
61
|
-
debits.header.service_class_code = '220'
|
62
|
-
debits.entries << @credit << @credit
|
63
|
-
debits.to_ach
|
64
|
-
debits.header.service_class_code.should == '220'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should set BatchControl#service_class_code from BatchHeader if not set' do
|
68
|
-
batch = new_batch
|
69
|
-
batch.header.service_class_code = 200
|
70
|
-
batch.control.service_class_code.should be_nil
|
71
|
-
batch.to_ach
|
72
|
-
batch.control.service_class_code.should == 200
|
73
|
-
|
74
|
-
batch = new_batch
|
75
|
-
batch.header.service_class_code = '225'
|
76
|
-
batch.control.service_class_code.should be_nil
|
77
|
-
batch.to_ach
|
78
|
-
batch.control.service_class_code.should == '225'
|
79
|
-
|
80
|
-
debits = new_batch
|
81
|
-
debits.entries << @debit << @debit
|
82
|
-
debits.header.service_class_code.should be_nil
|
83
|
-
debits.control.service_class_code.should be_nil
|
84
|
-
debits.to_ach
|
85
|
-
debits.header.service_class_code.should == 225
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'should set BatchControl#company_identification_code_designator from BatchHeader' do
|
89
|
-
batch = new_batch
|
90
|
-
batch.header.company_identification_code_designator = "3"
|
91
|
-
batch.control.company_identification_code_designator.should be_nil # default values are only set when calling to_ach
|
92
|
-
batch.to_ach
|
93
|
-
batch.control.company_identification_code_designator.should == "3"
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'should set BatchControl#company_identification from BatchHeader' do
|
97
|
-
batch = new_batch
|
98
|
-
batch.control.company_identification.should be_nil
|
99
|
-
batch.to_ach
|
100
|
-
batch.control.company_identification.should == "123456789"
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'should set BatchControl#originating_dfi_identification from BatchHeader' do
|
104
|
-
batch = new_batch
|
105
|
-
batch.control.originating_dfi_identification.should be_nil
|
106
|
-
batch.to_ach
|
107
|
-
batch.control.originating_dfi_identification.should == "00000000"
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'should not override BatchHeader#service_class_code if already set' do
|
111
|
-
# Granted that I can't imagine this every being used...
|
112
|
-
batch = new_batch
|
113
|
-
batch.header.service_class_code = 220
|
114
|
-
batch.control.service_class_code = 200
|
115
|
-
batch.to_ach
|
116
|
-
batch.control.service_class_code.should == 200
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'should truncate fields that exceed the length in left_justify' do
|
120
|
-
@credit.individual_name = "Employee Name That Is Much Too Long"
|
121
|
-
@credit.individual_name_to_ach.should == "Employee Name That Is "
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'should strip non ascii characters' do
|
125
|
-
@credit.individual_name = "Jacob Møller"
|
126
|
-
@credit.individual_name_to_ach.should == "Jacob Mller "
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
|
3
|
-
describe ACH::FieldIdentifiers do
|
4
|
-
describe 'setter' do
|
5
|
-
|
6
|
-
before(:each) do
|
7
|
-
@klass = Class.new(ACH::Records::Record)
|
8
|
-
@klass.instance_variable_set(:@fields, [])
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should validate against a Regexp' do
|
12
|
-
@klass.field(:sample, String, nil, nil, /\A\w{5}\Z/)
|
13
|
-
record = @klass.new
|
14
|
-
lambda { record.sample = 'abcd' }.should raise_error(RuntimeError)
|
15
|
-
record.sample.should be_nil
|
16
|
-
lambda { record.sample = 'abcdef' }.should raise_error(RuntimeError)
|
17
|
-
record.sample.should be_nil
|
18
|
-
lambda { record.sample = 'abcde' }.should_not raise_error
|
19
|
-
record.sample.should == 'abcde'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should validate against a Proc' do
|
23
|
-
block = Proc.new do |val|
|
24
|
-
[1, 2, 500].include?(val)
|
25
|
-
end
|
26
|
-
|
27
|
-
@klass.field(:sample, String, nil, nil, block)
|
28
|
-
record = @klass.new
|
29
|
-
lambda { record.sample = 5 }.should raise_error(RuntimeError)
|
30
|
-
record.sample.should be_nil
|
31
|
-
lambda { record.sample = 501 }.should raise_error(RuntimeError)
|
32
|
-
record.sample.should be_nil
|
33
|
-
lambda { record.sample = 1 }.should_not raise_error
|
34
|
-
record.sample.should == 1
|
35
|
-
lambda { record.sample = 500 }.should_not raise_error
|
36
|
-
record.sample.should == 500
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'should set instance variable' do
|
40
|
-
@klass.field(:sample, String)
|
41
|
-
record = @klass.new
|
42
|
-
record.sample = 'abcde'
|
43
|
-
record.instance_variable_get(:@sample).should == 'abcde'
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
101 191001234 9922222261210151518A094101Certification Bank-SiliCERTIFICATION BANK-SILIRETURNS
|
2
|
-
5200COMPANY INC DISC DATA 1412345678CORDESCRIPT 1210151210150001992222220000001
|
3
|
-
6211211403993300911569 0000000000A38LTNY2 NAME ONE 1121140390280747
|
4
|
-
798C05992222220280489 1211403932 121140390280747
|
5
|
-
820000000200121140390000000000000000000000001412345678 992222220000001
|
6
|
-
5200COMPANY INC DISC DATA 1412345678PPDDESCRIPT 1210151210150001992222220000002
|
7
|
-
6261211403993300911569 0000002536GKGQT9VK NAME TWO 1121140390280738
|
8
|
-
799R07992222220280393 12114039INVALID 121140390280738
|
9
|
-
820000000200121140390000000025360000000000001412345678 992222220000002
|
10
|
-
5200COMPANY INC DISC DATA 1412345678PPDDESCRIPT 1210150001992222220000003
|
11
|
-
6261211403993300911569 0000002417KYU341VP NAME THREE 1121140390280729
|
12
|
-
799R03992222220280389 12114039 121140390280729
|
13
|
-
820000000200121140390000000024170000000000001412345678 992222220000003
|
14
|
-
9000003000002000000060036342117000000004953000000000000
|
15
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
16
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
17
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
18
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
19
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
20
|
-
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
require 'date'
|
3
|
-
|
4
|
-
describe "Parse" do
|
5
|
-
describe 'Returns and NOC' do
|
6
|
-
before(:each) do
|
7
|
-
@data = File.read('examples/ach/fixtures/return_noc.txt')
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should produce the same number of entries as the original ACH file' do
|
11
|
-
entries = ACH::ACHFile.new(@data).batches.reduce([]) { |entries, batch| entries << batch.entries }
|
12
|
-
|
13
|
-
entries.flatten.size.should == 3
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should parse return/notification of change file" do
|
17
|
-
ach = ACH::ACHFile.new(@data)
|
18
|
-
fh = ach.header
|
19
|
-
fh.immediate_destination.should == "191001234"
|
20
|
-
fh.immediate_origin.should == "992222226"
|
21
|
-
fh.transmission_datetime.should == Time.utc(2012, 10, 15, 15, 18)
|
22
|
-
fh.immediate_destination_name.should == "Certification Bank-Sili"
|
23
|
-
fh.immediate_origin_name.should == "CERTIFICATION BANK-SILI"
|
24
|
-
|
25
|
-
ach.batches.size.should == 3
|
26
|
-
|
27
|
-
batch = ach.batches[0]
|
28
|
-
batch.entries.size.should == 1
|
29
|
-
bh = batch.header
|
30
|
-
bh.company_name.should == "COMPANY INC"
|
31
|
-
bh.company_identification.should == "412345678"
|
32
|
-
bh.standard_entry_class_code.should == 'COR'
|
33
|
-
bh.company_entry_description.should == "DESCRIPT"
|
34
|
-
bh.company_descriptive_date.should == Date.parse('121015')
|
35
|
-
bh.effective_entry_date.should == Date.parse('121015')
|
36
|
-
bh.originating_dfi_identification.should == "99222222"
|
37
|
-
|
38
|
-
ed = batch.entries[0]
|
39
|
-
ed.transaction_code.should == "21"
|
40
|
-
ed.routing_number.should == "121140399"
|
41
|
-
ed.account_number.should == "3300911569"
|
42
|
-
ed.amount.should == 0 # In cents
|
43
|
-
ed.individual_id_number.should == "A38LTNY2"
|
44
|
-
ed.individual_name.should == "NAME ONE"
|
45
|
-
|
46
|
-
ed.addenda.size.should == 1
|
47
|
-
ad = ed.addenda[0]
|
48
|
-
ad.type_code.should == '98'
|
49
|
-
ad.reason_code.should == 'C05'
|
50
|
-
ad.original_entry_trace_number.should == '992222220280489'
|
51
|
-
ad.corrected_data.should == '32'
|
52
|
-
ad.sequence_number.should == 4039
|
53
|
-
|
54
|
-
batch = ach.batches[1]
|
55
|
-
batch.entries.size.should == 1
|
56
|
-
bh = batch.header
|
57
|
-
bh.standard_entry_class_code.should == 'PPD'
|
58
|
-
ed = batch.entries[0]
|
59
|
-
ed.amount.should == 2536
|
60
|
-
|
61
|
-
ed.addenda.size.should == 1
|
62
|
-
ad = ed.addenda[0]
|
63
|
-
ad.type_code.should == '99'
|
64
|
-
ad.reason_code.should == 'R07'
|
65
|
-
ad.original_entry_trace_number.should == '992222220280393'
|
66
|
-
ad.addenda_information.should == 'INVALID'
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
require 'ach/records/shared/batch_summaries'
|
3
|
-
|
4
|
-
describe ACH::Records::BatchControl do
|
5
|
-
before(:each) do
|
6
|
-
@record = ACH::Records::BatchControl.new
|
7
|
-
@record.entry_count = 1
|
8
|
-
@record.entry_hash = 2
|
9
|
-
@record.debit_total = 3
|
10
|
-
@record.credit_total = 4
|
11
|
-
@record.company_identification = '123456789'
|
12
|
-
@record.message_authentication_code = '22345678'
|
13
|
-
@record.originating_dfi_identification = '32345678'
|
14
|
-
@record.batch_number = 5
|
15
|
-
end
|
16
|
-
|
17
|
-
self.instance_eval(&SharedExamples.batch_summaries)
|
18
|
-
|
19
|
-
describe '#to_ach' do
|
20
|
-
it 'should generate record string' do
|
21
|
-
exp = [
|
22
|
-
'8',
|
23
|
-
'200',
|
24
|
-
'000001',
|
25
|
-
'0000000002',
|
26
|
-
'000000000003',
|
27
|
-
'000000000004',
|
28
|
-
'1123456789',
|
29
|
-
'22345678 ',
|
30
|
-
' ',
|
31
|
-
'32345678',
|
32
|
-
'0000005'
|
33
|
-
]
|
34
|
-
@record.to_ach.should == exp.join('')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
require 'ach/records/shared/batch_summaries'
|
3
|
-
|
4
|
-
describe ACH::Records::BatchHeader do
|
5
|
-
before(:each) do
|
6
|
-
@record = ACH::Records::BatchHeader.new
|
7
|
-
end
|
8
|
-
|
9
|
-
self.instance_eval(&SharedExamples.batch_summaries)
|
10
|
-
|
11
|
-
describe '#standard_entry_class_code' do
|
12
|
-
it 'should default to PPD' do
|
13
|
-
@record.standard_entry_class_code_to_ach.should == 'PPD'
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should be capitalized' do
|
17
|
-
@record.standard_entry_class_code = 'ccd'
|
18
|
-
@record.standard_entry_class_code_to_ach.should == 'CCD'
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should be exactly three characters' do
|
22
|
-
lambda { @record.standard_entry_class_code = 'CCDA' }.should raise_error(RuntimeError)
|
23
|
-
lambda { @record.standard_entry_class_code = 'CC' }.should raise_error(RuntimeError)
|
24
|
-
lambda { @record.standard_entry_class_code = 'CCD' }.should_not raise_error(RuntimeError)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should be limited to real codes'
|
28
|
-
end
|
29
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
|
3
|
-
describe ACH::Records::CtxEntryDetail do
|
4
|
-
before(:each) do
|
5
|
-
@entry = ACH::CtxEntryDetail.new
|
6
|
-
@entry.transaction_code = ACH::CHECKING_DEBIT
|
7
|
-
@entry.routing_number = '023456789'
|
8
|
-
@entry.account_number = '123456789'
|
9
|
-
@entry.amount = 10000
|
10
|
-
@entry.individual_name = "Bob Roberts"
|
11
|
-
@entry.originating_dfi_identification = '02345678'
|
12
|
-
@entry.individual_id_number = '1'
|
13
|
-
@entry.trace_number = 1
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#addenda_records?' do
|
17
|
-
it 'should do report if it contains addena records' do
|
18
|
-
@entry.addenda_records?.should == false
|
19
|
-
|
20
|
-
@entry.addenda << ACH::Addendum.new
|
21
|
-
@entry.addenda_records?.should == true
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should print addenda records as part of to_ach' do
|
25
|
-
addendum_1 = ACH::Addendum.new
|
26
|
-
addendum_1.payment_data = ""
|
27
|
-
addendum_1.sequence_number = "1"
|
28
|
-
@entry.addenda << addendum_1
|
29
|
-
@entry.addenda.size.should == 1
|
30
|
-
|
31
|
-
addendum_2 = ACH::Addendum.new
|
32
|
-
addendum_2.payment_data = ""
|
33
|
-
addendum_2.sequence_number = "2"
|
34
|
-
@entry.addenda << addendum_2
|
35
|
-
@entry.addenda.size.should == 2
|
36
|
-
|
37
|
-
# 705 is the beginning of an addendum record
|
38
|
-
ach_string = @entry.to_ach
|
39
|
-
ach_string.scan("705").count.should == 2
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should print fields different from a CCD/PPD record' do
|
43
|
-
ach_string = @entry.to_ach
|
44
|
-
ach_string.slice(39, 15).should == "1 "
|
45
|
-
ach_string.slice(58, 16).should == "#{@entry.individual_name.upcase} "
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'should set addenda record indicators, count, and trace numbers' do
|
49
|
-
#Set a trace number we expect to find in the addendum record
|
50
|
-
expected_trace_number = "474"
|
51
|
-
@entry.trace_number = expected_trace_number
|
52
|
-
|
53
|
-
addendum_1 = ACH::Addendum.new
|
54
|
-
addendum_1.payment_data = ""
|
55
|
-
addendum_1.sequence_number = "1"
|
56
|
-
@entry.addenda << addendum_1
|
57
|
-
|
58
|
-
|
59
|
-
ach_string = @entry.to_ach
|
60
|
-
# Test addenda record indicator
|
61
|
-
ach_string.slice(78, 1).should == "1"
|
62
|
-
# Test number of addenda records
|
63
|
-
ach_string.slice(54, 4).should == "0001"
|
64
|
-
# Test for trace number in each addendum record
|
65
|
-
ach_string.scan(expected_trace_number).count.should == 2
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'ach'
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
class CtxEntryDetailTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
@entry = ACH::CtxEntryDetail.new
|
9
|
-
@entry.transaction_code = ACH::CHECKING_DEBIT
|
10
|
-
@entry.routing_number = '023456789'
|
11
|
-
@entry.account_number = '123456789'
|
12
|
-
@entry.amount = 10000
|
13
|
-
@entry.individual_name = "Bob Roberts"
|
14
|
-
@entry.originating_dfi_identification = '02345678'
|
15
|
-
@entry.individual_id_number = '1'
|
16
|
-
@entry.trace_number = 1
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_addenda_records?
|
20
|
-
@entry = ACH::CtxEntryDetail.new
|
21
|
-
assert @entry.addenda_records? == false
|
22
|
-
|
23
|
-
@entry.addenda << ACH::Addendum.new
|
24
|
-
assert @entry.addenda_records? == true
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_ctx_entry_prints_addenda
|
29
|
-
addendum_1 = ACH::Addendum.new
|
30
|
-
addendum_1.payment_data = ""
|
31
|
-
addendum_1.sequence_number = "1"
|
32
|
-
@entry.addenda << addendum_1
|
33
|
-
assert @entry.addenda.size == 1
|
34
|
-
|
35
|
-
addendum_2 = ACH::Addendum.new
|
36
|
-
addendum_2.payment_data = ""
|
37
|
-
addendum_2.sequence_number = "2"
|
38
|
-
@entry.addenda << addendum_2
|
39
|
-
assert @entry.addenda.size == 2
|
40
|
-
|
41
|
-
# 705 is the beginning of an addendum record
|
42
|
-
ach_string = @entry.to_ach
|
43
|
-
assert ach_string.scan("705").count == 2
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_ctx_correct_fields
|
48
|
-
ach_string = @entry.to_ach
|
49
|
-
assert ach_string.slice(39, 15) == "1 "
|
50
|
-
assert ach_string.slice(58, 16) == "#{@entry.individual_name.upcase} "
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_to_ach_set_addendum_count_and_entry_detail_sequence_number
|
54
|
-
#Set a trace number we expect to find in the addendum record
|
55
|
-
expected_trace_number = "474"
|
56
|
-
@entry.trace_number = expected_trace_number
|
57
|
-
|
58
|
-
|
59
|
-
addendum_1 = ACH::Addendum.new
|
60
|
-
addendum_1.payment_data = ""
|
61
|
-
addendum_1.sequence_number = "1"
|
62
|
-
@entry.addenda << addendum_1
|
63
|
-
|
64
|
-
|
65
|
-
ach_string = @entry.to_ach
|
66
|
-
# Test addenda record indicator
|
67
|
-
assert ach_string.slice(78, 1) == "1"
|
68
|
-
# Test number of addenda records
|
69
|
-
assert ach_string.slice(54, 4) == "0001"
|
70
|
-
# Test for trace number in each addendum record
|
71
|
-
assert ach_string.scan(expected_trace_number).count == 2
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
|
3
|
-
describe ACH::Records::FileHeader do
|
4
|
-
before(:each) do
|
5
|
-
@header = ACH::Records::FileHeader.new
|
6
|
-
@header.immediate_destination_name = 'destination'
|
7
|
-
@header.immediate_destination = '123456789'
|
8
|
-
@header.immediate_origin_name = 'origin'
|
9
|
-
@header.immediate_origin = '123456789'
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#to_ach' do
|
13
|
-
it 'has 94 characters' do
|
14
|
-
@header.to_ach.should have(94).characters
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '#immediate_origin_to_ach' do
|
19
|
-
it 'adds a leading space when only 9 digits' do
|
20
|
-
@header.immediate_origin_to_ach.should == ' 123456789'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'does not add a leading space when 10 digits' do
|
24
|
-
@header.immediate_origin = '1234567890'
|
25
|
-
@header.immediate_origin_to_ach.should == '1234567890'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe '#immediate_origin_to_ach' do
|
30
|
-
it 'adds a leading space when only 9 digits' do
|
31
|
-
@header.immediate_destination_to_ach.should == ' 123456789'
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'does not add a leading space when 10 digits' do
|
35
|
-
@header.immediate_destination = '1234567890'
|
36
|
-
@header.immediate_destination_to_ach.should == '1234567890'
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'example_helper'
|
2
|
-
|
3
|
-
describe ACH::Records::Nines do
|
4
|
-
before(:each) do
|
5
|
-
@nines = ACH::Records::Nines.new
|
6
|
-
end
|
7
|
-
|
8
|
-
describe '#to_ach' do
|
9
|
-
it 'should generate 94 copies of the digit "9"' do
|
10
|
-
@nines.to_ach.should == ('9' * 94)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# Include with:
|
2
|
-
#
|
3
|
-
# self.instance_eval(&shared_examples_for_batch_summaries)
|
4
|
-
|
5
|
-
module SharedExamples
|
6
|
-
def self.batch_summaries
|
7
|
-
Proc.new do
|
8
|
-
describe '#service_class_code' do
|
9
|
-
it 'should accept an Integer' do
|
10
|
-
@record.service_class_code = 200
|
11
|
-
@record.service_class_code.should == 200
|
12
|
-
@record.service_class_code_to_ach.should == '200'
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should accept a String' do
|
16
|
-
@record.service_class_code = '220'
|
17
|
-
@record.service_class_code.should == '220'
|
18
|
-
@record.service_class_code_to_ach.should == '220'
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'must be a 200, 220, 225 or 280' do
|
22
|
-
lambda { @record.service_class_code = '201' }.should raise_error(RuntimeError)
|
23
|
-
lambda { @record.service_class_code = 201 }.should raise_error(RuntimeError)
|
24
|
-
lambda { @record.service_class_code = '2020' }.should raise_error(RuntimeError)
|
25
|
-
lambda { @record.service_class_code = '20' }.should raise_error(RuntimeError)
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#service_class_code_to_ach' do
|
29
|
-
it 'should use a given value' do
|
30
|
-
@record.service_class_code = '220'
|
31
|
-
@record.service_class_code_to_ach.should == '220'
|
32
|
-
@record.service_class_code = '225'
|
33
|
-
@record.service_class_code_to_ach.should == '225'
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should default to 200 when entries unavailable' do
|
37
|
-
@record.service_class_code_to_ach.should == '200'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/examples/example_helper.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'micronaut'
|
3
|
-
require 'ach'
|
4
|
-
require 'date'
|
5
|
-
|
6
|
-
def not_in_editor?
|
7
|
-
!(ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM'))
|
8
|
-
end
|
9
|
-
|
10
|
-
Micronaut.configure do |c|
|
11
|
-
c.color_enabled = not_in_editor?
|
12
|
-
c.filter_run :focused => true
|
13
|
-
end
|