aba 0.4.0 → 1.0.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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +3 -4
- data/CHANGELOG.md +20 -0
- data/README.md +31 -10
- data/aba.gemspec +3 -4
- data/lib/aba.rb +2 -0
- data/lib/aba/batch.rb +36 -29
- data/lib/aba/entry.rb +17 -0
- data/lib/aba/return.rb +71 -0
- data/lib/aba/transaction.rb +4 -40
- data/lib/aba/validations.rb +12 -2
- data/lib/aba/version.rb +1 -1
- data/spec/lib/aba/batch_spec.rb +95 -25
- data/spec/lib/aba/return_spec.rb +67 -0
- data/spec/lib/aba/transaction_spec.rb +26 -13
- data/spec/lib/aba/validations_spec.rb +14 -16
- data/spec/spec_helper.rb +1 -0
- metadata +16 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2156c80e41e17a9df07891a515adff66f0b41412dd83897067a5faa1a598e956
|
4
|
+
data.tar.gz: 853deb00316a156169fd1dbc81b5cea3b666122ff538fc61646fedb5bf44d15a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccb0516b85f0b70af8374f8ef4a3f3effe157dcd19296283a2c274359926e567a9bf7120aad3cf784b4ae027f8bf9e4835edc3c02805d10ebca50d6feec4639e
|
7
|
+
data.tar.gz: fbce1803cff67a9bbff99f6c91720b05e20fc62837e39f6d170438b3f6e3d47972b2f24dcf969788487b65078b0822570f488541091847ae8238d8e9eb7542fd
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
## V1.0.1, 11 January 2021
|
2
|
+
|
3
|
+
### BUG FIX
|
4
|
+
|
5
|
+
Account numbers/alphas validation should be case insensitive
|
6
|
+
|
7
|
+
## v1.0.0, 12 July 2020
|
8
|
+
|
9
|
+
### BREAKING CHANGES
|
10
|
+
|
11
|
+
* Positive (`n`) and negative (`-n`) values are now treated the same.
|
12
|
+
e.g `5` and `-5` are both processed as `5`, without any signage.
|
13
|
+
To differentiate between a debit and credit, use the correct [Transaction Code](https://github.com/andrba/aba/blob/58446f5b0ef822e9792e9399b4af647319b13515/lib/aba/transaction.rb#L106-L112)
|
14
|
+
* Removed default values for transactions records to avoid generation of potentially incorrect records. Safety first!
|
15
|
+
* Minimum Ruby version is now 2.5
|
16
|
+
|
17
|
+
### NEW FEATURE
|
18
|
+
|
19
|
+
* You can now add a *return* record to be used when you'd like to return
|
20
|
+
a credit or a debit to another financial institution (OFI).
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ aba = Aba.batch(
|
|
19
19
|
process_at: Time.now.strftime("%d%m%y")
|
20
20
|
)
|
21
21
|
|
22
|
-
# Add transactions
|
22
|
+
# Add transactions...
|
23
23
|
10.times do
|
24
24
|
aba.add_transaction(
|
25
25
|
{
|
@@ -36,6 +36,26 @@ aba = Aba.batch(
|
|
36
36
|
)
|
37
37
|
end
|
38
38
|
|
39
|
+
# ...or add returns
|
40
|
+
10.times do
|
41
|
+
aba.add_return(
|
42
|
+
{
|
43
|
+
bsb: '453-543',
|
44
|
+
account_number: '45656733',
|
45
|
+
amount: 10000,
|
46
|
+
account_name: 'John Doe',
|
47
|
+
transaction_code: 53,
|
48
|
+
lodgement_reference: 'R435564',
|
49
|
+
trace_bsb: '342-342',
|
50
|
+
trace_account_number: '3244654',
|
51
|
+
name_of_remitter: 'Remitter',
|
52
|
+
return_code: 8,
|
53
|
+
original_user_id: 654321,
|
54
|
+
original_processing_day: 12,
|
55
|
+
}
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
39
59
|
puts aba.to_s # View output
|
40
60
|
File.write("/Users/me/dd_#{Time.now.to_i}.aba", aba.to_s) # or write output to file
|
41
61
|
```
|
@@ -45,28 +65,29 @@ There are a few ways to create a complete set of ABA data:
|
|
45
65
|
```ruby
|
46
66
|
# Transactions added to the defined ABA object variable
|
47
67
|
aba = Aba.batch financial_institution: 'ANZ', user_name: 'Joe Blow', user_id: 123456, process_at: 200615
|
48
|
-
aba.add_transaction bsb: '123-456', account_number: '000-123-456', amount: 50000
|
49
|
-
aba.add_transaction bsb: '456-789', account_number: '123-456-789', amount:
|
68
|
+
aba.add_transaction bsb: '123-456', account_number: '000-123-456', amount: 50000, transaction_code: 50
|
69
|
+
aba.add_transaction bsb: '456-789', account_number: '123-456-789', amount: 10000, transaction_code: 13
|
50
70
|
|
51
71
|
# Transactions passed individually inside a block
|
52
72
|
aba = Aba.batch financial_institution: 'ANZ', user_name: 'Joe Blow', user_id: 123456, process_at: 200615 do |a|
|
53
|
-
a.add_transaction bsb: '123-456', account_number: '000-123-456', amount: 50000
|
54
|
-
a.add_transaction bsb: '456-789', account_number: '123-456-789', amount:
|
73
|
+
a.add_transaction bsb: '123-456', account_number: '000-123-456', amount: 50000, transaction_code: 50
|
74
|
+
a.add_transaction bsb: '456-789', account_number: '123-456-789', amount: 10000, transaction_code: 13
|
55
75
|
end
|
56
76
|
|
57
77
|
# Transactions as an array passed to the second param of Aba.batch
|
58
78
|
aba = Aba.batch(
|
59
79
|
{ financial_institution: 'ANZ', user_name: 'Joe Blow', user_id: 123456, process_at: 200615 },
|
60
80
|
[
|
61
|
-
{ bsb: '123-456', account_number: '000-123-456', amount: 50000 },
|
62
|
-
{ bsb: '456-789', account_number: '123-456-789', amount:
|
81
|
+
{ bsb: '123-456', account_number: '000-123-456', amount: 50000, transaction_code: 50 },
|
82
|
+
{ bsb: '456-789', account_number: '123-456-789', amount: 10000, transaction_code: 13 }
|
63
83
|
]
|
64
84
|
)
|
65
|
-
|
66
|
-
# NOTE: Be careful with negative transaction amounts! transaction_code will not
|
67
|
-
# be set to debit automatically!
|
68
85
|
```
|
69
86
|
|
87
|
+
> **Note:** Positive (`n`) and negative (`-n`) values are now treated the same.
|
88
|
+
> e.g `5` and `-5` are both processed as `5`, without any signage.
|
89
|
+
> To differentiate between a debit and credit, use the correct [Transaction Code](https://github.com/andrba/aba/blob/58446f5b0ef822e9792e9399b4af647319b13515/lib/aba/transaction.rb#L106-L112)
|
90
|
+
|
70
91
|
Validation errors can be caught in several ways:
|
71
92
|
|
72
93
|
```ruby
|
data/aba.gemspec
CHANGED
@@ -18,10 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "
|
22
|
-
spec.add_development_dependency "
|
23
|
-
spec.add_development_dependency "pry", "~> 0.10"
|
21
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
22
|
+
spec.add_development_dependency "pry", "~> 0.13"
|
24
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
25
24
|
|
26
|
-
spec.required_ruby_version = '>=
|
25
|
+
spec.required_ruby_version = '>= 2.5.0'
|
27
26
|
end
|
data/lib/aba.rb
CHANGED
data/lib/aba/batch.rb
CHANGED
@@ -2,7 +2,7 @@ class Aba
|
|
2
2
|
class Batch
|
3
3
|
include Aba::Validations
|
4
4
|
|
5
|
-
attr_accessor :bsb, :financial_institution, :user_name, :user_id, :description, :process_at, :
|
5
|
+
attr_accessor :bsb, :financial_institution, :user_name, :user_id, :description, :process_at, :entries
|
6
6
|
|
7
7
|
# BSB
|
8
8
|
validates_bsb :bsb, allow_blank: true
|
@@ -34,8 +34,7 @@ class Aba
|
|
34
34
|
send("#{key}=", value)
|
35
35
|
end
|
36
36
|
|
37
|
-
@
|
38
|
-
@transactions = {}
|
37
|
+
@entries = []
|
39
38
|
|
40
39
|
unless transactions.nil? || transactions.empty?
|
41
40
|
transactions.to_a.each do |t|
|
@@ -47,56 +46,63 @@ class Aba
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def to_s
|
50
|
-
raise RuntimeError, 'No
|
49
|
+
raise RuntimeError, 'No entries present - add one using `add_transaction` or `add_return`' if entries.empty?
|
51
50
|
raise RuntimeError, 'ABA data is invalid - check the contents of `errors`' unless valid?
|
52
51
|
|
53
52
|
# Descriptive record
|
54
53
|
output = "#{descriptive_record}\r\n"
|
55
54
|
|
56
55
|
# Transactions records
|
57
|
-
output +=
|
56
|
+
output += entries.map { |t| t.to_s }.join("\r\n")
|
58
57
|
|
59
58
|
# Batch control record
|
60
59
|
output += "\r\n#{batch_control_record}"
|
61
60
|
end
|
62
61
|
|
63
62
|
def add_transaction(attrs = {})
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
add_entry(Aba::Transaction, attrs)
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_return(attrs = {})
|
67
|
+
add_entry(Aba::Return, attrs)
|
68
|
+
end
|
69
|
+
|
70
|
+
def transactions
|
71
|
+
entries.select { |entry| entry.instance_of?(Aba::Transaction) }
|
72
72
|
end
|
73
73
|
|
74
74
|
def transactions_valid?
|
75
|
-
!
|
75
|
+
!transactions.map { |t| t.valid? }.include?(false)
|
76
76
|
end
|
77
77
|
|
78
78
|
def valid?
|
79
|
-
!has_errors? &&
|
79
|
+
!has_errors? && !has_entry_errors?
|
80
80
|
end
|
81
81
|
|
82
82
|
def errors
|
83
83
|
# Run validations
|
84
84
|
has_errors?
|
85
|
-
|
85
|
+
has_entry_errors?
|
86
86
|
|
87
87
|
# Build errors
|
88
88
|
all_errors = {}
|
89
89
|
all_errors[:aba] = self.error_collection unless self.error_collection.empty?
|
90
|
-
|
91
|
-
all_errors[:
|
90
|
+
entry_error_collection = entries.each_with_index.map { |t, i| [i, t.error_collection] }.reject { |e| e[1].nil? || e[1].empty? }.to_h
|
91
|
+
all_errors[:entries] = entry_error_collection unless entry_error_collection.empty?
|
92
92
|
|
93
93
|
all_errors unless all_errors.empty?
|
94
94
|
end
|
95
95
|
|
96
96
|
private
|
97
97
|
|
98
|
-
def
|
99
|
-
|
98
|
+
def add_entry(type, attrs)
|
99
|
+
(attrs.instance_of?(type) ? attrs : type.new(attrs)).tap do |entry|
|
100
|
+
entries << entry
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def has_entry_errors?
|
105
|
+
entries.map { |t| t.valid? }.include?(false)
|
100
106
|
end
|
101
107
|
|
102
108
|
def descriptive_record
|
@@ -159,14 +165,15 @@ class Aba
|
|
159
165
|
end
|
160
166
|
|
161
167
|
def batch_control_record
|
162
|
-
net_total_amount = 0
|
163
168
|
credit_total_amount = 0
|
164
169
|
debit_total_amount = 0
|
165
170
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
171
|
+
entries.each do |entry|
|
172
|
+
if entry.debit?
|
173
|
+
debit_total_amount += Integer(entry.amount).abs
|
174
|
+
else
|
175
|
+
credit_total_amount += Integer(entry.amount).abs
|
176
|
+
end
|
170
177
|
end
|
171
178
|
|
172
179
|
# Record type
|
@@ -187,17 +194,17 @@ class Aba
|
|
187
194
|
# Net total
|
188
195
|
# Max: 10
|
189
196
|
# Char position: 21-30
|
190
|
-
output +=
|
197
|
+
output += (credit_total_amount - debit_total_amount).abs.to_s.rjust(10, "0")
|
191
198
|
|
192
199
|
# Credit Total Amount
|
193
200
|
# Max: 10
|
194
201
|
# Char position: 31-40
|
195
|
-
output += credit_total_amount.
|
202
|
+
output += credit_total_amount.to_s.rjust(10, "0")
|
196
203
|
|
197
204
|
# Debit Total Amount
|
198
205
|
# Max: 10
|
199
206
|
# Char position: 41-50
|
200
|
-
output += debit_total_amount.
|
207
|
+
output += debit_total_amount.to_s.rjust(10, "0")
|
201
208
|
|
202
209
|
# Reserved
|
203
210
|
# Max: 24
|
@@ -207,7 +214,7 @@ class Aba
|
|
207
214
|
# Total Item Count
|
208
215
|
# Max: 6
|
209
216
|
# Char position: 75-80
|
210
|
-
output +=
|
217
|
+
output += entries.size.to_s.rjust(6, "0")
|
211
218
|
|
212
219
|
# Reserved
|
213
220
|
# Max: 40
|
data/lib/aba/entry.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Aba
|
2
|
+
class Entry
|
3
|
+
def initialize(attrs = {})
|
4
|
+
attrs.each do |key, value|
|
5
|
+
send("#{key}=", value)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def credit?
|
10
|
+
Validations::CREDIT_TRANSACTION_CODES.include?(transaction_code.to_i)
|
11
|
+
end
|
12
|
+
|
13
|
+
def debit?
|
14
|
+
Validations::DEBIT_TRANSACTION_CODES.include?(transaction_code.to_i)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/aba/return.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
class Aba
|
2
|
+
class Return < Entry
|
3
|
+
include Aba::Validations
|
4
|
+
|
5
|
+
attr_accessor :account_number, :transaction_code, :amount, :account_name,
|
6
|
+
:bsb, :trace_bsb, :trace_account_number, :name_of_remitter,
|
7
|
+
:return_code, :lodgement_reference,
|
8
|
+
:original_processing_day, :original_user_id
|
9
|
+
|
10
|
+
# BSB
|
11
|
+
validates_bsb :bsb
|
12
|
+
|
13
|
+
# Account Number
|
14
|
+
validates_account_number :account_number
|
15
|
+
|
16
|
+
# Indicator
|
17
|
+
validates_return_code :return_code
|
18
|
+
|
19
|
+
# Transaction Code
|
20
|
+
validates_transaction_code :transaction_code
|
21
|
+
|
22
|
+
# Amount
|
23
|
+
validates_integer :amount
|
24
|
+
|
25
|
+
# Original Day of Processing
|
26
|
+
validates_integer :original_processing_day, :unsigned
|
27
|
+
|
28
|
+
# Original User Id
|
29
|
+
validates_max_length :original_user_id, 6
|
30
|
+
validates_integer :original_user_id, :unsigned
|
31
|
+
|
32
|
+
# Account Name
|
33
|
+
validates_max_length :account_name, 32
|
34
|
+
validates_becs :account_name
|
35
|
+
|
36
|
+
# Lodgement Reference
|
37
|
+
validates_max_length :lodgement_reference, 18
|
38
|
+
validates_becs :lodgement_reference
|
39
|
+
|
40
|
+
# Trace Record
|
41
|
+
validates_bsb :trace_bsb
|
42
|
+
validates_account_number :trace_account_number
|
43
|
+
|
44
|
+
# Name of Remitter
|
45
|
+
validates_max_length :name_of_remitter, 16
|
46
|
+
validates_becs :name_of_remitter
|
47
|
+
|
48
|
+
# Allow dashes to be input, but remove them from output
|
49
|
+
def account_number
|
50
|
+
@account_number ? @account_number.to_s.delete('-') : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
raise 'Transaction data is invalid - check the contents of `errors`' unless valid?
|
55
|
+
|
56
|
+
format('2%-7s%9s%1d%2d%010d%-32s%-18s%-7s%9s%-16s%02d%6s',
|
57
|
+
bsb,
|
58
|
+
account_number,
|
59
|
+
return_code,
|
60
|
+
transaction_code,
|
61
|
+
amount.to_i.abs,
|
62
|
+
account_name,
|
63
|
+
lodgement_reference,
|
64
|
+
trace_bsb,
|
65
|
+
trace_account_number,
|
66
|
+
name_of_remitter,
|
67
|
+
original_processing_day.to_i,
|
68
|
+
original_user_id)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/aba/transaction.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Aba
|
2
|
-
class Transaction
|
2
|
+
class Transaction < Entry
|
3
3
|
include Aba::Validations
|
4
4
|
|
5
5
|
attr_accessor :account_number, :transaction_code, :amount, :account_name,
|
@@ -37,57 +37,21 @@ class Aba
|
|
37
37
|
validates_max_length :name_of_remitter, 16
|
38
38
|
validates_becs :name_of_remitter
|
39
39
|
|
40
|
-
|
41
|
-
def initialize(attrs = {})
|
42
|
-
attrs.each do |key, value|
|
43
|
-
send("#{key}=", value)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
40
|
# Allow dashes to be input, but remove them from output
|
48
41
|
def account_number
|
49
42
|
@account_number ? @account_number.to_s.gsub('-', '') : nil
|
50
43
|
end
|
51
44
|
|
52
|
-
#
|
45
|
+
# Sane default for majority of use cases as per BECS
|
53
46
|
def indicator
|
54
|
-
@indicator ||
|
55
|
-
end
|
56
|
-
|
57
|
-
# Fall back to 50
|
58
|
-
def transaction_code
|
59
|
-
@transaction_code || 50
|
60
|
-
end
|
61
|
-
|
62
|
-
# Fall back to 0
|
63
|
-
def amount
|
64
|
-
@amount || 0
|
47
|
+
@indicator || ' '
|
65
48
|
end
|
66
49
|
|
67
|
-
#
|
68
|
-
def account_name
|
69
|
-
@account_name || ''
|
70
|
-
end
|
71
|
-
|
72
|
-
# Fall back to empty string
|
50
|
+
# Optional as per BECS
|
73
51
|
def lodgement_reference
|
74
52
|
@lodgement_reference || ''
|
75
53
|
end
|
76
54
|
|
77
|
-
# Fall back to BSB
|
78
|
-
def trace_bsb
|
79
|
-
@trace_bsb || bsb
|
80
|
-
end
|
81
|
-
|
82
|
-
# Fall back to Account Number
|
83
|
-
def trace_account_number
|
84
|
-
@trace_account_number ? @trace_account_number.to_s.gsub('-', '') : account_number
|
85
|
-
end
|
86
|
-
|
87
|
-
def name_of_remitter
|
88
|
-
@name_of_remitter || ''
|
89
|
-
end
|
90
|
-
|
91
55
|
def to_s
|
92
56
|
raise RuntimeError, 'Transaction data is invalid - check the contents of `errors`' unless valid?
|
93
57
|
|
data/lib/aba/validations.rb
CHANGED
@@ -4,6 +4,8 @@ class Aba
|
|
4
4
|
|
5
5
|
BECS_PATTERN = /\A[\w\+\-\@\ \$\!\%\&\(\)\*\.\/\#\=\:\;\?\,\'\[\]\_\^]*\Z/
|
6
6
|
INDICATORS = [' ', 'N', 'T', 'W', 'X', 'Y']
|
7
|
+
DEBIT_TRANSACTION_CODES = [13]
|
8
|
+
CREDIT_TRANSACTION_CODES = [50, 51, 52, 53, 54, 55, 56, 57]
|
7
9
|
|
8
10
|
def self.included(base)
|
9
11
|
base.instance_eval do
|
@@ -13,6 +15,10 @@ class Aba
|
|
13
15
|
base.send :extend, ClassMethods
|
14
16
|
end
|
15
17
|
|
18
|
+
def self.transaction_codes
|
19
|
+
DEBIT_TRANSACTION_CODES + CREDIT_TRANSACTION_CODES
|
20
|
+
end
|
21
|
+
|
16
22
|
def valid?
|
17
23
|
!has_errors?
|
18
24
|
end
|
@@ -47,7 +53,7 @@ class Aba
|
|
47
53
|
self.error_collection << "#{attribute} must be an unsigned number" unless value.to_s =~ /\A\d+\Z/
|
48
54
|
end
|
49
55
|
when :account_number
|
50
|
-
if value.to_s =~ /\A[0\ ]+\Z/ || value.to_s !~ /\A[a-z\d\ ]{1,9}\Z/
|
56
|
+
if value.to_s =~ /\A[0\ ]+\Z/ || value.to_s !~ /\A[a-z\d\ ]{1,9}\Z/i
|
51
57
|
self.error_collection << "#{attribute} must be a valid account number"
|
52
58
|
end
|
53
59
|
when :becs
|
@@ -56,7 +62,7 @@ class Aba
|
|
56
62
|
list = INDICATORS.join('\', \'')
|
57
63
|
self.error_collection << "#{attribute} must be a one of '#{list}'" unless INDICATORS.include?(value.to_s)
|
58
64
|
when :transaction_code
|
59
|
-
self.error_collection << "#{attribute} must be
|
65
|
+
self.error_collection << "#{attribute} must be one of #{Validations.transaction_codes.join(', ')}" unless Validations.transaction_codes.include?(value.to_i)
|
60
66
|
end
|
61
67
|
end
|
62
68
|
end
|
@@ -104,6 +110,10 @@ class Aba
|
|
104
110
|
add_validation_attribute(attribute, :transaction_code)
|
105
111
|
end
|
106
112
|
|
113
|
+
def validates_return_code(attribute)
|
114
|
+
add_validation_attribute(attribute, :integer, :return_code)
|
115
|
+
end
|
116
|
+
|
107
117
|
private
|
108
118
|
|
109
119
|
def add_validation_attribute(attribute, type, param = true)
|
data/lib/aba/version.rb
CHANGED
data/spec/lib/aba/batch_spec.rb
CHANGED
@@ -3,61 +3,131 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
describe Aba::Batch do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
subject(:batch) do
|
7
|
+
Aba::Batch.new(
|
8
|
+
financial_institution: "WPC",
|
9
|
+
user_name: "John Doe",
|
10
|
+
user_id: "466364",
|
11
|
+
description: "Payroll",
|
12
|
+
process_at: "190615",
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:transactions_attributes) { [{amount: 30, transaction_code: 50}, {amount: 20, transaction_code: 13}] }
|
17
|
+
let(:returns_attributes) { [{amount: 3, transaction_code: 50}, {amount: 2, transaction_code: 13}] }
|
18
|
+
|
19
|
+
before do
|
20
|
+
transactions_attributes.each do |attr|
|
21
|
+
transaction = Aba::Transaction.new(
|
22
|
+
bsb: '342-342',
|
23
|
+
account_number: '3244654',
|
24
|
+
amount: attr[:amount],
|
25
|
+
account_name: 'John Doe',
|
26
|
+
transaction_code: attr[:transaction_code],
|
27
|
+
lodgement_reference: 'R435564',
|
28
|
+
trace_bsb: '453-543',
|
29
|
+
trace_account_number: '45656733',
|
30
|
+
name_of_remitter: 'Remitter',
|
31
|
+
)
|
32
|
+
|
33
|
+
batch.add_transaction(transaction)
|
34
|
+
end
|
35
|
+
|
36
|
+
returns_attributes.map do |attr|
|
37
|
+
ret = Aba::Return.new(
|
38
|
+
bsb: '453-543',
|
39
|
+
account_number: '45656733',
|
40
|
+
amount: attr[:amount],
|
41
|
+
account_name: 'John Doe',
|
42
|
+
transaction_code: attr[:transaction_code],
|
43
|
+
lodgement_reference: 'R435564',
|
44
|
+
trace_bsb: '342-342',
|
45
|
+
trace_account_number: '3244654',
|
46
|
+
name_of_remitter: 'Remitter',
|
47
|
+
return_code: 8,
|
48
|
+
original_user_id: 654321,
|
49
|
+
original_processing_day: 12,
|
50
|
+
)
|
51
|
+
|
52
|
+
batch.add_return(ret)
|
15
53
|
end
|
16
54
|
end
|
17
|
-
subject { aba }
|
18
|
-
before { transactions.each { |trx| subject.add_transaction(trx) } }
|
19
55
|
|
20
56
|
describe "#to_s" do
|
21
|
-
|
22
57
|
context 'when descriptive record' do
|
23
|
-
|
24
58
|
context 'without bsb' do
|
25
59
|
it "should return a string containing the descriptive record without the bsb" do
|
26
|
-
expect(
|
60
|
+
expect(batch.to_s).to include("0 01WPC John Doe 466364Payroll 190615 \r\n")
|
27
61
|
end
|
28
62
|
end
|
29
63
|
|
30
64
|
context 'with bsb' do
|
31
|
-
before {
|
65
|
+
before { batch.bsb = "123-345" }
|
66
|
+
|
32
67
|
it "should return a string containing the descriptive record with the bsb" do
|
33
|
-
expect(
|
68
|
+
expect(batch.to_s).to include("0123-345 01WPC John Doe 466364Payroll 190615 \r\n")
|
34
69
|
end
|
35
70
|
end
|
36
71
|
end
|
37
72
|
|
38
73
|
|
39
74
|
context 'when detail record' do
|
40
|
-
|
41
|
-
|
42
|
-
expect(
|
43
|
-
expect(
|
75
|
+
it "should contain transaction & return records" do
|
76
|
+
expect(batch.to_s).to include("1342-342 3244654 500000000030John Doe R435564 453-543 45656733Remitter 00000000\r\n")
|
77
|
+
expect(batch.to_s).to include("1342-342 3244654 130000000020John Doe R435564 453-543 45656733Remitter 00000000\r\n")
|
78
|
+
expect(batch.to_s).to include("2453-543 456567338500000000003John Doe R435564 342-342 3244654Remitter 12654321\r\n")
|
79
|
+
expect(batch.to_s).to include("2453-543 456567338130000000002John Doe R435564 342-342 3244654Remitter 12654321\r\n")
|
44
80
|
end
|
45
81
|
end
|
46
82
|
|
47
83
|
context 'when file total record' do
|
48
|
-
|
49
84
|
context 'with unbalanced transactions' do
|
50
|
-
it "should return a string
|
51
|
-
expect(
|
85
|
+
it "should return a string where the net total is not zero" do
|
86
|
+
expect(batch.to_s).to include("7999-999 000000001100000000330000000022 000004 ")
|
87
|
+
# | Total || Credit || Debit |
|
52
88
|
end
|
53
89
|
end
|
54
90
|
|
55
91
|
context 'with balanced transactions' do
|
56
|
-
let(:
|
92
|
+
let(:transactions_attributes) do
|
93
|
+
[{amount: 30, transaction_code: 50}, {amount: 30, transaction_code: 13}, {amount: 30, transaction_code: 50}]
|
94
|
+
end
|
95
|
+
let(:returns_attributes) do
|
96
|
+
[{amount: 3, transaction_code: 50}, {amount: 3, transaction_code: 13}, {amount: 30, transaction_code: 13}]
|
97
|
+
end
|
98
|
+
|
57
99
|
it "should return a string where the net total is zero" do
|
58
|
-
expect(
|
100
|
+
expect(batch.to_s).to include("7999-999 000000000000000000630000000063 000006 ")
|
101
|
+
# | Total || Credit || Debit |
|
59
102
|
end
|
60
103
|
end
|
104
|
+
|
105
|
+
context 'with negative values supplied for the amounts' do
|
106
|
+
let(:transactions_attributes) { [{amount: -30, transaction_code: 50}, {amount: -20, transaction_code: 13}] }
|
107
|
+
let(:returns_attributes) { [{amount: -3, transaction_code: 50}, {amount: 2, transaction_code: 13}] }
|
108
|
+
|
109
|
+
it 'should return a string where the amount segments rely on the transaction code, not the amount sign' do
|
110
|
+
expect(batch.to_s).to include("7999-999 000000001100000000330000000022 000004 ")
|
111
|
+
# | Total || Credit || Debit |
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#errors" do
|
119
|
+
it "is empty" do
|
120
|
+
expect(batch.errors).to be_nil
|
121
|
+
end
|
122
|
+
|
123
|
+
context "with an invalid amount" do
|
124
|
+
let(:transactions_attributes) do
|
125
|
+
[{amount: 1, transaction_code: 50}, {amount: 'abc', transaction_code: 13}, {amount: 'def', transaction_code: 50}]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "reports the errors" do
|
129
|
+
expect(batch.errors).to eq(:entries => { 1 => ["amount must be a number"], 2 => ["amount must be a number"] })
|
130
|
+
end
|
61
131
|
end
|
62
132
|
end
|
63
133
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Aba::Return do
|
6
|
+
subject(:transaction) { Aba::Return.new(transaction_params) }
|
7
|
+
|
8
|
+
let(:transaction_attributes) { {amount: 50050, transaction_code: 53} }
|
9
|
+
let(:transaction_params) do
|
10
|
+
{
|
11
|
+
:trace_account_number => 23432342,
|
12
|
+
:transaction_code => transaction_attributes[:transaction_code],
|
13
|
+
:amount => transaction_attributes[:amount],
|
14
|
+
:account_name => "John Doe",
|
15
|
+
:trace_bsb => "345-453",
|
16
|
+
:return_code => 8,
|
17
|
+
:lodgement_reference => "R45343",
|
18
|
+
:bsb => "123-234",
|
19
|
+
:account_number => "4647642",
|
20
|
+
:name_of_remitter => "Remitter",
|
21
|
+
:original_processing_day => "07",
|
22
|
+
:original_user_id => "054321",
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#to_s" do
|
27
|
+
it "should create a transaction row" do
|
28
|
+
expect(subject.to_s).to include(
|
29
|
+
"2123-234 46476428530000050050John Doe R45343 345-453 23432342Remitter 07054321")
|
30
|
+
# | | || | | | | | | | |
|
31
|
+
# +-bsb | || +-amount +-account_name | | | | | +-original_user_id
|
32
|
+
# | |+-transaction_code | | | | +-original_processing_day
|
33
|
+
# | +-return_code | | | +-name_of_remitter
|
34
|
+
# +-account_number | | +-trace_account_number
|
35
|
+
# | +-trace_bsb
|
36
|
+
# +-lodgement_reference
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when supplied amount is negative' do
|
40
|
+
let(:transaction_attributes) { {amount: -50050, transaction_code: 53} }
|
41
|
+
|
42
|
+
it "should create a transaction row where the amount does not have a sign" do
|
43
|
+
expect(subject.to_s).to include(
|
44
|
+
"2123-234 46476428530000050050John Doe R45343 345-453 23432342Remitter 07054321")
|
45
|
+
# | | || | | | | | | | |
|
46
|
+
# +-bsb | || +-amount +-account_name | | | | | +-original_user_id
|
47
|
+
# | |+-transaction_code | | | | +-original_processing_day
|
48
|
+
# | +-return_code | | | +-name_of_remitter
|
49
|
+
# +-account_number | | +-trace_account_number
|
50
|
+
# | +-trace_bsb
|
51
|
+
# +-lodgement_reference
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#valid?" do
|
57
|
+
it "should be valid" do
|
58
|
+
expect(subject.valid?).to eq true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not be valid" do
|
62
|
+
transaction_params.delete(:bsb)
|
63
|
+
expect(subject.valid?).to eq false
|
64
|
+
expect(subject.errors).to eq ["bsb format is incorrect"]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -3,25 +3,38 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
describe Aba::Transaction do
|
6
|
-
let(:transaction_params) { {
|
7
|
-
:account_number => 23432342,
|
8
|
-
:transaction_code => 53,
|
9
|
-
:amount => 50050,
|
10
|
-
:account_name => "John Doe",
|
11
|
-
:bsb => "345-453",
|
12
|
-
:witholding_amount => 87,
|
13
|
-
:indicator => "W",
|
14
|
-
:lodgement_reference => "R45343",
|
15
|
-
:trace_bsb => "123-234",
|
16
|
-
:trace_account_number => "4647642",
|
17
|
-
:name_of_remitter => "Remitter"
|
18
|
-
} }
|
19
6
|
subject(:transaction) { Aba::Transaction.new(transaction_params) }
|
20
7
|
|
8
|
+
let(:transaction_attributes) { {amount: 50050, transaction_code: 53} }
|
9
|
+
|
10
|
+
let(:transaction_params) do
|
11
|
+
{
|
12
|
+
:account_number => 23432342,
|
13
|
+
:transaction_code => transaction_attributes[:transaction_code],
|
14
|
+
:amount => transaction_attributes[:amount],
|
15
|
+
:account_name => "John Doe",
|
16
|
+
:bsb => "345-453",
|
17
|
+
:witholding_amount => 87,
|
18
|
+
:indicator => "W",
|
19
|
+
:lodgement_reference => "R45343",
|
20
|
+
:trace_bsb => "123-234",
|
21
|
+
:trace_account_number => "4647642",
|
22
|
+
:name_of_remitter => "Remitter",
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
21
26
|
describe "#to_s" do
|
22
27
|
it "should create a transaction row" do
|
23
28
|
expect(subject.to_s).to include("1345-453 23432342W530000050050John Doe R45343 123-234 4647642Remitter 00000087")
|
24
29
|
end
|
30
|
+
|
31
|
+
context 'when supplied amount is negative' do
|
32
|
+
let(:transaction_attributes) { {amount: -50050, transaction_code: 53} }
|
33
|
+
|
34
|
+
it "should create a transaction row where the amount does not have a sign" do
|
35
|
+
expect(subject.to_s).to include("1345-453 23432342W530000050050John Doe R45343 123-234 4647642Remitter 00000087")
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
|
27
40
|
describe "#valid?" do
|
@@ -138,8 +138,7 @@ describe Aba::Validations do
|
|
138
138
|
expect(subject.errors).to eq ["attr1 must be a valid account number"]
|
139
139
|
|
140
140
|
subject.attr1 = "00 0A0"
|
141
|
-
expect(subject.valid?).to eq
|
142
|
-
expect(subject.errors).to eq ["attr1 must be a valid account number"]
|
141
|
+
expect(subject.valid?).to eq true
|
143
142
|
|
144
143
|
subject.attr1 = "00 111"
|
145
144
|
expect(subject.valid?).to eq true
|
@@ -152,6 +151,9 @@ describe Aba::Validations do
|
|
152
151
|
|
153
152
|
subject.attr1 = "aa aaa"
|
154
153
|
expect(subject.valid?).to eq true
|
154
|
+
|
155
|
+
subject.attr1 = "1A2B3C"
|
156
|
+
expect(subject.valid?).to eq true
|
155
157
|
end
|
156
158
|
|
157
159
|
it "should validate becs" do
|
@@ -180,35 +182,31 @@ describe Aba::Validations do
|
|
180
182
|
|
181
183
|
subject.attr1 = "$"
|
182
184
|
expect(subject.valid?).to eq false
|
183
|
-
list =
|
185
|
+
list = described_class::INDICATORS.join('\', \'')
|
184
186
|
expect(subject.errors).to eq ["attr1 must be a one of '#{list}'"]
|
185
187
|
|
186
|
-
subject.attr1 =
|
188
|
+
subject.attr1 = described_class::INDICATORS.sample
|
187
189
|
expect(subject.valid?).to eq true
|
188
190
|
end
|
189
191
|
|
190
192
|
it "should validate transaction code" do
|
191
193
|
clean_room.instance_eval do
|
192
|
-
attr_accessor :
|
193
|
-
validates_transaction_code :
|
194
|
+
attr_accessor :transaction_code
|
195
|
+
validates_transaction_code :transaction_code
|
194
196
|
end
|
195
197
|
|
196
|
-
subject.
|
197
|
-
expect(subject.valid?).to eq false
|
198
|
-
expect(subject.errors).to eq ["attr1 must be a 2 digit number"]
|
199
|
-
|
200
|
-
subject.attr1 = "123"
|
198
|
+
subject.transaction_code = "AA"
|
201
199
|
expect(subject.valid?).to eq false
|
202
|
-
expect(subject.errors).to eq ["
|
200
|
+
expect(subject.errors).to eq ["transaction_code must be one of #{described_class::transaction_codes.join(', ')}"]
|
203
201
|
|
204
|
-
subject.
|
202
|
+
subject.transaction_code = "1"
|
205
203
|
expect(subject.valid?).to eq false
|
206
|
-
expect(subject.errors).to eq ["
|
204
|
+
expect(subject.errors).to eq ["transaction_code must be one of #{described_class::transaction_codes.join(', ')}"]
|
207
205
|
|
208
|
-
subject.
|
206
|
+
subject.transaction_code = "13"
|
209
207
|
expect(subject.valid?).to eq true
|
210
208
|
|
211
|
-
subject.
|
209
|
+
subject.transaction_code = 50
|
212
210
|
expect(subject.valid?).to eq true
|
213
211
|
end
|
214
212
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,58 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Bazhutkin
|
8
8
|
- Trevor Wistaff
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-11 00:00:00.000000000 Z
|
13
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.6'
|
21
|
-
type: :development
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - "~>"
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '1.6'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: rake
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
31
17
|
requirements:
|
32
18
|
- - "~>"
|
33
19
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
20
|
+
version: '13.0'
|
35
21
|
type: :development
|
36
22
|
prerelease: false
|
37
23
|
version_requirements: !ruby/object:Gem::Requirement
|
38
24
|
requirements:
|
39
25
|
- - "~>"
|
40
26
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
27
|
+
version: '13.0'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: pry
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
45
31
|
requirements:
|
46
32
|
- - "~>"
|
47
33
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0.
|
34
|
+
version: '0.13'
|
49
35
|
type: :development
|
50
36
|
prerelease: false
|
51
37
|
version_requirements: !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
39
|
- - "~>"
|
54
40
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0.
|
41
|
+
version: '0.13'
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: rspec
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,6 +64,7 @@ files:
|
|
78
64
|
- ".gitignore"
|
79
65
|
- ".rspec"
|
80
66
|
- ".travis.yml"
|
67
|
+
- CHANGELOG.md
|
81
68
|
- Gemfile
|
82
69
|
- LICENSE
|
83
70
|
- README.md
|
@@ -85,10 +72,13 @@ files:
|
|
85
72
|
- aba.gemspec
|
86
73
|
- lib/aba.rb
|
87
74
|
- lib/aba/batch.rb
|
75
|
+
- lib/aba/entry.rb
|
76
|
+
- lib/aba/return.rb
|
88
77
|
- lib/aba/transaction.rb
|
89
78
|
- lib/aba/validations.rb
|
90
79
|
- lib/aba/version.rb
|
91
80
|
- spec/lib/aba/batch_spec.rb
|
81
|
+
- spec/lib/aba/return_spec.rb
|
92
82
|
- spec/lib/aba/transaction_spec.rb
|
93
83
|
- spec/lib/aba/validations_spec.rb
|
94
84
|
- spec/lib/aba_spec.rb
|
@@ -97,7 +87,7 @@ homepage: https://github.com/andrba/aba
|
|
97
87
|
licenses:
|
98
88
|
- MIT
|
99
89
|
metadata: {}
|
100
|
-
post_install_message:
|
90
|
+
post_install_message:
|
101
91
|
rdoc_options: []
|
102
92
|
require_paths:
|
103
93
|
- lib
|
@@ -105,20 +95,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
95
|
requirements:
|
106
96
|
- - ">="
|
107
97
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
98
|
+
version: 2.5.0
|
109
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
100
|
requirements:
|
111
101
|
- - ">="
|
112
102
|
- !ruby/object:Gem::Version
|
113
103
|
version: '0'
|
114
104
|
requirements: []
|
115
|
-
|
116
|
-
|
117
|
-
signing_key:
|
105
|
+
rubygems_version: 3.0.3
|
106
|
+
signing_key:
|
118
107
|
specification_version: 4
|
119
108
|
summary: ABA File Generator
|
120
109
|
test_files:
|
121
110
|
- spec/lib/aba/batch_spec.rb
|
111
|
+
- spec/lib/aba/return_spec.rb
|
122
112
|
- spec/lib/aba/transaction_spec.rb
|
123
113
|
- spec/lib/aba/validations_spec.rb
|
124
114
|
- spec/lib/aba_spec.rb
|