headache 0.1.1 → 0.1.3

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: 38197db347ba22937f9bd2ac2c4ec0f08a7b1912
4
- data.tar.gz: 81698a7ed860a42987faaf609cef7fff299e3b67
3
+ metadata.gz: a72d32f6528347c6a9d436c4bdac202084e41aab
4
+ data.tar.gz: 767ad6765618b1eacdace436a4c58f6c835bacc9
5
5
  SHA512:
6
- metadata.gz: 724993f4ab4e3bd4421d83b59c7d467be8ea86161efb4c464ee35317959de419c9edd239a6634b436fb8cfa7b067a54fae32f17110ab5ee9148ebd7665e5a2f0
7
- data.tar.gz: 7332c63174ef2162947174fd5455d6f2e2f3837a02d1989a22fd8507b24bd9cef312961649aadd9e5c1306f8f2790b9a83eca254cee0edda368199237bae821c
6
+ metadata.gz: c3c1de15d6b368b661d816743bf79e0ebcad538ba32258fb5a9368aaecb29be6ebe76a8fe57d0d2aa88eccdf796e3433db4adf21aa4f3220092182083417059c
7
+ data.tar.gz: 395de1946348f85b31e0a374ed8443d85a88949b446754c488f6f19c80a3962291511d2cf4bff4f63122c5f583acdf5afabf37ac502f6004293784631c47e808
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  *.gem
11
+ .rspec
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'coveralls', require: false
4
+
3
5
  # Specify your gem's dependencies in headache.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # HeadACHe
2
2
 
