ach_builder 0.0.2 → 0.2.1

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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -1
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +10 -0
  7. data/Gemfile +11 -2
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +19 -11
  10. data/Rakefile +44 -0
  11. data/ach_builder.gemspec +9 -5
  12. data/lib/ach/batch.rb +10 -32
  13. data/lib/ach/batch/builder.rb +60 -0
  14. data/lib/ach/batch/control.rb +18 -3
  15. data/lib/ach/batch/header.rb +21 -4
  16. data/lib/ach/component.rb +125 -43
  17. data/lib/ach/component/has_many_association.rb +155 -0
  18. data/lib/ach/constants.rb +15 -1
  19. data/lib/ach/file.rb +50 -44
  20. data/lib/ach/file/builder.rb +81 -0
  21. data/lib/ach/file/control.rb +15 -3
  22. data/lib/ach/file/header.rb +20 -3
  23. data/lib/ach/file/reader.rb +103 -0
  24. data/lib/ach/file/transmission_header.rb +77 -0
  25. data/lib/ach/formatter.rb +113 -76
  26. data/lib/ach/formatter/rule.rb +27 -0
  27. data/lib/ach/record.rb +13 -64
  28. data/lib/ach/record/addenda.rb +25 -0
  29. data/lib/ach/record/base.rb +109 -0
  30. data/lib/ach/record/dynamic.rb +58 -0
  31. data/lib/ach/record/entry.rb +49 -0
  32. data/lib/ach/record/tail.rb +10 -0
  33. data/lib/ach/validations.rb +5 -3
  34. data/lib/ach/version.rb +1 -1
  35. data/lib/ach_builder.rb +20 -33
  36. data/spec/batch_spec.rb +23 -11
  37. data/spec/componenet/has_many_association_spec.rb +111 -0
  38. data/spec/file_spec.rb +173 -81
  39. data/spec/formatter_spec.rb +9 -9
  40. data/spec/reader_spec.rb +55 -0
  41. data/spec/record/addenda_spec.rb +8 -0
  42. data/spec/record/base_spec.rb +53 -0
  43. data/spec/record/dynamic_spec.rb +74 -0
  44. data/spec/record/entry_spec.rb +7 -0
  45. data/spec/record/tail_spec.rb +7 -0
  46. data/spec/spec_helper.rb +1 -0
  47. data/spec/support/ach_file_factory.rb +70 -0
  48. data/spec/support/examples/well_fargo_empty.ach +2 -0
  49. data/spec/support/examples/well_fargo_with_data.ach +6 -0
  50. data/spec/support/helpers/ach_files_examples.rb +17 -0
  51. metadata +69 -26
  52. data/lib/ach/entry.rb +0 -31
  53. data/lib/ach/tail.rb +0 -6
  54. data/spec/entry_spec.rb +0 -7
  55. data/spec/record_spec.rb +0 -34
  56. data/spec/tail_spec.rb +0 -7
@@ -4,19 +4,19 @@ describe ACH::Formatter do
4
4
  before(:all) do
5
5
  module ACH::Formatter
6
6
  # redefining RULES FOR new test values
7
- RULES = RULES.dup
8
- RULES[:ljust_10] = '<-10'
9
- RULES[:ljust_10_transform] = '<-10|upcase'
10
- RULES[:rjust_10] = '->10'
11
- RULES[:rjust_10_spaced] = '->10-'
7
+ RULES = remove_const(:RULES).dup
8
+ RULES[:ljust_5] = '<-5'
9
+ RULES[:ljust_5_transform] = '<-5|upcase'
10
+ RULES[:rjust_6] = '->6'
11
+ RULES[:rjust_6_spaced] = '->6-'
12
12
  end
13
13
  end
14
14
 
15
- it{ ACH::Formatter.ljust_10('FOO').should == 'FOO'.ljust(10) }
15
+ it{ ACH::Formatter.ljust_5('foo').should == 'foo ' }
16
16
 
17
- it{ ACH::Formatter.ljust_10_transform('foo').should == 'FOO'.ljust(10) }
17
+ it{ ACH::Formatter.ljust_5_transform('bar').should == 'BAR ' }
18
18
 
