aba 0.4.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f11f3830479ca1fad3b854bb9459f99ce7dc8f5a
4
- data.tar.gz: f793d6648ffc17e7589b2c5db57b26f548c5800e
2
+ SHA256:
3
+ metadata.gz: 2156c80e41e17a9df07891a515adff66f0b41412dd83897067a5faa1a598e956
4
+ data.tar.gz: 853deb00316a156169fd1dbc81b5cea3b666122ff538fc61646fedb5bf44d15a
5
5
  SHA512:
6
- metadata.gz: b350430aa9ee2c21cfa6d239c6871fcb3626f724dbd67d5cc5d58dac4d627c16b1e2873d1d4c4e9e80e0ca11acec6a5dfede5bae8b8184fcd8ab182ced99e7d9
7
- data.tar.gz: 356d63f3de331b90a69fc8d586690eb793fa606c8544f4bfc481a8a055ee96811c98a76158617db3e773f13a126eab2a0b53f62d5ac0ddcf0985e1f09ce8bec3
6
+ metadata.gz: ccb0516b85f0b70af8374f8ef4a3f3effe157dcd19296283a2c274359926e567a9bf7120aad3cf784b4ae027f8bf9e4835edc3c02805d10ebca50d6feec4639e
7
+ data.tar.gz: fbce1803cff67a9bbff99f6c91720b05e20fc62837e39f6d170438b3f6e3d47972b2f24dcf969788487b65078b0822570f488541091847ae8238d8e9eb7542fd
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
+ .ruby-version
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.7
6
- - 2.2.3
3
+ - 2.5.8
4
+ - 2.6.6
5
+ - 2.7.1
7
6
  script: bundle exec rspec spec
@@ -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: '-10000', transaction_code: 13
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: '-10000', transaction_code: 13
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: '-10000', transaction_code: 13 }
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
@@ -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 "bundler", "~> 1.6"
22
- spec.add_development_dependency "rake", "~> 10.4"
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 = '>= 1.9.2'
25
+ spec.required_ruby_version = '>= 2.5.0'
27
26
  end
data/lib/aba.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "aba/version"
2
2
  require "aba/validations"
3
+ require "aba/entry"
3
4
  require "aba/batch"
5
+ require "aba/return"
4
6
  require "aba/transaction"
5
7
 
6
8
  class Aba
@@ -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, :transactions
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
- @transaction_index = 0
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 transactions present - add one using `add_transaction`' if @transactions.empty?
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 += @transactions.map{ |t| t[1].to_s }.join("\r\n")
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
- if attrs.instance_of?(Aba::Transaction)
65
- transaction = attrs
66
- else
67
- transaction = Aba::Transaction.new(attrs)
68
- end
69
- @transactions[@transaction_index] = transaction
70
- @transaction_index += 1
71
- transaction
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
- !has_transaction_errors?
75
+ !transactions.map { |t| t.valid? }.include?(false)
76
76
  end
77
77
 
78
78
  def valid?
79
- !has_errors? && transactions_valid?
79
+ !has_errors? && !has_entry_errors?
80
80
  end
81
81
 
82
82
  def errors
83
83
  # Run validations
84
84
  has_errors?
85
- has_transaction_errors?
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
- transaction_error_collection = @transactions.each_with_index.map{ |(k, t), i| [k, t.error_collection] }.reject{ |e| e[1].nil? || e[1].empty? }.to_h
91
- all_errors[:transactions] = transaction_error_collection unless transaction_error_collection.empty?
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 has_transaction_errors?
99
- @transactions.map{ |t| t[1].valid? }.include?(false)
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
- @transactions.each do |t|
167
- net_total_amount += t[1].amount.to_i
168
- credit_total_amount += t[1].amount.to_i if t[1].amount.to_i > 0
169
- debit_total_amount += t[1].amount.to_i if t[1].amount.to_i < 0
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 += net_total_amount.abs.to_s.rjust(10, "0")
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.abs.to_s.rjust(10, "0")
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.abs.to_s.rjust(10, "0")
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 += @transactions.size.to_s.rjust(6, "0")
217
+ output += entries.size.to_s.rjust(6, "0")
211
218
 
