headache 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 666d14df0f9f60429e47c14b581ad73fd37611e7
4
+ data.tar.gz: e75fd53aa8b9c3e8708ad252e9adc83722aefd66
5
+ SHA512:
6
+ metadata.gz: a79fdbed3a9c657c79137485d88315209af552f135dab39f2e50ab366aa996cae2d53de1062c5fa5181a5af668c633cb17d2b6641030b20b4bc8c3cbc7c9c884
7
+ data.tar.gz: cac050138755d8ca8575441db4736c8a2aa3a60b879af9aa90617e131a3b087cc8fb73275c1c31fce08f770b638fc0237e0c1823360f7f138461bfe680f6427b
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in headache.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # HeadACHe
2
+
3
+ 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.
4
+
5
+ Headache is built on top of the excellent [Fixy gem](https://github.com/Chetane/fixy) for handling fixed-width files.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'headache'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install headache
22
+
23
+ ## Usage
24
+
25
+ It is outside of the scope of this document to describe NACHA's ACH file format. There are plenty of resources available that explain the syntax in detail.
26
+
27
+ ### Record Types
28
+
29
+ ACH files contain 5 different record types. They are:
30
+
31
+ * File Header `Headache::Record::FileHeader`
32
+ * Batch Header `Headache::Record::FileHeader`
33
+ * Entry Detail `Headache::Record::Entry`
34
+ * Batch Control `Headache::Record::BatchControl`
35
+ * File Control `Headache::Record::FileControl`
36
+
37
+ A batch itself is represented by `Headache::Batch` and the document is unsurprisingly `Headache::Document`.
38
+
39
+ ### Building an ACH Document
40
+
41
+ Headache provides some convenience out-of-the-box if you only plan to generate ACH files that contain a single batch, however there's nothing stopping you from implementing multiple batches.
42
+
43
+ Calling `#batch` or `#first_batch` will automatically create a `Headache::Batch` if the document's batch list is empty. `#batch` will raise an exception if the document contains multiple batches.
44
+
45
+ All ACH fields are represented and available to you. Headache attempts to abstract batch header and control records, allowing you to specify those details directly on the `Batch` object itself, but more granular control over that data is available if needed.
46
+
47
+ Further, Headache abstracts an ACH record _definition_ from the record itself; so should you need to create your own record and document objects, you're free to re-use the [definition mixins](https://github.com/teampayoff/headache/blob/master/lib/headache/definition) for this purpose.
48
+
49
+ Create a new ACH document (some optional fields are omitted in this example):
50
+
51
+ ```ruby
52
+ document = Headache::Document.new.tap do |document|
53
+ document.header.tap do |file_header|
54
+ file_header.destination_name = '1ST INTERNET BANK'
55
+ file_header.destination = '111111111' # Originating DFI number
56
+ file_header.origin_name = 'ACME CORP'
57
+ file_header.origin = '1111111111'
58
+ file_header.reference_code = '11111111'
59
+ end
60
+ document.batch.tap do |batch|
61
+ batch.type = :debit
62
+ batch.odfi_id = '11111111'
63
+ batch.company_identification = '1111111111'
64
+ batch.batch_number = 1
65
+ batch.effective_date = Date.today
66
+ batch.company_name = 'ACME CORP FTW'
67
+ batch.entry_description = 'My Description'
68
+ batch.entry_class_code = 'WEB'
69
+ batch.discretionary = 'My Discretionary Data'
70
+
71
+ # Now, for each credit/debit, generate an Entry ...
72
+ batch << Headache::Record::Entry.new.tap do |entry|
73
+ entry.routing_number = '123456789'
74
+ entry.account_number = '1234567890'
75
+ entry.amount = -100_00 # $100.00 (negative, since we're debiting)
76
+ entry.individual_name = 'Bob Smith'
77
+
78
+ # these fields are for your own tracking...
79
+ entry.trace_number = '1234567890'
80
+ entry.internal_id = '1234567890'
81
+ entry.transaction_code = '1234567890'
82
+ end
83
+ end
84
+ end
85
+ ```
86
+
87
+ Finally, you can generate the file:
88
+
89
+ ```ruby
90
+ document.generate_to_file 'ACH.txt'
91
+ ```
92
+
93
+ ## Development
94
+
95
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
96
+
97
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
98
+
99
+ ## Contributing
100
+
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/teampayoff/headache.
102
+
103
+ ## Authors
104
+
105
+ Made possible by all of our [contributors](https://github.com/teampayoff/headache/graphs/contributors).
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "headache"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/headache.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'headache/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'headache'
8
+ spec.version = Headache::VERSION
9
+ spec.authors = ['Payoff, Inc.', 'Chris Bielinski']
10
+ spec.email = ['engineering@payoff.com', 'cbielinski@payoff.com']
11
+ spec.licenses = ['MIT']
12
+ spec.summary = 'Take the pain out of building ACH files.'
13
+ spec.description = 'Take the pain out of building ACH files. Wraps the Fixy gem for building fixed-with ACH files as specified by NACHA.'
14
+ spec.homepage = 'https://github.com/teampayoff/headache'
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = 'exe'
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ['lib']
19
+ spec.add_dependency 'fixy', '~> 0.0'
20
+ spec.add_dependency 'activesupport', '~> 4'
21
+ spec.add_development_dependency 'faker', '~> 1.4'
22
+ spec.add_development_dependency 'rspec', '~> 3.3'
23
+ spec.add_development_dependency 'factory_girl', '~> 4.5'
24
+ spec.add_development_dependency 'bundler', '~> 1.10'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ end
@@ -0,0 +1,84 @@
1
+ module Headache
2
+ class Batch
3
+ include Enumerable
4
+
5
+ attr_accessor :type, :document, :batch_number, :service_code, :odfi_id,
6
+ :company_name, :company_identification, :effective_date,
7
+ :company_name, :company_identification, :discretionary,
8
+ :entry_class_code, :entry_description
9
+
10
+ @@record_classes = { header: Record::BatchHeader,
11
+ control: Record::BatchControl }
12
+
13
+ def self.header=(klass)
14
+ set_class :header, klass
15
+ end
16
+
17
+ def self.control=(klass)
18
+ set_class :control, klass
19
+ end
20
+
21
+ def self.set_class(type, klass)
22
+ fail "unknown record class: #{type}" unless @@record_classes[type].present?
23
+ @@record_classes[type] = klass
24
+ end
25
+
26
+ def effective_date
27
+ @effective_date || Date.today
28
+ end
29
+
30
+ def initialize(document = nil)
31
+ @document = document
32
+ @members = []
33
+ end
34
+
35
+ def service_code
36
+ return '220' if type == :credit
37
+ return '225' if type == :debit
38
+ fail "unknown batch type: #{type.inspect} (expecting :credit or :debit)"
39
+ end
40
+
41
+ def header
42
+ @header ||= @@record_classes[:header].new self, @document
43
+ end
44
+
45
+ def control
46
+ @control ||= @@record_classes[:control].new self, @document
47
+ end
48
+
49
+ def entries
50
+ @members
51
+ end
52
+
53
+ def batch_number
54
+ @batch_number || document.batches.index(batch) + 1
55
+ end
56
+
57
+ def entry_hash
58
+ entries.map(&:routing_identification).map(&:to_i).sum
59
+ end
60
+
61
+ def add_entry(entry)
62
+ entry.batch = self
63
+ @members << entry
64
+ end
65
+
66
+ def <<(entry_or_entries)
67
+ (entries.is_a?(Array) ? entry_or_entries : [entry_or_entries]).each { |e| add_entry e }
68
+ self
69
+ end
70
+
71
+ def method_missing(m, *args, &block)
72
+ entries.send m, *args, &block
73
+ end
74
+
75
+ def total_debit
76
+ entries.map(&:amount).select { |amt| amt < 0 }.map(&:abs).sum
77
+ end
78
+
79
+ def total_credit
80
+ entries.map(&:amount).select { |amt| amt > 0 }.sum
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,25 @@
1
+ module Headache
2
+ module Definition
3
+ module BatchControl
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Common
8
+
9
+ field :service_code, 3, '2-4', :alphanumeric # Field2
10
+ field :entry_count, 6, '5-10', :numeric # Field3
11
+ field :entry_hash, 10, '11-20', :numeric # Field4
12
+ field :total_debit, 12, '21-32', :numeric # Field5
13
+ field :total_credit, 12, '33-44', :numeric # Field6
14
+ field :company_identification, 10, '45-54', :alphanumeric # Field7
15
+ field :message_authentication_code, 19, '55-73', :nothing # Field8
16
+ field :reserved, 6, '74-79', :nothing # Field9
17
+ field :odfi_id, 8, '80-87', :alphanumeric # Field10
18
+ field :batch_number, 7, '88-94', :numeric # Field11
19
+
20
+ field_value :message_authentication_code, ''
21
+ field_value :reserved, ''
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module Headache
2
+ module Definition
3
+ module BatchHeader
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Common
8
+
9
+ field :service_code, 3, '2-4', :alphanumeric # Field2 credits = 220, debits = 225
10
+ field :company_name, 16, '5-20', :alphanumeric # Field3
11
+ field :discretionary, 20, '21-40', :alphanumeric # Field4
12
+ field :company_identification, 10, '41-50', :alphanumeric # Field5
13
+ field :entry_class_code, 3, '51-53', :alphanumeric # Field6
14
+ field :entry_description, 10, '54-63', :alphanumeric # Field7
15
+ field :descriptive_date, 6, '64-69', :nothing # Field8
16
+ field :effective_date, 6, '70-75', :date # Field9
17
+ field :settlement_date, 3, '76-78', :nothing # Field10
18
+ field :originator_status_code, 1, '79-79', :alphanumeric # Field11
19
+ field :odfi_id, 8, '80-87', :alphanumeric # Field12
20
+ field :batch_number, 7, '88-94', :alphanumeric # Field13
21
+
22
+ field_value :descriptive_date, ''
23
+ field_value :settlement_date, ''
24
+ field_value :originator_status_code, '1'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ module Headache
2
+ module Definition
3
+ module Common
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ attr_accessor :document
8
+
9
+ set_record_length 94
10
+ set_line_ending Fixy::Record::LINE_ENDING_CRLF
11
+
12
+ include Formatters
13
+
14
+ field :record_type_code, 1, '1-1', :alphanumeric
15
+
16
+ def record_type_codes
17
+ { file_header: 1,
18
+ batch_header: 5,
19
+ entry: 6,
20
+ batch_control: 8,
21
+ file_control: 9 }
22
+ end
23
+
24
+ def record_type_code
25
+ record_type = self.class.name.demodulize.underscore
26
+ record_type_codes[record_type.to_sym]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ module Headache
2
+ module Definition
3
+ module Entry
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Common
8
+
9
+ field :transaction_code, 2, '2-3', :alphanumeric # Field2
10
+ field :routing_identification, 8, '4-11', :numeric # Field3
11
+ field :check_digit, 1, '12-12', :numeric # Field4
12
+ field :account_number, 17, '13-29', :alphanumeric # Field5
13
+ field :amount, 10, '30-39', :numeric # Field6
14
+ field :internal_id, 15, '40-54', :alphanumeric # Field7
15
+ field :individual_name, 22, '55-76', :alphanumeric # Field8
16
+ field :discretionary, 2, '77-78', :alphanumeric # Field9
17
+ field :addenda_record, 1, '79-79', :alphanumeric # Field10
18
+ field :trace_number, 15, '80-94', :alphanumeric # Field11
19
+
20
+ field_value :addenda_record, '0'
21
+ field_value :discretionary, ''
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
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ module Headache
2
+ module Definition
3
+ module FileControl
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Common
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
12
+ field :entry_hash, 10, '22-31', :numeric
13
+ field :total_debit, 12, '32-43', :numeric
14
+ field :total_credit, 12, '44-55', :numeric
15
+ field :reserved, 39, '56-94', :nothing
16
+
17
+ field_value :reserved, ''
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module Headache
2
+ module Definition
3
+ module FileHeader
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Common
8
+
9
+ field :priority_code, 2, '2-3', :numeric # Field2
10
+ field :destination, 10, '4-13', :alphanumeric # Field3
11
+ field :origin, 10, '14-23', :alphanumeric # Field4
12
+ field :creation_date, 6, '24-29', :date # Field5
13
+ field :creation_time, 4, '30-33', :time # Field6
14
+ field :id_modifier, 1, '34-34', :alphanumeric # Field7
15
+ field :record_size, 3, '35-37', :alphanumeric # Field8
16
+ field :blocking_factor, 2, '38-39', :alphanumeric # Field9
17
+ field :format_code, 1, '40-40', :alphanumeric # Field10
18
+ field :destination_name, 23, '41-63', :alphanumeric # Field11
19
+ field :origin_name, 23, '64-86', :alphanumeric # Field12
20
+ field :reference_code, 8, '87-94', :alphanumeric # Field13
21
+
22
+ field_value :priority_code, '01'
23
+ field_value :record_size, '094'
24
+ field_value :blocking_factor, '10'
25
+ field_value :format_code, '1'
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ require 'headache/definition/common'
2
+ require 'headache/definition/file_header'
3
+ require 'headache/definition/batch_header'
4
+ require 'headache/definition/entry'
5
+ require 'headache/definition/batch_control'
6
+ require 'headache/definition/file_control'
@@ -0,0 +1,80 @@
1
+ module Headache
2
+ class Document < Fixy::Document
3
+ attr_reader :batches
4
+
5
+ delegate :add_entry, :'<<', to: :first_batch
6
+
7
+ @@record_classes = { batch: Batch,
8
+ header: Record::FileHeader,
9
+ control: Record::FileControl }
10
+
11
+ def self.header=(klass)
12
+ set_class :header, klass
13
+ end
14
+
15
+ def self.control=(klass)
16
+ set_class :control, klass
17
+ end
18
+
19
+ def self.set_class(type, klass)
20
+ fail "unknown record class: #{type}" unless @@record_classes[type].present?
21
+ @@record_classes[type] = klass
22
+ end
23
+
24
+ def initialize
25
+ @batches = []
26
+ end
27
+
28
+ def first_batch
29
+ add_batch @@record_classes[:batch].new(self) if @batches.empty?
30
+ @batches.first
31
+ end
32
+
33
+ def batch
34
+ fail 'multiple batches detected, be more explicit or use first_batch' if @batches.count > 1
35
+ first_batch
36
+ end
37
+
38
+ def add_batch(batch)
39
+ batch.document = self
40
+ @batches << batch # @@record_classes[:batch].new(self)
41
+ end
42
+
43
+ def <<(batch)
44
+ add_batch batch
45
+ self
46
+ end
47
+
48
+ def entries
49
+ @batches.map(&:entries).flatten
50
+ end
51
+
52
+ def header
53
+ @header ||= @@record_classes[:header].new self
54
+ end
55
+
56
+ def control
57
+ @control ||= @@record_classes[:control].new self
58
+ end
59
+
60
+ def lines
61
+ @content.split("\n").count
62
+ end
63
+
64
+ def overflow_lines_needed
65
+ 10 - lines % 10
66
+ end
67
+
68
+ def build
69
+ append_record header
70
+ @batches.each do |batch|
71
+ append_record batch.header
72
+ batch.entries.each { |entry| append_record entry }
73
+ append_record batch.control
74
+ end
75
+ append_record control
76
+ overflow_lines_needed.times { append_record Record::Overflow.new }
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,30 @@
1
+ module Headache
2
+ module Formatters
3
+ include Fixy::Formatter::Alphanumeric
4
+
5
+ def format_alphanumeric(input, length)
6
+ super(input, length).upcase
7
+ end
8
+
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'
12
+ end
13
+
14
+ def format_nothing(_input, length)
15
+ ' ' * length
16
+ end
17
+
18
+ def format_numeric(input, length)
19
+ input = input.to_i.abs.to_s
20
+ fail ArgumentError, "Invalid Input: #{input.inspect} (only digits are accepted) from #{self.class.to_s.demodulize}" unless input =~ /^\d+$/
21
+ fail ArgumentError, "Not enough length (input: #{input}, length: #{length})" if input.length > length
22
+ input.rjust(length, '0')
23
+ end
24
+
25
+ def format_time(input, _length)
26
+ fail "input #{input.inspect} does not respond to #strftime!" unless input.respond_to?(:strftime)
27
+ input.strftime '%H%M'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module Headache
2
+ module Record
3
+ class BatchControl < Fixy::Record
4
+ include Definition::BatchControl
5
+
6
+ attr_accessor :batch, :document
7
+
8
+ delegate :entry_hash, :total_debit, :total_credit, :batch_number,
9
+ :service_code, :odfi_id, :company_identification, to: :batch
10
+
11
+ def initialize(batch, document)
12
+ @batch = batch
13
+ @document = document
14
+ end
15
+
16
+ def entry_count
17
+ batch.size
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Headache
2
+ module Record
3
+ class BatchHeader < Fixy::Record
4
+ include Definition::BatchHeader
5
+
6
+ attr_accessor :batch, :document
7
+
8
+ delegate :batch_number, :'batch_number=', :service_code, :odfi_id, :'odfi_id=',
9
+ :company_identification, :'company_identification=', :company_name,
10
+ :'company_name=', :entry_description, :'entry_description=', :discretionary,
11
+ :'discretionary=', :entry_class_code, :'entry_class_code=', :effective_date,
12
+ :'effective_date=', to: :batch
13
+
14
+ def initialize(batch = nil, document = nil)
15
+ @batch = batch
16
+ @document = document
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Headache
2
+ module Record
3
+ class Entry < Fixy::Record
4
+ include Definition::Entry
5
+
6
+ attr_accessor :routing_number, :account_number, :amount,
7
+ :internal_id, :trace_number, :individual_name,
8
+ :transaction_code, :document, :batch, :discretionary
9
+
10
+ def initialize(batch = nil, document = nil)
11
+ @batch = batch
12
+ @document = document
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ module Headache
2
+ module Record
3
+ class FileControl < Fixy::Record
4
+ include Definition::FileControl
5
+
6
+ attr_accessor :document
7
+
8
+ def initialize(document = nil)
9
+ @document = document
10
+ end
11
+
12
+ def batch_count
13
+ document.batches.count
14
+ end
15
+
16
+ def block_count
17
+ (((batch_count * 2) + document.entries.count + 2) / 10.0).ceil
18
+ end
19
+
20
+ def entry_count
21
+ document.entries.count
22
+ end
23
+
24
+ def entry_hash
25
+ batch_sum(:entry_hash).to_s.last(10)
26
+ end
27
+
28
+ def total_debit
29
+ batch_sum :total_debit
30
+ end
31
+
32
+ def total_credit
33
+ batch_sum :total_credit
34
+ end
35
+
36
+ protected
37
+
38
+ def batch_sum(method)
39
+ document.batches
40
+ .map { |b| b.send method }
41
+ .map(&:to_i).sum
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ module Headache
2
+ module Record
3
+ class FileHeader < Fixy::Record
4
+ include Definition::FileHeader
5
+
6
+ attr_accessor :reference_code, :creation_time, :origin, :origin_name,
7
+ :destination, :destination_name, :document, :creation_date,
8
+ :id_modifier
9
+
10
+ def initialize(document = nil)
11
+ @document = document
12
+ end
13
+
14
+ def destination
15
+ ' ' + (@destination || '')
16
+ end
17
+
18
+ def creation_date
19
+ @creation_date || Date.today
20
+ end
21
+
22
+ def creation_time
23
+ @creation_time || Time.now
24
+ end
25
+
26
+ def id_modifier
27
+ @id_modifier || 'A'
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ module Headache
2
+ module Record
3
+ class Overflow < Fixy::Record
4
+ include Formatters
5
+
6
+ set_record_length 94
7
+ set_line_ending Fixy::Record::LINE_ENDING_CRLF
8
+
9
+ field :overflow, 94, '1-94', :numeric
10
+ field_value :overflow, -> { '9' * 94 }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ require 'headache/record/file_header'
2
+ require 'headache/record/batch_header'
3
+ require 'headache/record/entry'
4
+ require 'headache/record/batch_control'
5
+ require 'headache/record/file_control'
6
+ require 'headache/record/overflow'
@@ -0,0 +1,3 @@
1
+ module Headache
2
+ VERSION = "0.1.0"
3
+ end
data/lib/headache.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'fixy'
2
+
3
+ require 'active_support/concern'
4
+ require 'active_support/core_ext/string'
5
+ require 'active_support/core_ext/enumerable'
6
+
7
+ require 'headache/formatters'
8
+ require 'headache/definitions'
9
+ require 'headache/records'
10
+ require 'headache/batch'
11
+ require 'headache/document'
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: headache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Payoff, Inc.
8
+ - Chris Bielinski
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-08-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fixy
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '4'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '4'
42
+ - !ruby/object:Gem::Dependency
43
+ name: faker
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.4'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.4'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.3'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.3'
70
+ - !ruby/object:Gem::Dependency
71
+ name: factory_girl
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '4.5'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '4.5'
84
+ - !ruby/object:Gem::Dependency
85
+ name: bundler
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.10'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.10'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rake
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '10.0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '10.0'
112
+ description: Take the pain out of building ACH files. Wraps the Fixy gem for building
113
+ fixed-with ACH files as specified by NACHA.
114
+ email:
115
+ - engineering@payoff.com
116
+ - cbielinski@payoff.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - ".gitignore"
122
+ - ".travis.yml"
123
+ - Gemfile
124
+ - README.md
125
+ - Rakefile
126
+ - bin/console
127
+ - bin/setup
128
+ - headache.gemspec
129
+ - lib/headache.rb
130
+ - lib/headache/batch.rb
131
+ - lib/headache/definition/batch_control.rb
132
+ - lib/headache/definition/batch_header.rb
133
+ - lib/headache/definition/common.rb
134
+ - lib/headache/definition/entry.rb
135
+ - lib/headache/definition/file_control.rb
136
+ - lib/headache/definition/file_header.rb
137
+ - lib/headache/definitions.rb
138
+ - lib/headache/document.rb
139
+ - lib/headache/formatters.rb
140
+ - lib/headache/record/batch_control.rb
141
+ - lib/headache/record/batch_header.rb
142
+ - lib/headache/record/entry.rb
143
+ - lib/headache/record/file_control.rb
144
+ - lib/headache/record/file_header.rb
145
+ - lib/headache/record/overflow.rb
146
+ - lib/headache/records.rb
147
+ - lib/headache/version.rb
148
+ homepage: https://github.com/teampayoff/headache
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 2.4.8
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: Take the pain out of building ACH files.
172
+ test_files: []