19
- it{ ACH::Formatter.rjust_10(1599).should == '1599'.rjust(10, '0') }
19
+ it{ ACH::Formatter.rjust_6(1599).should == '001599' }
20
20
 
21
- it{ ACH::Formatter.rjust_10_spaced(1599).should == '1599'.rjust(10) }
21
+ it{ ACH::Formatter.rjust_6_spaced(1599).should == ' 1599' }
22
22
  end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::File::Reader do
4
+ context "reading from file" do
5
+ { 'empty' => well_fargo_empty_filename, 'non-empty' => well_fargo_with_data }.each do |description, file|
6
+ context description do
7
+ before do
8
+ @source = file
9
+ @ach_file = ACH::File::Reader.new(File.readlines(@source)).to_ach
10
+ end
11
+
12
+ subject { @ach_file }
13
+
14
+ it "should return instance of the ACH::File" do
15
+ should be_instance_of ACH::File
16
+ end
17
+
18
+ describe "reverse conversion" do
19
+ before do
20
+ @result = @ach_file.to_s!
21
+ @result.gsub! /^9+\n?$/, ''
22
+ @result.gsub! /^\n$/, ''
23
+ end
24
+
25
+ subject { @result }
26
+ it { should be_a String }
27
+ it "should be eql to source string" do
28
+ should == File.read(@source)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ context "reading ACH file without batches" do
36
+ before do
37
+ @source = well_fargo_empty_filename
38
+ @ach_file = ACH::File::Reader.new(File.readlines(@source)).to_ach
39
+ end
40
+
41
+ it { @ach_file.header.should be_an ACH::File::Header }
42
+ it { @ach_file.batches.count.should == 0 }
43
+ end
44
+
45
+ context "reading ACH file with batch" do
46
+ before do
47
+ @source = well_fargo_with_data
48
+ @ach_file = ACH::File::Reader.new(File.readlines(@source)).to_ach
49
+ end
50
+
51
+ it { @ach_file.header.should be_an ACH::File::Header }
52
+ it { @ach_file.batches.count.should == 1 }
53
+ end
54
+
55
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::Record::Addenda do
4
+ it "should have length of 94" do
5
+ addenda = ACH::FileFactory.sample_file.batches[0].addendas.values.flatten.first
6
+ addenda.to_s!.size.should == 94
7
+ end
8
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::Record::Base do
4
+ before(:all) do
5
+ @test_record = Class.new(ACH::Record::Base) do
6
+ fields :customer_name, :amount
7
+ defaults :customer_name => 'JOHN SMITH'
8
+ end
9
+ end
10
+
11
+ it "should have 2 ordered fields" do
12
+ @test_record.fields.should == [:customer_name, :amount]
13
+ end
14
+
15
+ it "should create a record with default value" do
16
+ @test_record.new.customer_name.should == 'JOHN SMITH'
17
+ end
18
+
19
+ it "should overwrite default value" do
20
+ entry = @test_record.new(:customer_name => 'SMITH JOHN')
21
+ entry.customer_name.should == 'SMITH JOHN'
22
+ end
23
+
24
+ it "should generate formatted string" do
25
+ entry = @test_record.new :amount => 1599
26
+ entry.to_s!.should == "JOHN SMITH".ljust(22) + "1599".rjust(10, '0')
27
+ end
28
+
29
+ it "should raise exception with unfilled value" do
30
+ lambda{
31
+ @test_record.new.to_s!
32
+ }.should raise_error(ACH::Record::Base::EmptyFieldError)
33
+ end
34
+
35
+ context "creating record from string" do
36
+ before :each do
37
+ @content = "JOHN SMITH 0000000005"
38
+ @record = @test_record.from_s @content
39
+ end
40
+
41
+ it "should be an instance of ACH::Record" do
42
+ @record.is_a?(ACH::Record::Base).should be_true
43
+ end
44
+
45
+ it "should has correctly detected amount" do
46
+ @record.fields[:amount].should == '0000000005'
47
+ end
48
+
49
+ it "should has correctly detected customer_name" do
50
+ @record.fields[:customer_name].should == 'JOHN SMITH '
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::Record::Dynamic do
4
+ before(:all) do
5
+ @valid_record_definition = lambda do
6
+ Class.new(ACH::Record::Dynamic) do
7
+ record_name
8
+ record_id '345'
9
+ field_one '->1'
10
+ field_two '->2', 34
11
+ field_three '->3' => 45
12
+ end
13
+ end
14
+ end
15
+
16
+ before(:each) do
17
+ module ACH::Formatter
18
+ # redefining RULES FOR new test values
19
+ remove_const(:OLD_RULES) if defined? OLD_RULES
20
+ OLD_RULES = remove_const(:RULES)
21
+ RULES = {
22
+ :record_id => '->5',
23
+ :record_name => '<-10' }
24
+ end
25
+ end
26
+
27
+ after(:each) do
28
+ module ACH::Formatter
29
+ remove_const(:RULES)
30
+ RULES = OLD_RULES
31
+ end
32
+ end
33
+
34
+ it "should should not raise error on valid record definition" do
35
+ expect(&@valid_record_definition).to_not raise_error
36
+ end
37
+
38
+ it "should add new rules to a formatter" do
39
+ @valid_record_definition.call
40
+ ACH::Formatter::RULES.keys.should include(:field_one, :field_two, :field_three)
41
+ end
42
+
43
+ it "should add declared fields to a record" do
44
+ klass = @valid_record_definition.call
45
+ klass.fields.should == [:record_name, :record_id, :field_one, :field_two, :field_three]
46
+ end
47
+
48
+ it "should assign default values to a record" do
49
+ klass = @valid_record_definition.call
50
+ expected_defaults = {
51
+ :record_id => '345',
52
+ :field_two => 34,
53
+ :field_three => 45 }
54
+ klass.defaults.should == expected_defaults
55
+ end
56
+
57
+ it "should raise error when redefining new rule" do
58
+ [['->5'], ['->5', '123'], [{'->5' => '123'}]].each do |args|
59
+ expect do
60
+ Class.new(ACH::Record::Dynamic) do
61
+ record_name *args
62
+ end
63
+ end.to raise_error(ACH::Record::Dynamic::DuplicateFormatError)
64
+ end
65
+ end
66
+
67
+ it "should raise error when declaring unknown field without specifying a format" do
68
+ expect do
69
+ Class.new(ACH::Record::Dynamic) do
70
+ field_four
71
+ end
72
+ end.to raise_error(ACH::Record::Dynamic::UndefinedFormatError)
73
+ end
74
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::Record::Entry do
4
+ it "should have length of 94" do
5
+ ACH::FileFactory.sample_file.batches[0].entries[0].to_s!.length.should == ACH::Constants::RECORD_SIZE
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACH::Record::Tail do
4
+ it "should have length of 94" do
5
+ ACH::Record::Tail.new.to_s!.length.should == ACH::Constants::RECORD_SIZE
6
+ end
7
+ end
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  require 'bundler/setup'
3
3
 