212
219
  # Reserved
213
220
  # Max: 40
@@ -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
@@ -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
@@ -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
- # Fall back to blank string
45
+ # Sane default for majority of use cases as per BECS
53
46
  def indicator
54
- @indicator || Aba::Validations::INDICATORS.first
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
- # Fall back to empty string
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
 
@@ -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 a 2 digit number" unless value.to_s =~ /\A\d{2,2}\Z/
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)
@@ -1,3 +1,3 @@
1
1
  class Aba
2
- VERSION = "0.4.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -3,61 +3,131 @@
3
3
  require "spec_helper"
4
4
 
5
5
  describe Aba::Batch do
6
- let(:aba) { Aba::Batch.new(financial_institution: "WPC", user_name: "John Doe",
7
- user_id: "466364", description: "Payroll", process_at: "190615") }
8
- let(:transaction_values) { [30, -20] }
9
- let(:transactions) do
10
- transaction_values.map do |amount|
11
- Aba::Transaction.new(bsb: '342-342', account_number: '3244654', amount: amount,
12
- account_name: 'John Doe', transaction_code: 53,
13
- lodgement_reference: 'R435564', trace_bsb: '453-543',
14
- trace_account_number: '45656733', name_of_remitter: 'Remitter')
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(subject.to_s).to include("0 01WPC John Doe 466364Payroll 190615 \r\n")
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 { subject.bsb = "123-345" }
65
+ before { batch.bsb = "123-345" }
66
+
32
67
  it "should return a string containing the descriptive record with the bsb" do
33
- expect(subject.to_s).to include("0123-345 01WPC John Doe 466364Payroll 190615 \r\n")
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
- it "should contain transactions records" do
42
- expect(subject.to_s).to include("1342-342 3244654 530000000030John Doe R435564 453-543 45656733Remitter 00000000\r\n")
43
- expect(subject.to_s).to include("1342-342 3244654 530000000020John Doe R435564 453-543 45656733Remitter 00000000\r\n")
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 wihere the net total is not zero" do
51
- expect(subject.to_s).to include("7999-999 000000001000000000300000000020 000002 ")
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(:transaction_values) { [30, 30, -60] }
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(subject.to_s).to include("7999-999 000000000000000000600000000060 000003 ")
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 false
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 = Aba::Validations::INDICATORS.join('\', \'')
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 = Aba::Validations::INDICATORS.sample
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 :attr1
193
- validates_transaction_code :attr1
194
+ attr_accessor :transaction_code
195
+ validates_transaction_code :transaction_code
194
196
  end
195
197
 
196
- subject.attr1 = "AA"
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 ["attr1 must be a 2 digit number"]
200
+ expect(subject.errors).to eq ["transaction_code must be one of #{described_class::transaction_codes.join(', ')}"]
203
201
 
204
- subject.attr1 = "1"
202
+ subject.transaction_code = "1"
205
203
  expect(subject.valid?).to eq false
206
- expect(subject.errors).to eq ["attr1 must be a 2 digit number"]
204
+ expect(subject.errors).to eq ["transaction_code must be one of #{described_class::transaction_codes.join(', ')}"]
207
205
 
208
- subject.attr1 = "15"
206
+ subject.transaction_code = "13"
209
207
  expect(subject.valid?).to eq true
210
208
 
211
- subject.attr1 = 15
209
+ subject.transaction_code = 50
212
210
  expect(subject.valid?).to eq true
213
211
  end
214
212
  end
@@ -2,6 +2,7 @@ require 'bundler/setup'
2
2
  Bundler.setup
3
3
 
4
4
  require "aba"
5
+ require "pry"
5
6
 
6
7
  RSpec.configure do |config|
7
8
  config.order = :random
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.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: 2015-09-24 00:00:00.000000000 Z
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: '10.4'
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: '10.4'
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.10'
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.10'
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: 1.9.2
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
- rubyforge_project:
116
- rubygems_version: 2.2.2
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