zilverline-mt940 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.document +5 -0
- data/.gitignore +52 -0
- data/.ruby-version +1 -0
- data/CHANGELOG +56 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +20 -0
- data/README.md +75 -0
- data/Rakefile +9 -0
- data/lib/mt940.rb +10 -0
- data/lib/mt940/bank_statement.rb +13 -0
- data/lib/mt940/banks/abnamro.rb +76 -0
- data/lib/mt940/banks/ing.rb +84 -0
- data/lib/mt940/banks/rabobank.rb +770 -0
- data/lib/mt940/banks/triodos.rb +20 -0
- data/lib/mt940/base.rb +165 -0
- data/lib/mt940/structured_format.rb +16 -0
- data/lib/mt940/transaction.rb +23 -0
- data/lib/mt940/version.rb +3 -0
- data/mt940.gemspec +32 -0
- data/spec/fixtures/abnamro.txt +41 -0
- data/spec/fixtures/abnamro_structured.txt +54 -0
- data/spec/fixtures/ing.txt +24 -0
- data/spec/fixtures/ing_structured.txt +31 -0
- data/spec/fixtures/rabobank.txt +140 -0
- data/spec/fixtures/rabobank_mt940_structured.txt +48 -0
- data/spec/fixtures/rabobank_mt940_structured_dutch_tax.txt +10 -0
- data/spec/fixtures/rabobank_mt940_structured_multi_line.txt +14 -0
- data/spec/fixtures/rabobank_mt940_structured_savings_account.txt +11 -0
- data/spec/fixtures/rabobank_mt940_structured_to_savings_account.txt +10 -0
- data/spec/fixtures/rabobank_with_debet_previous_balance.txt +6 -0
- data/spec/fixtures/triodos.txt +14 -0
- data/spec/fixtures/two_accounts.txt +29 -0
- data/spec/fixtures/unknown.txt +22 -0
- data/spec/mt940_abnamro_spec.rb +244 -0
- data/spec/mt940_base_spec.rb +48 -0
- data/spec/mt940_ing_spec.rb +227 -0
- data/spec/mt940_rabobank_spec.rb +376 -0
- data/spec/mt940_triodos_spec.rb +58 -0
- data/spec/mt940_two_accounts_spec.rb +49 -0
- data/spec/spec_helper.rb +4 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
M2VjYjdlOGZlYzJkMDZmOWIzZTkzODkwNjc0YThmYjg0NTg0MDdmOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Mjg3Mzg5YmYzMTE4NDkzYWIwYTBhMWVkMDlhM2U1M2UyYjg5ZTY1ZQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YmRlMTM0ZTI5MzdmYmE3NGIwZTBmNGQwOTI1YmU1NzJlY2I1ZDNkNTk0YWY2
|
10
|
+
NWZhNzYzYWU1ZTFmNDJmNTE0NzRhZTgzN2M1NGIxNTNiN2Q1MjkzMzM5MzVj
|
11
|
+
ZjRjMDBlYjRiM2Y4M2IzY2Y5M2Q1OWVmYTFmMGQzNTMyMjI3NTM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NWU5Njk2YWU4N2E1ZTQ0YjUzZDVhZjkzY2ViNTEyOTQ0ZTE5MGQ0MjBkOWNi
|
14
|
+
NzRmOTNmNGZiODQ0MjZiMDE4ZDE4YzQ3N2M2MDYyYjc2OWY5YjAzNGJlMzUy
|
15
|
+
YzdmMGFmYzg2NjRiOTAwNDFkODkxODU4NTU2ODJmYjBhNTQzM2M=
|
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
|
4
|
+
# rdoc generated
|
5
|
+
rdoc
|
6
|
+
|
7
|
+
# yard generated
|
8
|
+
doc
|
9
|
+
.yardoc
|
10
|
+
|
11
|
+
# bundler
|
12
|
+
.bundle
|
13
|
+
|
14
|
+
# jeweler generated
|
15
|
+
pkg
|
16
|
+
|
17
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
18
|
+
#
|
19
|
+
# * Create a file at ~/.gitignore
|
20
|
+
# * Include files you want ignored
|
21
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
22
|
+
#
|
23
|
+
# After doing this, these files will be ignored in all your git projects,
|
24
|
+
# saving you from having to 'pollute' every project you touch with them
|
25
|
+
#
|
26
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
27
|
+
#
|
28
|
+
# For MacOS:
|
29
|
+
#
|
30
|
+
#.DS_Store
|
31
|
+
|
32
|
+
# For TextMate
|
33
|
+
#*.tmproj
|
34
|
+
#tmtags
|
35
|
+
|
36
|
+
# For emacs:
|
37
|
+
#*~
|
38
|
+
#\#*
|
39
|
+
#.\#*
|
40
|
+
|
41
|
+
# For vim:
|
42
|
+
#*.swp
|
43
|
+
|
44
|
+
# For redcar:
|
45
|
+
#.redcar
|
46
|
+
|
47
|
+
# For rubinius:
|
48
|
+
#*.rbc
|
49
|
+
|
50
|
+
# rvmrc
|
51
|
+
.rvmrc
|
52
|
+
.idea/
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p385
|
data/CHANGELOG
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
* 0.6.6
|
2
|
+
- Added currency support in transaction (contribution of Bob Forma)
|
3
|
+
|
4
|
+
* 0.6.5
|
5
|
+
|
6
|
+
- Use bundler for gem building and release
|
7
|
+
- Add travis configuration
|
8
|
+
|
9
|
+
* 0.6.4
|
10
|
+
|
11
|
+
- Fix for multiline description for Rabobank
|
12
|
+
|
13
|
+
* 0.6.3
|
14
|
+
|
15
|
+
- include the updated Changelog and README as well
|
16
|
+
|
17
|
+
* 0.6.2 (Was never released)
|
18
|
+
|
19
|
+
- Parse a NONREF contra account for the rabobank correctly
|
20
|
+
|
21
|
+
* 0.6.1 (Was never released)
|
22
|
+
|
23
|
+
- Extracting contra account for ING, AbnAmro and Triodos as well
|
24
|
+
- Standardized all account numbers to exactly 9 digits
|
25
|
+
|
26
|
+
* 0.6.0 (Was never released)
|
27
|
+
|
28
|
+
* 0.5.1
|
29
|
+
|
30
|
+
- Delegated determination of bank to corresponding subclass
|
31
|
+
|
32
|
+
* 0.5.0
|
33
|
+
|
34
|
+
- Added bank to a transaction
|
35
|
+
|
36
|
+
* 0.4.1
|
37
|
+
|
38
|
+
- Handle can be a Tempfile as well
|
39
|
+
|
40
|
+
* 0.4.0
|
41
|
+
|
42
|
+
- Also handle to MT940 file possible
|
43
|
+
|
44
|
+
* 0.3.0
|
45
|
+
|
46
|
+
- Added a date to a transaction
|
47
|
+
- Change transaction attribute name of contra_account_name into contra_account_owner
|
48
|
+
|
49
|
+
* 0.2.0
|
50
|
+
|
51
|
+
- General parse method refactored and broke down in individual parse methods per tag
|
52
|
+
- Automatic determination of bank on the base of the first line implemented
|
53
|
+
|
54
|
+
* 0.1.0
|
55
|
+
|
56
|
+
Initial release
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
zilverline-mt940 (1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.3)
|
10
|
+
rake (10.1.0)
|
11
|
+
rspec (2.12.0)
|
12
|
+
rspec-core (~> 2.12.0)
|
13
|
+
rspec-expectations (~> 2.12.0)
|
14
|
+
rspec-mocks (~> 2.12.0)
|
15
|
+
rspec-core (2.12.0)
|
16
|
+
rspec-expectations (2.12.0)
|
17
|
+
diff-lcs (~> 1.1.3)
|
18
|
+
rspec-mocks (2.12.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
rake
|
25
|
+
rspec
|
26
|
+
zilverline-mt940!
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Frank Oxener - Agile Dovadi BV
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
MT940
|
2
|
+
======
|
3
|
+
|
4
|
+
Full parser for MT940 files, see [MT940](http://nl.wikipedia.org/wiki/MT940). This is based on
|
5
|
+
the original gem of [Frank Oxener - Agile Dovadi BV](http://github.com/dovadi/mt940) but completely redesigned and extended.
|
6
|
+
|
7
|
+
The following Dutch banks are implemented:
|
8
|
+
|
9
|
+
* ABN Amro
|
10
|
+
* ING
|
11
|
+
* Rabobank
|
12
|
+
* Triodos
|
13
|
+
|
14
|
+
Usage
|
15
|
+
=====
|
16
|
+
|
17
|
+
With the file name as argument:
|
18
|
+
|
19
|
+
file_name = '~/Downloads/ing.940'
|
20
|
+
|
21
|
+
@parse_result = MT940::Base.parse_mt940(file_name)
|
22
|
+
|
23
|
+
or with the file itself:
|
24
|
+
|
25
|
+
file_name = '~/Downloads/ing.940'
|
26
|
+
|
27
|
+
file = File.open(file_name)
|
28
|
+
|
29
|
+
@parse_result = MT940::Base.parse_mt940(file)
|
30
|
+
|
31
|
+
after parsing:
|
32
|
+
|
33
|
+
@parse_result.each do |account_number, bank_statements|
|
34
|
+
puts "Account number #{account_number} has #{bank_statements.size} bank statements"
|
35
|
+
bank_statements.each do |bank_statement|
|
36
|
+
puts "Bank statement has balance of #{bank_statement.previous_balance.amount} at date #{bank_statement.previous_balance.date}"
|
37
|
+
bank_statement.transactions.each do |transaction|
|
38
|
+
# do something with transaction
|
39
|
+
# ...
|
40
|
+
end
|
41
|
+
puts "Bank statement has new balance of #{bank_statement.new_balance.amount} at date #{bank_statement.new_balance.date}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
* Independent of the bank
|
46
|
+
|
47
|
+
- a parse_result consists of:
|
48
|
+
|
49
|
+
- a map with account numbers as key and a list of BankStatements (http://en.wikipedia.org/wiki/Bank_statement)
|
50
|
+
- A BankStatement is a summary of financial transaction in a certain period of time.
|
51
|
+
- It is a Struct
|
52
|
+
- It contains a previous_balance (Balance) and a new_balance (Balance)
|
53
|
+
- It has a list of Transactions
|
54
|
+
- a transaction always consists of:
|
55
|
+
- accountnumber
|
56
|
+
- bank (for example Ing, Rabobank or Unknown)
|
57
|
+
- date
|
58
|
+
- amount (which is negative in case of a withdrawal)
|
59
|
+
- description
|
60
|
+
- contra account
|
61
|
+
|
62
|
+
* With the Rabobank its owner is extracted as well.
|
63
|
+
|
64
|
+
Running tests
|
65
|
+
=============
|
66
|
+
|
67
|
+
> bundle install
|
68
|
+
|
69
|
+
> bundle exec rake spec
|
70
|
+
|
71
|
+
Copyright
|
72
|
+
==========
|
73
|
+
|
74
|
+
Copyright (c) 2012 Frank Oxener - Agile Dovadi BV. See LICENSE.txt for further details.
|
75
|
+
|
data/Rakefile
ADDED
data/lib/mt940.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'date'
|
3
|
+
require_relative 'mt940/transaction'
|
4
|
+
require_relative 'mt940/bank_statement'
|
5
|
+
require_relative 'mt940/base'
|
6
|
+
require_relative 'mt940/structured_format'
|
7
|
+
require_relative 'mt940/banks/ing'
|
8
|
+
require_relative 'mt940/banks/rabobank'
|
9
|
+
require_relative 'mt940/banks/abnamro'
|
10
|
+
require_relative 'mt940/banks/triodos'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MT940
|
2
|
+
##
|
3
|
+
# A Bankstatement contains a single or multiple Transaction's.
|
4
|
+
# It is the equivalent of an actual real life gold old paper bank statement
|
5
|
+
# as we used to get them via post in the old days.
|
6
|
+
#
|
7
|
+
BankStatement = Struct.new(:transactions, :bank_account, :bank_account_iban, :page_number, :previous_balance, :new_balance)
|
8
|
+
|
9
|
+
##
|
10
|
+
# A Balance describes the amount of money you have on your bank account
|
11
|
+
# at a certain moment in time.
|
12
|
+
Balance = Struct.new(:amount, :date, :currency)
|
13
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class MT940::Abnamro < MT940::Base
|
2
|
+
include MT940::StructuredFormat
|
3
|
+
|
4
|
+
def self.determine_bank(*args)
|
5
|
+
self if args[0].match(/ABNANL/)
|
6
|
+
end
|
7
|
+
|
8
|
+
def mt_940_start_line?(line)
|
9
|
+
super || line.match(/ABNANL/)
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_tag_61
|
13
|
+
if @line.match(/^:61:(\d{6})\d{4}(C|D)(\d+),(\d{0,2})/)
|
14
|
+
type = $2 == 'D' ? -1 : 1
|
15
|
+
@transaction = MT940::Transaction.new(:bank_account => @bank_account, :amount => type * ($3 + '.' + $4).to_f, :bank => @bank, :currency => @currency)
|
16
|
+
@transaction.date = parse_date($1)
|
17
|
+
@bank_statement.transactions << @transaction
|
18
|
+
@tag86 = false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_contra_account
|
23
|
+
if @transaction
|
24
|
+
|
25
|
+
case @transaction.description
|
26
|
+
when /^(GIRO)\s+(\d+)(.+)/
|
27
|
+
@transaction.contra_account = $2.rjust(9, '000000000')
|
28
|
+
@transaction.description = $3
|
29
|
+
when /^(\d{2}.\d{2}.\d{2}.\d{3})(.+)/
|
30
|
+
@transaction.description = $2.strip
|
31
|
+
@transaction.contra_account = $1.gsub('.', '')
|
32
|
+
when /\/TRTP\/SEPA OVERBOEKING/
|
33
|
+
description_parts = @line[4..-1].split('/')
|
34
|
+
@transaction.contra_account_iban = parse_description_after_tag description_parts, "IBAN"
|
35
|
+
@transaction.contra_account = iban_to_account @transaction.contra_account_iban
|
36
|
+
@transaction.contra_account_owner = parse_description_after_tag description_parts, "NAME"
|
37
|
+
@transaction.description = parse_description_after_tag description_parts, "REMI"
|
38
|
+
when /SEPA IDEAL/
|
39
|
+
read_all_description_lines!
|
40
|
+
full_description = @transaction.description
|
41
|
+
if full_description.match /OMSCHRIJVING\:(.+)?/
|
42
|
+
@transaction.description = $1.strip
|
43
|
+
end
|
44
|
+
if full_description.match /IBAN\:(.+)?BIC\:/
|
45
|
+
@transaction.contra_account_iban = $1.strip
|
46
|
+
@transaction.contra_account = iban_to_account @transaction.contra_account_iban
|
47
|
+
end
|
48
|
+
if full_description.match /NAAM\:(.+)?OMSCHRIJVING\:/
|
49
|
+
@transaction.contra_account_owner = $1.strip
|
50
|
+
end
|
51
|
+
when /SEPA ACCEPTGIROBETALING/
|
52
|
+
read_all_description_lines!
|
53
|
+
full_description = @transaction.description
|
54
|
+
if full_description.match /(BETALINGSKENM\.\:.+)/
|
55
|
+
@transaction.description = $1.strip
|
56
|
+
end
|
57
|
+
if full_description.match /IBAN\:(.+)?BIC\:/
|
58
|
+
@transaction.contra_account_iban = $1.strip
|
59
|
+
@transaction.contra_account = iban_to_account @transaction.contra_account_iban
|
60
|
+
end
|
61
|
+
if full_description.match /NAAM\:(.+)?BETALINGSKENM\.\:/
|
62
|
+
@transaction.contra_account_owner = $1.strip
|
63
|
+
end
|
64
|
+
else
|
65
|
+
@skip_parse_line = false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def iban_to_account(iban)
|
73
|
+
!iban.nil? ? iban.split(//).last(10).join.gsub(/^0+/, '') : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class MT940::Ing < MT940::Base
|
2
|
+
|
3
|
+
IBAN_BIC_R = /^([a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{0,30})(?:\s)([a-zA-Z0-9]{8,11})(?:\s)(.*)/
|
4
|
+
CONTRA_ACCOUNT_DESCRIPTION_R = /^(.*)(?:\s)(?:NOTPROVIDED)(?:\s)(.*)/
|
5
|
+
|
6
|
+
|
7
|
+
def self.determine_bank(*args)
|
8
|
+
self if args[0].match(/INGBNL/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_tag_61
|
12
|
+
|
13
|
+
@is_structured_format = @line.match /EREF|PREF|MARF|\d{16}/
|
14
|
+
|
15
|
+
if @line.match(/^:61:(\d{6})(C|D)(\d+),(\d{0,2})N(\S+)/)
|
16
|
+
sign = $2 == 'D' ? -1 : 1
|
17
|
+
@transaction = MT940::Transaction.new(:bank_account => @bank_account, :amount => sign * ($3 + '.' + $4).to_f, :bank => @bank, :currency => @currency)
|
18
|
+
@transaction.type = human_readable_type($5.strip)
|
19
|
+
@transaction.date = parse_date($1)
|
20
|
+
@bank_statement.transactions << @transaction
|
21
|
+
@tag86 = false
|
22
|
+
else
|
23
|
+
raise @line
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_tag_62F
|
28
|
+
super
|
29
|
+
@tag86 = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_contra_account
|
33
|
+
if @is_structured_format && @transaction && @transaction.description.match(IBAN_BIC_R)
|
34
|
+
parse_structured_description $1, $3
|
35
|
+
elsif @transaction && @transaction.description.match(/([P|\d]\d{9})?(.+)/)
|
36
|
+
parse_description $1, $2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def human_readable_type(type)
|
41
|
+
ING_MAPPING[type.strip] || type.strip
|
42
|
+
end
|
43
|
+
|
44
|
+
ING_MAPPING = {}
|
45
|
+
ING_MAPPING["AC"]= "Acceptgiro"
|
46
|
+
ING_MAPPING["BA"]= "Betaalautomaattransactie"
|
47
|
+
ING_MAPPING["CH"]= "Cheque"
|
48
|
+
ING_MAPPING["DV"]= "Diversen"
|
49
|
+
ING_MAPPING["FL"]= "Filiaalboeking, concernboeking"
|
50
|
+
ING_MAPPING["GF"]= "Telefonisch bankieren"
|
51
|
+
ING_MAPPING["GM"]= "Geldautomaat"
|
52
|
+
ING_MAPPING["GT"]= "Internetbankieren"
|
53
|
+
ING_MAPPING["IC"]= "Incasso"
|
54
|
+
ING_MAPPING["OV"]= "Overschrijving"
|
55
|
+
ING_MAPPING["PK"]= "Opname kantoor"
|
56
|
+
ING_MAPPING["PO"]= "Periodieke overschrijving"
|
57
|
+
ING_MAPPING["ST"]= "ST Storting (eigen rekening of derde)"
|
58
|
+
ING_MAPPING["VZ"]= "Verzamelbetaling"
|
59
|
+
ING_MAPPING["Code"]= "Toelichting"
|
60
|
+
ING_MAPPING["CHK"]= "Cheque"
|
61
|
+
ING_MAPPING["TRF"]= "Overboeking buitenland"
|
62
|
+
|
63
|
+
private
|
64
|
+
# introduced by IBAN
|
65
|
+
def parse_structured_description(iban, description)
|
66
|
+
@transaction.contra_account_iban=iban
|
67
|
+
@transaction.description=description
|
68
|
+
@transaction.contra_account=@transaction.contra_account_iban[8..-1].sub(/^0+/, '') if @transaction.contra_account_iban.match /^NL/
|
69
|
+
if @transaction.description.match CONTRA_ACCOUNT_DESCRIPTION_R
|
70
|
+
@transaction.contra_account_owner=$1
|
71
|
+
@transaction.description=$2
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_description(account_number, description)
|
76
|
+
@transaction.description = description.strip
|
77
|
+
number = account_number
|
78
|
+
unless number.nil?
|
79
|
+
@transaction.contra_account = number.gsub(/\D/, '').gsub(/^0+/, '')
|
80
|
+
else
|
81
|
+
@transaction.contra_account = "NONREF"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|