4
4
  require File.expand_path(File.dirname(__FILE__) + '/../lib/ach_builder.rb')
5
+ Dir[File.expand_path(File.dirname(__FILE__) + '/support/**/*.rb')].each {|f| require f}
5
6
 
6
7
  RSpec.configure do |config|
7
8
  # some (optional) config here
@@ -0,0 +1,70 @@
1
+ # Generates ACH files for tests
2
+ class ACH::FileFactory
3
+ def self.sample_file(custom_attrs = {})
4
+ attrs = {:company_id => '11-11111', :company_name => 'MY COMPANY'}
5
+ attrs.merge!(custom_attrs)
6
+ with_transmission = attrs.delete(:transmission_header)
7
+
8
+ klass = ACH::File
9
+ if with_transmission
10
+ klass = Class.new(klass) do
11
+ transmission_header do
12
+ request_type '$$ADD ID='
13
+ remote_id '132'
14
+ blank ' '
15
+ batch_id_parameter 'BID='
16
+ starting_single_quote "'"
17
+ file_type 'NWFACH'
18
+ application_id '321'
19
+ ending_single_quote "'"
20
+ end
21
+ end
22
+ end
23
+
24
+ klass.new(attrs) do
25
+ immediate_dest '123123123'
26
+ immediate_dest_name 'COMMERCE BANK'
27
+ immediate_origin '123123123'
28
+ immediate_origin_name 'MYCOMPANY'
29
+
30
+ ['WEB', 'TEL'].each do |code|
31
+ batch(:entry_class_code => code, :company_entry_descr => 'TV-TELCOM') do
32
+ effective_date Time.now.strftime('%y%m%d')
33
+ desc_date Time.now.strftime('%b %d').upcase
34
+ origin_dfi_id "00000000"
35
+ entry :customer_name => 'JOHN SMITH',
36
+ :customer_acct => '61242882282',
37
+ :amount => '2501',
38
+ :routing_number => '010010101',
39
+ :bank_account => '103030030'
40
+ addenda :addenda_type_code => '05',
41
+ :payment_related_info => 'foo bar',
42
+ :addenda_sequence_num => 1,
43
+ :entry_details_sequence_num => 1
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ def self.with_transmission_header(custom_attrs = {})
51
+ define_transmission_header_fields
52
+ attrs = {:transmission_header => true}.merge(custom_attrs)
53
+ sample_file(attrs)
54
+ end
55
+
56
+ def self.define_transmission_header_fields
57
+ unless ACH::Formatter.defined?(:request_type)
58
+ ACH::Formatter::RULES.merge!({
59
+ :request_type => '<-9-',
60
+ :remote_id => '<-8-',
61
+ :blank => '<-1-',
62
+ :batch_id_parameter => '<-4-',
63
+ :starting_single_quote => '<-1' ,
64
+ :file_type => '<-6-',
65
+ :application_id => '->8' ,
66
+ :ending_single_quote => '<-1' ,
67
+ })
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,2 @@
1
+ 10112345678 0910000190909140528A094101WELLS FARGO WELLS FARGO BANK
2
+ 9000000000001000000000000000000000000000000000000000000
@@ -0,0 +1,6 @@
1
+ 1011234567890 0910000190909140559A094101ABC COMPANY WELLS FARGO BANK
2
+ 5200ABC COMPANY 2222222222PPDPREMIUM SEP 120909120001091000017000001
3
+ 6260515012990123456 00000018130001234 BOB B BROWN SR 1091000010111111
4
+ 799R08091000010406896 05150129 091000010087001
5
+ 820000000200051501290000000018130000000000002222222222 091000010000001
6
+ 9000005000003000000100058631944000000010805000000000000
@@ -0,0 +1,17 @@
1
+ module AchFilesExamples
2
+
3
+ def well_fargo_empty_filename
4
+ File.expand_path(File.dirname(__FILE__) + '/../examples/well_fargo_empty.ach')
5
+ end
6
+
7
+ def well_fargo_with_data
8
+ File.expand_path(File.dirname(__FILE__) + '/../examples/well_fargo_with_data.ach')
9
+ end
10
+
11
+ end
12
+
13
+ if defined?(World)
14
+ World(AchFilesExamples)
15
+ else
16
+ include AchFilesExamples
17
+ end
metadata CHANGED
@@ -1,96 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ach_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
7
+ - TMX Credit
8
8
  - Artem Kuzko
