wage_slave 2.0.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: 24c6b5c6e8da902e4fa340e8fee0286950d7f657
4
+ data.tar.gz: 0a0e36576e6218da70432406087466458a64acf3
5
+ SHA512:
6
+ metadata.gz: e69be9f0670ea23e89440be5fac0ad0fb1cd4bf0bf6bee471d073ea8cbfd3d6c8844ad154023682b0efb186b75ad7e823b0d3677e2d2e92f8af9608112359a4f
7
+ data.tar.gz: bf29ce045b85eafddbd8b495b8083102d617f3d864f3a12b04dbc481bbeb6b91c5cae0f6d3e76eb20829b34e5c90e945e3b436efad65692e8158891cccdf6fdf
data/.env.example ADDED
@@ -0,0 +1,5 @@
1
+ ## NO YELLING XERO DEMO KEYS
2
+ DEMO_XERO_CONSUMER_KEY=""
3
+ DEMO_XERO_CONSUMER_SECRET=""
4
+ ## NO YELLING XERO KEYS
5
+ XERO_PEM_FILE_LOCATION="privatekey.pem"
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .ruby-version
11
+ .ruby-gemset
12
+ *.tmp
13
+ *.swp
14
+ *.swo
15
+ *~
16
+ .DS_Store
17
+ .env
18
+ *.pem
19
+ .idea
20
+ .idea/**/*
21
+ .idea/*
22
+ .gem
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wage_slave.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 mesge
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # WageSlave
2
+ [![Build Status](https://travis-ci.org/noyelling/wage_slave.png)](https://travis-ci.org/noyelling/wage_slave)
3
+
4
+ A toolkit for generating and working with bulk payment files in various banking formats.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'wage_slave'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle install
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install wage_slave
21
+
22
+ ## Formats
23
+
24
+ WageSlave can generate payment files in the following formats:
25
+
26
+ ### Available
27
+
28
+ 1. [ABA / Cemtext](https://www.cemtexaba.com/aba-format) (Australian Banks)
29
+
30
+ ### Coming soon
31
+
32
+ 1. [NZ-DE](http://help.westpac.com.au/help/content/col/documents/pdfs/olpimportnzde.pdf) (New Zealand Direct Entry File Format)
33
+ 2. [IB4B](https://www.bnz.co.nz/assets/business-banking-help-support/internet-banking/ib4b-file-format-guide.pdf) (Bank of New Zealand)
34
+ 3. More...
35
+
36
+ ## Usage
37
+
38
+ Configure your application with information relating to your financial institution. For Rails applications this should be kept in
39
+ an initializer. Keep this information secure and out of version control.
40
+
41
+ ### Configuration
42
+
43
+ ```ruby
44
+ WageSlave.configure do | config |
45
+ config.financial_institution = "ANZ" # Name of your bank
46
+ config.bank_code = "123-456" # i.e. BSB, Sort code etc
47
+ config.user_id = "12345678" # i.e. CRN, Acc no. etc
48
+ config.description = "A default description for all WageSlave transactions"
49
+ config.user_name = "Username"
50
+ end
51
+ ```
52
+
53
+ ### ABA / Cemtext
54
+
55
+ A bulk payment file that works with most Australian banks.
56
+
57
+ ```ruby
58
+
59
+ # Build individual transactions
60
+ transactions = [
61
+ { name: "John Doe", account_number: "12345678", bsb: "999-999", amount: 5000 },
62
+ { name: "Jane Doe", account_number: "87654321", bsb: "999-999", amount: 6000 }
63
+ ]
64
+
65
+ # Create an ABA object
66
+ aba = WageSlave::ABA.new(transactions)
67
+
68
+ # Print in ABA format
69
+ # Validation errors will raise a RuntimeError when calling #to_s on an ABA object.
70
+ aba.to_s
71
+
72
+ ```
73
+
74
+ ## Development
75
+
76
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `ruby bin/console` for an interactive prompt that will allow you to experiment.
77
+
78
+ ## Contributing
79
+
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/noyelling/wage_slave.
81
+
82
+ ## License
83
+
84
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
85
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'spec'
6
+ t.pattern = "spec/*_spec.rb"
7
+ t.test_files = FileList['spec/wage_slave/services/*_spec.rb', 'spec/wage_slave/*_spec.rb', 'spec/wage_slave/aba/*_spec.rb' ]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "wage_slave"
5
+ require 'dotenv'
6
+
7
+ Dotenv.load
8
+
9
+ # Configure Application with Demo API Keys
10
+ WageSlave.configure do | config |
11
+ config.financial_institution = "ANZ"
12
+ config.bank_code = "123-456"
13
+ config.account_number = "12345678"
14
+ config.user_id = "000001"
15
+ config.description = "PAYROLL"
16
+ config.user_name = "No Yelling"
17
+ end
18
+
19
+ # You can add fixtures and/or initialization code here to make experimenting
20
+ # with your gem easier. You can also use a different console, if you like.
21
+
22
+ # (If you use this, don't forget to add pry to your Gemfile!)
23
+ # require "pry"
24
+ # Pry.start
25
+
26
+ require "irb"
27
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/wage_slave.rb ADDED
@@ -0,0 +1,16 @@
1
+ # Require config
2
+ require 'wage_slave/configuration'
3
+
4
+ # Require validation base
5
+ require 'wage_slave/validation'
6
+
7
+ # Require modules
8
+ require 'wage_slave/aba'
9
+ require 'wage_slave/aba/record'
10
+ require 'wage_slave/aba/detail_collection'
11
+ require 'wage_slave/aba/descriptive_record'
12
+ require 'wage_slave/aba/detail_record'
13
+
14
+ # Require validators
15
+ require 'wage_slave/validators/detail_record_validator'
16
+ require 'wage_slave/validators/descriptive_record_validator'
@@ -0,0 +1,75 @@
1
+ module WageSlave
2
+ class ABA
3
+
4
+ attr_reader :descriptive_record, :details
5
+
6
+ def initialize(transactions = [])
7
+ @descriptive_record = WageSlave::ABA::DescriptiveRecord.new
8
+ @details = WageSlave::ABA::DetailCollection.new(transactions)
9
+ end
10
+
11
+ ##
12
+ # This method was adapted from https://github.com/andrba/aba which is released under MIT.
13
+ # See /LICENSE.txt for details.
14
+
15
+ def to_s
16
+ output = @descriptive_record.to_s + "\r\n"
17
+ output += @details.to_s + "\r\n"
18
+
19
+ # Record Type
20
+ # Size: 1
21
+ # Char position: 1
22
+ # Must be 7
23
+ output += "7"
24
+
25
+ # BSB format filler
26
+ # Size: 7
27
+ # Char position: 2-8
28
+ # Must be 999-999
29
+ output += "999-999"
30
+
31
+ # Reserved
32
+ # Size: 12
33
+ # Char position: 9-20
34
+ # Blank filled
35
+ output += " " * 12
36
+
37
+ # Net total amount
38
+ # Size: 10
39
+ # Char position: 21-30
40
+ # Right justified, zero filled.
41
+ output += @details.net_total.abs.to_s.rjust(10, "0")
42
+
43
+ # Credit total amount
44
+ # Size: 10
45
+ # Char position: 31-40
46
+ # Right justified, zero filled.
47
+ output += @details.credit_total.abs.to_s.rjust(10, "0")
48
+
49
+ # Debit total amount
50
+ # Size: 10
51
+ # Char position: 41-50
52
+ # Right justified, zero filled.
53
+ output += @details.debit_total.abs.to_s.rjust(10, "0")
54
+
55
+ # Reserved
56
+ # Size: 24
57
+ # Char position: 51-74
58
+ # Blank filled
59
+ output += " " * 24
60
+
61
+ # Count of Type 1 records
62
+ # Size: 6
63
+ # Char position: 75-80
64
+ # Right justified, zero filled.
65
+ output += @details.size.to_s.rjust(6, "0")
66
+
67
+ # Reserved
68
+ # Size: 40
69
+ # Char position: 81-120
70
+ # Blank filled
71
+ output += " " * 40
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,97 @@
1
+ module WageSlave
2
+ class ABA
3
+ class DescriptiveRecord < WageSlave::ABA::Record
4
+
5
+ include WageSlave::Validation
6
+
7
+ ##
8
+ # Reel sequence becomes important for payment runs of multiple ABA files.
9
+ # It is incremented each time a descriptive record is created.
10
+
11
+ @@reel_sequence = 0
12
+
13
+ attr_reader :bsb, :financial_institution, :user_name, :user_id, :description, :process_at, :reel_sequence
14
+
15
+ def initialize(attrs = {})
16
+ @type = "0"
17
+ @bsb = WageSlave.configuration.bank_code
18
+ @financial_institution = WageSlave.configuration.financial_institution
19
+ @user_name = WageSlave.configuration.user_name
20
+ @user_id = WageSlave.configuration.user_id
21
+ @description = WageSlave.configuration.description
22
+ @process_at = attrs[:process_at] || Date.today
23
+
24
+ # Bump reel sequence number.
25
+ @reel_sequence = '%02d' % @@reel_sequence+=1
26
+ end
27
+
28
+ ##
29
+ # This method was adapted from https://github.com/andrba/aba which is released under MIT.
30
+ # See /LICENSE.txt for details.
31
+
32
+ def to_s
33
+ raise RuntimeError.new "Descriptive record is invalid. Check the contents of 'errors'" unless self.valid?
34
+
35
+ # Record type
36
+ # Size: 1
37
+ # Char position: 1
38
+ # Must be 0
39
+ output = @type
40
+
41
+ # Optional branch number of the funds account
42
+ # Char position: 2-18
43
+ # Size: 17
44
+ # Format: XXX-XXX
45
+ # Blank filled
46
+ output += @bsb.nil? ? " " * 17 : @bsb.to_s.ljust(17)
47
+
48
+ # Sequence number
49
+ # Char position: 19-20
50
+ # Size: 2
51
+ # Zero padded
52
+ output += @reel_sequence
53
+
54
+ # Name of user financial instituion
55
+ # Size: 3
56
+ # Char position: 21-23
57
+ output += @financial_institution.to_s
58
+
59
+ # Reserved
60
+ # Size: 7
61
+ # Char position: 24-30
62
+ output += " " * 7
63
+
64
+ # Name of User supplying File
65
+ # Char position: 31-56
66
+ # Size: 26
67
+ # Full BECS character set valid
68
+ # Blank filled
69
+ output += @user_name.to_s.ljust(26)
70
+
71
+ # Direct Entry User ID
72
+ # Char position: 57-62
73
+ # Size: 6
74
+ # Zero padded
75
+ output += @user_id.to_s.rjust(6, "0")
76
+
77
+ # Description of payments in the file (e.g. Payroll, Creditors etc.)
78
+ # Char position: 63-74
79
+ # Size: 12
80
+ # Full BECS character set valid
81
+ # Blank filled
82
+ output += @description.to_s.ljust(12)
83
+
84
+ # Date on which the payment is to be processed
85
+ # Char position: 75-80
86
+ # Size: 6
87
+ output += @process_at.strftime("%d%m%y")
88
+
89
+ # Reserved
90
+ # Size: 40
91
+ # Char position: 81-120
92
+ output += " " * 40
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,33 @@
1
+ module WageSlave
2
+ class ABA
3
+ class DetailCollection < Array
4
+
5
+ def initialize(details = [])
6
+ self.concat(
7
+ details.map { |d| WageSlave::ABA::DetailRecord.new(d) }
8
+ )
9
+ end
10
+
11
+ def net_total
12
+ self.credit_total + self.debit_total
13
+ end
14
+
15
+ def credit_total
16
+ self
17
+ .select { |d| d.amount > 0 }
18
+ .reduce(0) { |acc, n| acc + n.amount }
19
+ end
20
+
21
+ def debit_total
22
+ self
23
+ .select { |d| d.amount < 0 }
24
+ .reduce(0) { |acc, n| acc + n.amount }
25
+ end
26
+
27
+ def to_s
28
+ self.map(&:to_s).join("\r\n")
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,145 @@
1
+ module WageSlave
2
+ class ABA
3
+ class DetailRecord < WageSlave::ABA::Record
4
+
5
+ include WageSlave::Validation
6
+
7
+ # Key Value
8
+ # ===========
9
+ # "N" For new or varied Bank/State/Branch number or name details, otherwise blank filled.
10
+ #
11
+ # Withholding Tax Indicators
12
+ # ==========================
13
+ # "W" Dividend paid to a resident of a country where a double tax agreement is in force.
14
+ # "X" Dividend paid to a resident of any other country.
15
+ # "Y" Interest paid to all non-residents.
16
+
17
+ @@indicators = Set.new ["N", "W", "X", "Y"]
18
+
19
+ # Code Transaction Description
20
+ # =============================
21
+ # 13 Externally initiated debit items
22
+ # 50 Externally initiated credit items with the exception of those bearing Transaction Codes
23
+ # 51 Australian Government Security Interest
24
+ # 52 Family Allowance
25
+ # 53 Pay
26
+ # 54 Pension
27
+ # 55 Allotment
28
+ # 56 Dividend
29
+ # 57 Debenture/Note Interest
30
+
31
+ @@transaction_codes = Set.new [
32
+ "13", "50", "51", "52", "53", "54", "55", "56", "57"
33
+ ]
34
+
35
+ attr_reader :bsb, :account_number, :indicator, :transaction_code, :amount, :name,
36
+ :lodgement_reference, :trace_bsb, :trace_account, :remitter, :witholding_amount
37
+
38
+ def initialize(attrs={})
39
+ @type = "1"
40
+ @bsb = attrs[:bsb]
41
+ @account_number = attrs[:account_number]
42
+ self.indicator = attrs[:indicator] || "N"
43
+ self.transaction_code = attrs[:transaction_code] || "53"
44
+ @amount = attrs[:amount] || 0
45
+ @name = attrs[:name]
46
+ @lodgement_reference = attrs[:lodgement_reference] || WageSlave.configuration.user_name
47
+ @trace_bsb = attrs[:trace_bsb] || WageSlave.configuration.bank_code
48
+ @trace_account = attrs[:trace_account] || WageSlave.configuration.account_number
49
+ @remitter = attrs[:remitter] || WageSlave.configuration.user_name
50
+ @witholding_amount = attrs[:tax_withholding] || 0
51
+ end
52
+
53
+ def transaction_code=(code)
54
+ @transaction_code = code if @@transaction_codes.include? code
55
+ end
56
+
57
+ def indicator=(key)
58
+ @indicator = key if @@indicators.include? key
59
+ end
60
+
61
+ ##
62
+ # This method was adapted from https://github.com/andrba/aba which is released under MIT.
63
+ # See /LICENSE.txt for details.
64
+
65
+ def to_s
66
+ raise RuntimeError.new "Detail record is invalid. Check the contents of 'errors'" unless self.valid?
67
+
68
+ # Record type
69
+ # Size: 1
70
+ # Char position: 1
71
+ # Must be 1
72
+ output = @type
73
+
74
+ # BSB of account
75
+ # Size: 7
76
+ # Char position: 2-8
77
+ # Format: XXX-XXX
78
+ output += @bsb.to_s
79
+
80
+ # Account number
81
+ # Size: 9
82
+ # Char position: 9-17
83
+ # Blank filled, right justified.
84
+ output += @account_number.to_s.rjust(9, " ")
85
+
86
+ # Indicator
87
+ # Size: 1
88
+ # Char position: 18
89
+ # Valid entries: N, W, X or Y.
90
+ output += @indicator.to_s.ljust(1, " ")
91
+
92
+ # Transaction Code
93
+ # Size: 2
94
+ # Char position: 19-20
95
+ output += @transaction_code.to_s
96
+
97
+ # Amount to be credited or debited
98
+ # Size: 10
99
+ # Char position: 21-30
100
+ # Numeric only, shown in cents. Right justified, zero filled.
101
+ output += @amount.to_i.abs.to_s.rjust(10, "0")
102
+
103
+ # Title of Account
104
+ # Full BECS character set valid
105
+ # Size: 32
106
+ # Char position: 31-62
107
+ # Blank filled, left justified.
108
+ output += @name.to_s.ljust(32, " ")
109
+
110
+ # Lodgement Reference Produced on the recipient’s Account Statement.
111
+ # Size: 18
112
+ # Char position: 63-80
113
+ # Full BECS character set valid
114
+ # Blank filled, left justified.
115
+ output += @lodgement_reference.to_s.ljust(18, " ")
116
+
117
+ # Trace BSB Number
118
+ # Size: 7
119
+ # Char position: 81-87
120
+ # Format: XXX-XXX
121
+ output += @trace_bsb.to_s
122
+
123
+ # Trace Account Number
124
+ # Size: 9
125
+ # Char position: 88-96
126
+ # Blank filled, right justified.
127
+ output += @trace_account.to_s.rjust(9, " ")
128
+
129
+ # Name of Remitter Produced on the recipient’s Account Statement
130
+ # Size: 16
131
+ # Char position: 97-112
132
+ # Full BECS character set valid
133
+ # Blank filled, left justified.
134
+ output += @remitter.to_s.ljust(16, " ")
135
+
136
+ # Withholding amount in cents
137
+ # Size: 8
138
+ # Char position: 113-120
139
+ # Numeric only, shown in cents. Right justified, zero filled.
140
+ output += @witholding_amount.abs.to_s.rjust(8, "0")
141
+ end
142
+
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,9 @@
1
+ module WageSlave
2
+ class ABA
3
+ class Record
4
+
5
+ attr_reader :type
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ module WageSlave
2
+
3
+ ##
4
+ # Configuration for WageSlave
5
+ #
6
+ # @financial_institution is your bank
7
+ # @bank_code is your BSB for Australian banks
8
+ # @user_id is your banking account ID
9
+ # @description is the default description for transactions
10
+
11
+ class Configuration
12
+ attr_accessor :financial_institution, :bank_code, :user_id, :user_name, :account_number, :description
13
+
14
+ def initialize
15
+ @financial_institution = nil
16
+ @bank_code = nil
17
+ @account_number = nil
18
+ @user_id = "000001"
19
+ @user_name = nil
20
+ @description = "Payroll"
21
+ end
22
+
23
+ end
24
+
25
+ ##
26
+ # Simple way to configure WageSlave
27
+ # WageSlave.configure do | config |
28
+ # config.bank_code = "123-234"
29
+ # end
30
+
31
+ class << self
32
+ attr_writer :configuration
33
+
34
+ def configuration
35
+ @configuration ||= Configuration.new
36
+ end
37
+
38
+ def reset
39
+ @configuration = Configuration.new
40
+ end
41
+
42
+ def configure
43
+ yield(configuration)
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,98 @@
1
+ # A module mixin for simple Ruby data validation. No Rails needed. Basic, but highly extentable with different kinds of
2
+ # validators. You can create new validation types by adding to the case statement on line 77, and adding an accompanying
3
+ # method.
4
+
5
+ module WageSlave
6
+
7
+ module Validation
8
+ def valid?
9
+ klass = Object.const_get("#{self.class.name}Validator")
10
+ @validator = klass.new(self)
11
+ @validator.valid?
12
+ end
13
+
14
+ def errors
15
+ return {} unless defined?(@validator)
16
+ @validator.errors
17
+ end
18
+ end
19
+
20
+ class ValidationErrors
21
+ attr_accessor :all
22
+
23
+ def initialize
24
+ @all = {}
25
+ end
26
+
27
+ def add(name, msg)
28
+ (@all[name] ||= []) << msg
29
+ end
30
+
31
+ def full_messages
32
+ @all.map do |e|
33
+ "#{e.first.capitalize} #{e.last.join(' & ')}. "
34
+ end.join
35
+ end
36
+ end
37
+
38
+ module Validate
39
+ def self.included(base)
40
+ base.send(:include, InstanceMethods)
41
+ base.extend(ClassMethods)
42
+ end
43
+
44
+ module InstanceMethods
45
+ attr_reader :object, :errors
46
+
47
+ def initialize(object)
48
+ @object = object
49
+ @errors = ValidationErrors.new
50
+ end
51
+
52
+ def valid?
53
+ self.class.validators.each { |args| validate(args) }
54
+ @errors.all.empty?
55
+ end
56
+
57
+ private
58
+
59
+ def validate(args)
60
+ case
61
+ when args[1].key?(:with)
62
+ with_validator(*args)
63
+ when args[1].key?(:type)
64
+ type_validator(*args)
65
+ end
66
+ end
67
+
68
+ def with_validator(name, options)
69
+ fail unless options[:with].call(@object)
70
+ rescue
71
+ @errors.add(name, options[:msg])
72
+ end
73
+
74
+ def type_validator(name, options)
75
+ return if @object.send(name).is_a?(options[:type])
76
+ @errors.add(name, "must be a #{options[:type].name}")
77
+ end
78
+ end
79
+
80
+ module ClassMethods
81
+ def validates(*args)
82
+ create_validation(args)
83
+ end
84
+
85
+ def validators
86
+ @validators
87
+ end
88
+
89
+ private
90
+
91
+ def create_validation(args)
92
+ @validators = [] unless defined?(@validators)
93
+ @validators << args
94
+ end
95
+ end
96
+ end
97
+
98
+ end
@@ -0,0 +1,41 @@
1
+ module WageSlave
2
+ class ABA
3
+ class DescriptiveRecordValidator
4
+
5
+ include WageSlave::Validate
6
+
7
+ validates :type,
8
+ with: proc { |p| p.type === "0" },
9
+ msg: "must be '0'"
10
+
11
+ validates :bsb,
12
+ with: proc { |p| p.bsb.nil? ? true : p.bsb.to_s =~ /^\d{3}-\d{3}$/ },
13
+ msg: "is not in the required format (xxx-xxx)"
14
+
15
+ validates :financial_institution,
16
+ with: proc { |p| p.financial_institution.to_s.length === 3 },
17
+ msg: "must be valid 3 character abbreviation of an Australian financial institution"
18
+
19
+ validates :user_name,
20
+ with: proc { |p| p.user_name.to_s.length <= 26 },
21
+ msg: "must not exceed 26 characters"
22
+
23
+ validates :user_id,
24
+ with: proc { |p| p.user_id.to_s =~ /^\d{6}$/ },
25
+ msg: "must not exceed 6 characters and may only be numeric"
26
+
27
+ validates :description,
28
+ with: proc { |p| p.description.to_s.length <= 12 },
29
+ msg: "must not exceed 12 characters"
30
+
31
+ validates :process_at,
32
+ with: proc { |p| p.process_at.is_a? Date },
33
+ msg: "must be an instance of Date"
34
+
35
+ validates :reel_sequence,
36
+ with: proc { |p| p.reel_sequence =~ /^\d{2}$/ },
37
+ msg: "must be 2 digits up to 99"
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,57 @@
1
+ module WageSlave
2
+ class ABA
3
+ class DetailRecordValidator
4
+
5
+ include WageSlave::Validate
6
+
7
+ validates :type,
8
+ with: proc { |p| p.type === '1' },
9
+ msg: "must be '1'"
10
+
11
+ validates :bsb,
12
+ with: proc { |p| p.bsb =~ /^\d{3}-\d{3}$/ },
13
+ msg: "is not in the required format (xxx-xxx)"
14
+
15
+ validates :account_number,
16
+ with: proc { |p| p.account_number.to_s =~ /^[\d\- ]{1,9}$/ && p.account_number !~ /^0*$/ },
17
+ msg: "not a valid account number"
18
+
19
+ validates :indicator,
20
+ type: String,
21
+ msg: "must be defined as a String"
22
+
23
+ validates :transaction_code,
24
+ type: String,
25
+ msg: "must be defined as a String"
26
+
27
+ validates :amount,
28
+ with: proc { |p| p.amount > 0 && p.amount <= 9_999_999_999 },
29
+ msg: "must be greater than 0 and less than 10,000,000,000"
30
+
31
+ validates :name,
32
+ with: proc { |p| p.name.to_s.length > 0 && p.name.to_s.length <= 32 },
33
+ msg: "is required and must not be longer than 32 characters"
34
+
35
+ validates :lodgement_reference,
36
+ with: proc { |p| p.lodgement_reference.to_s.length > 0 && p.lodgement_reference.to_s.length <= 18 },
37
+ msg: "is required and must not be longer than 18 characters"
38
+
39
+ validates :trace_bsb,
40
+ with: proc { |p| p.trace_bsb =~ /^\d{3}-\d{3}$/ },
41
+ msg: "is not in the required format (xxx-xxx)"
42
+
43
+ validates :trace_account,
44
+ with: proc { |p| p.trace_account.to_s =~ /^[\d\- ]{1,9}$/ && p.trace_account !~ /^0*$/ },
45
+ msg: "not a valid account number"
46
+
47
+ validates :remitter,
48
+ with: proc { |p| p.remitter.to_s.length > 0 && p.remitter.to_s.length <= 16 },
49
+ msg: "is required and must not be longer than 16 characters"
50
+
51
+ validates :witholding_amount,
52
+ with: proc { |p| p.witholding_amount <= 99_999_999 },
53
+ msg: "must be less than 100,000,000"
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module WageSlave
2
+ VERSION = "2.0.0"
3
+ end
data/travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wage_slave/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wage_slave"
8
+ spec.version = WageSlave::VERSION
9
+ spec.authors = ["James Gemmell", "Jasper Boyschau"]
10
+ spec.email = ["dev@noyelling.com.au"]
11
+
12
+ spec.summary = %q{Generate ABA, NZ-DE and IB4B direct entry files.}
13
+ spec.description = %q{A toolkit for generating and working with bulk payment files in various banking formats.}
14
+ spec.homepage = "http://github.com/noyelling/wage_slave"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ spec.add_development_dependency "mocha", "~> 1.1"
26
+ spec.add_development_dependency "dotenv", "~> 2.1"
27
+ spec.add_development_dependency "minitest-reporters", "~> 1.1"
28
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wage_slave
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - James Gemmell
8
+ - Jasper Boyschau
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2016-08-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.11'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.11'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: minitest
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '5.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '5.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mocha
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.1'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.1'
70
+ - !ruby/object:Gem::Dependency
71
+ name: dotenv
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '2.1'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '2.1'
84
+ - !ruby/object:Gem::Dependency
85
+ name: minitest-reporters
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.1'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.1'
98
+ description: A toolkit for generating and working with bulk payment files in various
99
+ banking formats.
100
+ email:
101
+ - dev@noyelling.com.au
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".env.example"
107
+ - ".gitignore"
108
+ - ".travis.yml"
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - bin/console
114
+ - bin/setup
115
+ - lib/wage_slave.rb
116
+ - lib/wage_slave/aba.rb
117
+ - lib/wage_slave/aba/descriptive_record.rb
118
+ - lib/wage_slave/aba/detail_collection.rb
119
+ - lib/wage_slave/aba/detail_record.rb
120
+ - lib/wage_slave/aba/record.rb
121
+ - lib/wage_slave/configuration.rb
122
+ - lib/wage_slave/validation.rb
123
+ - lib/wage_slave/validators/descriptive_record_validator.rb
124
+ - lib/wage_slave/validators/detail_record_validator.rb
125
+ - lib/wage_slave/version.rb
126
+ - travis.yml
127
+ - wage_slave.gemspec
128
+ homepage: http://github.com/noyelling/wage_slave
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.4.8
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Generate ABA, NZ-DE and IB4B direct entry files.
152
+ test_files: []