3
- [![Code Climate](https://img.shields.io/codeclimate/github/teampayoff/headache.svg?style=flat-square)](https://codeclimate.com/github/teampayoff/headache)
3
+ [![Code Climate](https://img.shields.io/codeclimate/github/teampayoff/headache.svg?style=flat-square)](https://codeclimate.com/github/teampayoff/headache) [![Travis CI](https://img.shields.io/travis/teampayoff/headache.svg?style=flat-square)](https://travis-ci.org/teampayoff/headache) [![Coverage](https://img.shields.io/coveralls/teampayoff/headache.svg?style=flat-square)](https://coveralls.io/r/teampayoff/headache)
4
4
 
5
5
  Headache takes a lot of the guesswork out of building [ACH (Automated Clearing House)](https://en.wikipedia.org/wiki/Automated_Clearing_House) files to move money around between banks.
6
6
 
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ['lib']
19
19
  spec.add_dependency 'fixy', '~> 0.0'
20
- spec.add_dependency 'activesupport', '~> 4'
20
+ spec.add_dependency 'activesupport', '>= 4'
21
21
  spec.add_development_dependency 'faker', '~> 1.4'
22
22
  spec.add_development_dependency 'rspec', '~> 3.3'
23
23
  spec.add_development_dependency 'factory_girl', '~> 4.5'
@@ -6,6 +6,7 @@ require 'active_support/core_ext/enumerable'
6
6
 
7
7
  require 'headache/formatters'
8
8
  require 'headache/definitions'
9
+ require 'headache/record/base'
9
10
  require 'headache/records'
10
11
  require 'headache/batch'
11
12
  require 'headache/document'
@@ -5,7 +5,8 @@ module Headache
5
5
  attr_accessor :type, :document, :batch_number, :service_code, :odfi_id,
6
6
  :company_name, :company_identification, :effective_date,
7
7
  :company_name, :company_identification, :discretionary,
8
- :entry_class_code, :entry_description
8
+ :entry_class_code, :entry_description, :descriptive_date,
9
+ :total_debit, :total_credit, :entry_hash
9
10
 
10
11
  @@record_classes = { header: Record::BatchHeader,
11
12
  control: Record::BatchControl }
@@ -23,6 +24,17 @@ module Headache
23
24
  @@record_classes[type] = klass
24
25
  end
25
26
 
27
+ def parse(records)
28
+ @header = @@record_classes[:header].new(self, @document).parse(records.shift)
29
+ @control = @@record_classes[:control].new(self, @document).parse(records.pop)
30
+ records.each { |r| @members << Headache::Record::Entry.new(self, @document).parse(r) }
31
+ self
32
+ end
33
+
34
+ def descriptive_date
35
+ @descriptive_date || Date.today
36
+ end
37
+
26
38
  def effective_date
27
39
  @effective_date || Date.today
28
40
  end
@@ -32,6 +44,12 @@ module Headache
32
44
  @members = []
33
45
  end
34
46
 
47
+ def self.type_from_service_code(code)
48
+ return :credit if code.to_s == '220'
49
+ return :debit if code.to_s == '225'
50
+ fail "unknown service code: #{code.inspect} (expecting 220 or 225)"
51
+ end
52
+
35
53
  def service_code
36
54
  return '220' if type == :credit
37
55
  return '225' if type == :debit
@@ -51,11 +69,17 @@ module Headache
51
69
  end
52
70
 
53
71
  def batch_number
54
- @batch_number || document.batches.index(batch) + 1
72
+ @batch_number || document.batches.index(self) + 1
73
+ end
74
+
75
+ def to_h
76
+ { batch_header: @header.to_h,
77
+ entries: @members.to_a.map(&:to_h),
78
+ batch_control: @control.to_h }
55
79
  end
56
80
 
57
81
  def entry_hash
58
- entries.map(&:routing_identification).map(&:to_i).sum
82
+ @entry_hash || entries.map(&:routing_identification).map(&:to_i).sum
59
83
  end
60
84
 
61
85
  def add_entry(entry)
@@ -73,11 +97,11 @@ module Headache
73
97
  end
74
98
 
75
99
  def total_debit
76
- entries.map(&:amount).select { |amt| amt < 0 }.map(&:abs).sum
100
+ @total_debit || entries.map(&:amount).select { |amt| (amt || 0) < 0 }.map(&:abs).sum
77
101
  end
78
102
 
79
103
  def total_credit
80
- entries.map(&:amount).select { |amt| amt > 0 }.sum
104
+ @total_credit || entries.map(&:amount).select { |amt| (amt || 0) > 0 }.sum
81
105
  end
82
106
 
83
107
  end
@@ -7,10 +7,10 @@ module Headache
7
7
  include Common
8
8
 
9
9
  field :service_code, 3, '2-4', :alphanumeric
10
- field :entry_count, 6, '5-10', :numeric
10
+ field :entry_count, 6, '5-10', :numeric_value
11
11
  field :entry_hash, 10, '11-20', :numeric
12
- field :total_debit, 12, '21-32', :numeric
13
- field :total_credit, 12, '33-44', :numeric
12
+ field :total_debit, 12, '21-32', :numeric_value
13
+ field :total_credit, 12, '33-44', :numeric_value
14
14
  field :company_identification, 10, '45-54', :alphanumeric
15
15
  field :message_authentication_code, 19, '55-73', :nothing
16
16
  field :reserved, 6, '74-79', :nothing
@@ -12,14 +12,13 @@ module Headache
12
12
  field :company_identification, 10, '41-50', :alphanumeric
13
13
  field :entry_class_code, 3, '51-53', :alphanumeric
14
14
  field :entry_description, 10, '54-63', :alphanumeric
15
- field :descriptive_date, 6, '64-69', :nothing
15
+ field :descriptive_date, 6, '64-69', :date
16
16
  field :effective_date, 6, '70-75', :date
17
- field :settlement_date, 3, '76-78', :nothing
17
+ field :settlement_date, 3, '76-78', :nothing # inserted by ACH operator
18
18
  field :originator_status_code, 1, '79-79', :alphanumeric
19
19
  field :odfi_id, 8, '80-87', :alphanumeric
20
- field :batch_number, 7, '88-94', :alphanumeric
20
+ field :batch_number, 7, '88-94', :numeric
21
21
 
22
- field_value :descriptive_date, ''
23
22
  field_value :settlement_date, ''
24
23
  field_value :originator_status_code, '1'
25
24
  end
@@ -13,7 +13,10 @@ module Headache
13
13
 
14
14
  field :record_type_code, 1, '1-1', :alphanumeric
15
15
 
16
- def record_type_codes
16
+ delegate :record_type_codes, to: :class
17
+ delegate :record_type_code, to: :class
18
+
19
+ def self.record_type_codes
17
20
  { file_header: 1,
18
21
  batch_header: 5,
19
22
  entry: 6,
@@ -21,8 +24,8 @@ module Headache
21
24
  file_control: 9 }
22
25
  end
23
26
 
24
- def record_type_code
25
- record_type = self.class.name.demodulize.underscore
27
+ def self.record_type_code
28
+ record_type = name.demodulize.underscore
26
29
  record_type_codes[record_type.to_sym]
27
30
  end
28
31
  end
@@ -10,7 +10,7 @@ module Headache
10
10
  field :routing_identification, 8, '4-11', :numeric
11
11
  field :check_digit, 1, '12-12', :numeric
12
12
  field :account_number, 17, '13-29', :alphanumeric
13
- field :amount, 10, '30-39', :numeric
13
+ field :amount, 10, '30-39', :numeric_value
14
14
  field :internal_id, 15, '40-54', :alphanumeric
15
15
  field :individual_name, 22, '55-76', :alphanumeric
16
16
  field :discretionary, 2, '77-78', :alphanumeric
@@ -20,14 +20,6 @@ module Headache
20
20
  field_value :addenda_record, '0'
21
21
  field_value :discretionary, ''
22
22
  end
23
-
24
- def routing_identification
25
- routing_number.first 8
26
- end
27
-
28
- def check_digit
29
- routing_number.last 1
30
- end
31
23
  end
32
24
  end
33
25
  end
@@ -6,14 +6,14 @@ module Headache
6
6
  included do
7
7
  include Common
8
8
 
9
- field :batch_count, 6, '2-7', :numeric
10
- field :block_count, 6, '8-13', :numeric
11
- field :entry_count, 8, '14-21', :numeric
9
+ field :batch_count, 6, '2-7', :numeric_value
10
+ field :block_count, 6, '8-13', :numeric_value
11
+ field :entry_count, 8, '14-21', :numeric_value
12
12
  field :entry_hash, 10, '22-31', :numeric
13
- field :total_debit, 12, '32-43', :numeric
14
- field :total_credit, 12, '44-55', :numeric
13
+ field :total_debit, 12, '32-43', :numeric_value
14
+ field :total_credit, 12, '44-55', :numeric_value
15
15
  field :reserved, 39, '56-94', :nothing
16
-
16
+
17
17
  field_value :reserved, ''
18
18
  end
19
19
  end
@@ -2,12 +2,22 @@ module Headache
2
2
  class Document < Fixy::Document
3
3
  attr_reader :batches
4
4
 
5
+ LINE_SEPARATOR = "\r\n"
6
+
5
7
  delegate :add_entry, :'<<', to: :first_batch
6
8
 
7
9
  @@record_classes = { batch: Batch,
8
10
  header: Record::FileHeader,
9
11
  control: Record::FileControl }
10
12
 
13
+ def self.header_class
14
+ @@record_classes[:header]
15
+ end
16
+
17
+ def self.control_class
18
+ @@record_classes[:control]
19
+ end
20
+
11
21
  def self.header=(klass)
12
22
  set_class :header, klass
13
23
  end
@@ -16,13 +26,50 @@ module Headache
16
26
  set_class :control, klass
17
27
  end
18
28
 
29
+ def self.extract_lines(string_or_file)
30
+ string = string_or_file.respond_to?(:read) ? string_or_file.read : string_or_file
31
+ string.split(LINE_SEPARATOR).reject { |line| line == Headache::Record::Overflow.new.generate.strip }
32
+ end
33
+
34
+ def self.cleanse_records(records)
35
+ invalid_lines = records.reject { |line| Headache::Record::FileHeader.record_type_codes.values.include?(line.first.to_i) }
36
+ raise "uknown record type(s): #{invalid_lines.map(&:first).inspect}" if invalid_lines.any?
37
+ records
38
+ end
39
+
40
+ def self.parse(string_or_file)
41
+ records = cleanse_records(extract_lines string_or_file)
42
+ header = header_class.new(nil).parse(records.shift)
43
+ control = control_class.new(nil).parse(records.pop)
44
+ batches = get_batches(records).map { |b| Headache::Batch.new(self).parse(b) }
45
+ new header, control, batches
46
+ end
47
+
48
+ def self.get_batches(records)
49
+ batches = []
50
+ batch = []
51
+ records.each do |line|
52
+ if line.starts_with?(Headache::Record::BatchHeader.record_type_codes[:batch_header].to_s)
53
+ batches << batch unless batches.empty? && batch == []
54
+ batch = [line]
55
+ else
56
+ batch << line
57
+ end
58
+ end
59
+ batches << batch
60
+ end
61
+
19
62
  def self.set_class(type, klass)
20
63
  fail "unknown record class: #{type}" unless @@record_classes[type].present?
21
64
  @@record_classes[type] = klass
22
65
  end
23
66
 
24
- def initialize
25
- @batches = []
67
+ def initialize(header = nil, control = nil, batches = [])
68
+ @header = header
69
+ @control = control
70
+ @batches = batches
71
+ @header.document = self unless @header.nil?
72
+ @control.document = self unless @control.nil?
26
73
  end
27
74
 
28
75
  def first_batch
@@ -57,6 +104,12 @@ module Headache
57
104
  @control ||= @@record_classes[:control].new self
58
105
  end
59
106
 
107
+ def records
108
+ ([ header ] << batches.map do |batch|
109
+ [ batch.header, batch.entries, batch.control ]
110
+ end << control).flatten # .compact
111
+ end
112
+
60
113
  def lines
61
114
  @content.split("\n").count
62
115
  end
@@ -65,6 +118,12 @@ module Headache
65
118
  10 - lines % 10
66
119
  end
67
120
 
121
+ def to_h
122
+ { file_header: @header.to_h,
123
+ batches: @batches.map(&:to_h),
124
+ file_control: @control.to_h }
125
+ end
126
+
68
127
  def build
69
128
  append_record header
70
129
  @batches.each do |batch|
@@ -1,14 +1,24 @@
1
1
  module Headache
2
2
  module Formatters
3
3
  include Fixy::Formatter::Alphanumeric
4
+ BLANK_DATE = " "
4
5
 
5
6
  def format_alphanumeric(input, length)
6
7
  super(input, length).upcase
7
8
  end
8
9
 
9
- def format_date(input, _length)
10
- fail "input #{input.inspect} does not respond to #strftime!" unless input.respond_to?(:strftime)
11
- input.strftime '%y%m%d'
10
+ def format_numeric_value(input, length)
11
+ format_numeric(input, length)
12
+ end
13
+
14
+ def format_date(input, length)
15
+ if input.respond_to?(:strftime)
16
+ return input.strftime '%y%m%d'
17
+ elsif input.blank?
18
+ return BLANK_DATE
19
+ else
20
+ format_date Date.strptime(input.to_s, '%y%m%d'), length
21
+ end
12
22
  end
13
23
 
14
24
  def format_nothing(_input, length)
@@ -23,6 +33,12 @@ module Headache
23
33
  end
24
34
 
25
35
  def format_time(input, _length)
36
+ if input.is_a?(String) || input.is_a?(Fixnum)
37
+ chars = input.to_s.chars
38
+ minutes = chars.pop(2).join.to_i
39
+ hours = chars.join.to_i
40
+ input = Time.new 0, 1, 1, hours, minutes
41
+ end
26
42
  fail "input #{input.inspect} does not respond to #strftime!" unless input.respond_to?(:strftime)
27
43
  input.strftime '%H%M'
28
44
  end
@@ -0,0 +1,57 @@
1
+ module Headache
2
+ module Record
3
+ class Base < Fixy::Record
4
+ def self.parse_fields_normalize(record_string)
5
+ parse_fields(record_string).inject({}) { |m,i| m[i.first] = normalize_field_value(i.first, i.last); m }
6
+ end
7
+
8
+ def self.parse_fields(record_string)
9
+ parse(record_string)[:fields].inject({}) do |m,i|
10
+ m[i[:name]] = i[:value]; m
11
+ end
12
+ end
13
+
14
+ def self.fields
15
+ @record_fields.to_a.map { |i| i.last }.inject({}) { |m,i| m[i[:name]] = i.except(:name); m }
16
+ end
17
+
18
+ def self.normalize_field_value(field, value)
19
+ field_type = fields[field].try(:[],:type)
20
+ return value if field_type.nil?
21
+
22
+ case field_type
23
+ when :numeric_value
24
+ value.gsub(/^0+/,'').to_i
25
+ when :alphanumeric
26
+ value.strip
27
+ when :nothing
28
+ nil
29
+ else
30
+ value
31
+ end
32
+ end
33
+
34
+ def normalize_field_value(f, v)
35
+ self.class.normalize_field_value(f, v)
36
+ end
37
+
38
+ def to_h
39
+ str = self.generate.gsub Headache::Document::LINE_SEPARATOR, ''
40
+ self.class.parse_fields(str)
41
+ end
42
+
43
+ def parse_fields(record_string)
44
+ self.class.parse_fields record_string
45
+ end
46
+
47
+ def parse(record_string)
48
+ parse_fields(record_string).each_pair do |field, value|
49
+ if respond_to?("#{field}=")
50
+ send "#{field}=", normalize_field_value(field, value)
51
+ end
52
+ end
53
+ self
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,12 +1,13 @@
1
1
  module Headache
2
2
  module Record
3
- class BatchControl < Fixy::Record
3
+ class BatchControl < Headache::Record::Base
4
4
  include Definition::BatchControl
5
5
 
6
6
  attr_accessor :batch, :document
7
7
 
8
- delegate :entry_hash, :total_debit, :total_credit, :batch_number,
9
- :service_code, :odfi_id, :company_identification, to: :batch
8
+ delegate :entry_hash, :batch_number, :total_debit, :total_credit,
9
+ :total_debit=, :total_credit=, :service_code, :odfi_id,
10
+ :company_identification, :entry_hash=, to: :batch
10
11
 
11
12
  def initialize(batch, document)
12
13
  @batch = batch
@@ -16,7 +17,6 @@ module Headache
16
17
  def entry_count
17
18
  batch.size
18
19
  end
19
-
20
20
  end
21
21
  end
22
22
  end
@@ -1,6 +1,6 @@
1
1
  module Headache
2
2
  module Record
3
- class BatchHeader < Fixy::Record
3
+ class BatchHeader < Headache::Record::Base
4
4
  include Definition::BatchHeader
5
5
 
6
6
  attr_accessor :batch, :document
@@ -9,12 +9,19 @@ module Headache
9
9
  :company_identification, :'company_identification=', :company_name,
10
10
  :'company_name=', :entry_description, :'entry_description=', :discretionary,
11
11
  :'discretionary=', :entry_class_code, :'entry_class_code=', :effective_date,
12
- :'effective_date=', to: :batch
12
+ :'effective_date=', :'type=', :descriptive_date,
13
+ :'descriptive_date=', to: :batch
13
14
 
14
15
  def initialize(batch = nil, document = nil)
15
16
  @batch = batch
16
17
  @document = document
17
18
  end
19
+
20
+ def parse_fields(record_string)
21
+ fields = super
22
+ type = Headache::Batch.type_from_service_code(fields.delete :service_code)
23
+ fields.merge(type: type)
24
+ end
18
25
  end
19
26
  end
20
27
  end
@@ -1,14 +1,54 @@
1
1
  module Headache
2
2
  module Record
3
- class Entry < Fixy::Record
3
+ class Entry < Headache::Record::Base
4
4
  include Definition::Entry
5
5
 
6
6
  attr_accessor :routing_number, :account_number, :amount,
7
7
  :internal_id, :trace_number, :individual_name,
8
- :transaction_code, :document, :batch, :discretionary
8
+ :transaction_code, :document, :batch, :discretionary,
9
+ :check_digit, :routing_identification
10
+
11
+ def check_digit=(value)
12
+ rval = (@check_digit = value)
13
+ assemble_routing_number
14
+ rval
15
+ end
16
+
17
+ def routing_identification=(value)
18
+ rval = (@routing_identification = value)
19
+ assemble_routing_number
20
+ rval
21
+ end
22
+
23
+ def assemble_routing_number
24
+ if @routing_identification.present? && @check_digit.present?
25
+ @routing_number = "#{@routing_identification}#{@check_digit}"
26
+ end
27
+ end
28
+
29
+ def to_h
30
+ new_hsh = {}
31
+ super.each_pair do |key, value|
32
+ next if key == :check_digit
33
+ if key == :routing_identification
34
+ key = :routing_number
35
+ value = @routing_number
36
+ end
37
+ new_hsh[key] = value
38
+ end
39
+ new_hsh
40
+ end
41
+
42
+ def routing_identification
43
+ @routing_identification || routing_number.to_s.first(8)
44
+ end
45
+
46
+ def check_digit
47
+ @check_digit || routing_number.to_s.last(1)
48
+ end
9
49
 
10
50
  def initialize(batch = nil, document = nil)
11
- @batch = batch
51
+ @batch = batch
12
52
  @document = document
13
53
  end
14
54
  end
@@ -1,6 +1,6 @@
1
1
  module Headache
2
2
  module Record
3
- class FileControl < Fixy::Record
3
+ class FileControl < Headache::Record::Base
4
4
  include Definition::FileControl
5
5
 
6
6
  attr_accessor :document
@@ -1,6 +1,6 @@
1
1
  module Headache
2
2
  module Record
3
- class FileHeader < Fixy::Record
3
+ class FileHeader < Headache::Record::Base
4
4
  include Definition::FileHeader
5
5
 
6
6
  attr_accessor :reference_code, :creation_time, :origin, :origin_name,
@@ -12,7 +12,7 @@ module Headache
12
12
  end
13
13
 
14
14
  def destination
15
- ' ' + (@destination || '')
15
+ ' ' + (@destination || '').to_s
16
16
  end
17
17
 
18
18
  def creation_date
@@ -1,6 +1,6 @@
1
1
  module Headache
2
2
  module Record
3
- class Overflow < Fixy::Record
3
+ class Overflow < Headache::Record::Base
4
4
  include Formatters
5
5
 
6
6
  set_record_length 94
@@ -1,3 +1,3 @@
1
1
  module Headache
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: headache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Payoff, Inc.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2015-09-02 00:00:00.000000000 Z
12
+ date: 2015-10-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fixy
@@ -29,14 +29,14 @@ dependencies:
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '4'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '4'
42
42
  - !ruby/object:Gem::Dependency
@@ -137,6 +137,7 @@ files:
137
137
  - lib/headache/definitions.rb
138
138
  - lib/headache/document.rb
139
139
  - lib/headache/formatters.rb
140
+ - lib/headache/record/base.rb
140
141
  - lib/headache/record/batch_control.rb
141
142
  - lib/headache/record/batch_header.rb
142
143
  - lib/headache/record/entry.rb
@@ -165,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
166
  version: '0'
166
167
  requirements: []
167
168
  rubyforge_project:
168
- rubygems_version: 2.4.8
169
+ rubygems_version: 2.4.5.1
169
170
  signing_key:
170
171
  specification_version: 4
171
172
  summary: Take the pain out of building ACH files.