9
+ - Sergey Potapov
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2011-09-14 00:00:00.000000000Z
13
+ date: 2013-08-20 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rspec
16
- requirement: &77088640 !ruby/object:Gem::Requirement
17
- none: false
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ! '>='
19
+ - - '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: 2.0.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *77088640
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: 2.0.0
25
29
  - !ruby/object:Gem::Dependency
26
- name: active_support
27
- requirement: &77088380 !ruby/object:Gem::Requirement
28
- none: false
30
+ name: activesupport
31
+ requirement: !ruby/object:Gem::Requirement
29
32
  requirements:
30
- - - ! '>='
33
+ - - '>='
31
34
  - !ruby/object:Gem::Version
32
35
  version: 2.3.0
33
36
  type: :runtime
34
37
  prerelease: false
35
- version_requirements: *77088380
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: 2.3.0
43
+ - !ruby/object:Gem::Dependency
44
+ name: i18n
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
36
57
  description: Ruby tools for building ACH (Automated Clearing House) files
37
58
  email:
38
- - a.kuzko@gmail.com
59
+ - rubygems@tmxcredit.com
60
+ - AKuzko@sphereconsultinginc.com
61
+ - SPotapov@sphereconsultinginc.com
39
62
  executables: []
40
63
  extensions: []
41
64
  extra_rdoc_files: []
