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 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