42
65
  files:
43
66
  - .gitignore
44
67
  - .rspec
68
+ - .ruby-gemset
69
+ - .ruby-version
70
+ - .travis.yml
45
71
  - Gemfile
46
72
  - MIT-LICENSE
47
73
  - README.md
48
74
  - Rakefile
49
75
  - ach_builder.gemspec
50
76
  - lib/ach/batch.rb
77
+ - lib/ach/batch/builder.rb
51
78
  - lib/ach/batch/control.rb
52
79
  - lib/ach/batch/header.rb
53
80
  - lib/ach/component.rb
81
+ - lib/ach/component/has_many_association.rb
54
82
  - lib/ach/constants.rb
55
- - lib/ach/entry.rb
56
83
  - lib/ach/file.rb
84
+ - lib/ach/file/builder.rb
57
85
  - lib/ach/file/control.rb
58
86
  - lib/ach/file/header.rb
87
+ - lib/ach/file/reader.rb
88
+ - lib/ach/file/transmission_header.rb
59
89
  - lib/ach/formatter.rb
90
+ - lib/ach/formatter/rule.rb
60
91
  - lib/ach/record.rb
61
- - lib/ach/tail.rb
92
+ - lib/ach/record/addenda.rb
93
+ - lib/ach/record/base.rb
94
+ - lib/ach/record/dynamic.rb
95
+ - lib/ach/record/entry.rb
96
+ - lib/ach/record/tail.rb
62
97
  - lib/ach/validations.rb
63
98
  - lib/ach/version.rb
64
99
  - lib/ach_builder.rb
65
100
  - spec/batch_spec.rb
66
- - spec/entry_spec.rb
101
+ - spec/componenet/has_many_association_spec.rb
67
102
  - spec/file_spec.rb
68
103
  - spec/formatter_spec.rb
69
- - spec/record_spec.rb
104
+ - spec/reader_spec.rb
105
+ - spec/record/addenda_spec.rb
106
+ - spec/record/base_spec.rb
107
+ - spec/record/dynamic_spec.rb
108
+ - spec/record/entry_spec.rb
109
+ - spec/record/tail_spec.rb
70
110
  - spec/spec_helper.rb
71
- - spec/tail_spec.rb
72
- homepage: http://github.com/akuzko/ach_builder
73
- licenses: []
111
+ - spec/support/ach_file_factory.rb
112
+ - spec/support/examples/well_fargo_empty.ach
113
+ - spec/support/examples/well_fargo_with_data.ach
114
+ - spec/support/helpers/ach_files_examples.rb
115
+ homepage: https://github.com/TMXCredit/ach_builder
116
+ licenses:
117
+ - MIT
118
+ metadata: {}
74
119
  post_install_message:
75
120
  rdoc_options: []
76
121
  require_paths:
77
122
  - lib
78
123
  required_ruby_version: !ruby/object:Gem::Requirement
79
- none: false
80
124
  requirements:
81
- - - ! '>='
125
+ - - '>='
82
126
  - !ruby/object:Gem::Version
83
127
  version: '0'
84
128
  required_rubygems_version: !ruby/object:Gem::Requirement
85
- none: false
86
129
  requirements:
87
- - - ! '>='
130
+ - - '>='
88
131
  - !ruby/object:Gem::Version
89
132
  version: '0'
90
133
  requirements: []
91
134
  rubyforge_project:
92
- rubygems_version: 1.8.6
135
+ rubygems_version: 2.0.3
93
136
  signing_key:
94
- specification_version: 3
137
+ specification_version: 4
95
138
  summary: Ruby tools for building ACH files
96
139
  test_files: []