rbankgiro 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -11,7 +11,6 @@ begin
11
11
  gemspec.email = "johan@duh.se"
12
12
  gemspec.homepage = "http://github.com/jage/rbankgiro"
13
13
  gemspec.authors = ["Johan Eckerström"]
14
- #gemspec.files = FileList['lib/rbankgiro.rb']
15
14
  gemspec.has_rdoc = false
16
15
  end
17
16
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
data/lib/rbankgiro.rb CHANGED
@@ -7,16 +7,46 @@ module Rbankgiro
7
7
  class TransactionCountError < StandardError; end
8
8
  class PartSumError < StandardError; end
9
9
 
10
- # A Rbankgiro transaction, contains OCR-number for the transaction
10
+ # A Bankgiro transaction, contains reference_number-number for the transaction
11
11
  # amount in SEK and the transaction date
12
12
  class Transaction
13
- attr_reader :amount, :ocr, :file_date
13
+ attr_reader :amount, :ore, :reference_number, :file_date,
14
+ :bankgiro_number, :lb_flag, :service_number
14
15
 
15
- def initialize(ocr, raw_amount, file_date)
16
+ OVERPUNCH_TRANSLATION = {
17
+ "-" => "0",
18
+ "J" => "1",
19
+ "K" => "2",
20
+ "L" => "3",
21
+ "M" => "4",
22
+ "N" => "5",
23
+ "O" => "6",
24
+ "P" => "7",
25
+ "Q" => "8",
26
+ "R" => "9"
27
+ }
28
+
29
+ def initialize(reference_number, raw_amount, file_date, bankgiro_number, lb_flag = false, service_number = false)
16
30
  @raw_amount = raw_amount
17
- @ocr = ocr
18
- @amount = raw_amount.split('')[0..-3].join.to_i
19
- @file_date = file_date
31
+
32
+ r = raw_amount.match(/^(\d{11})(.)(.)$/)
33
+
34
+ if OVERPUNCH_TRANSLATION.include?(r[3])
35
+ raise FileFormatError, "Overpunch but not an LB transaction" unless lb_flag
36
+ amount = "-" + r[1]
37
+ ore = "-" + r[2] + OVERPUNCH_TRANSLATION[r[3]]
38
+ else
39
+ amount = r[1]
40
+ ore = r[2] + r[3]
41
+ end
42
+
43
+ @amount = amount.to_i
44
+ @ore = ore.to_i
45
+ @reference_number = reference_number
46
+ @file_date = file_date
47
+ @bankgiro_number = bankgiro_number
48
+ @lb_flag = lb_flag
49
+ @service_number = service_number
20
50
  end
21
51
 
22
52
  # If the amount last two characters aren't 00,
@@ -29,13 +59,10 @@ module Rbankgiro
29
59
  class Transactions < Array
30
60
  attr_reader :file_date
31
61
 
32
- # Parses an OCR transaction file from Rbankgirocentralen
62
+ # Parses an reference_number transaction file from Rbankgirocentralen
33
63
  # Creates Rbankgiro::Transaction objects for each transaction
34
- def initialize(file, bankgiro_number)
35
- @bankgiro_number = bankgiro_number.to_s
36
-
37
- ocr_transaction_input = File.open(file, 'r') {|f| f.read }
38
- ocr_transaction_input.each_line do |row|
64
+ def initialize(file)
65
+ File.read(file).each_line do |row|
39
66
  next if row.strip.empty? # Skip empty rows
40
67
  parse_row(row)
41
68
  end
@@ -50,69 +77,76 @@ module Rbankgiro
50
77
  "@sum=#{self.sum}, @length=#{self.length}, @file_date=#{self.file_date}")
51
78
  end
52
79
 
80
+ def select_with(bankgiro_number)
81
+ self.dup.replace(self.select {|t| t.bankgiro_number == bankgiro_number })
82
+ end
83
+
53
84
  private
54
85
 
55
86
  def parse_row(row)
56
- columns = row.scan(/\w+/).collect {|c| c.strip }
57
- case columns.first
58
- when '00909897'
87
+ columns = row.split(' ').collect {|c| c.strip }.compact
88
+ case columns[0]
89
+ when /^(00)(\d{0,6})/
59
90
  # The first row if a File header, should look like:
60
- # 00909897 <6:date> BANKGIROT
91
+ # 00<6:service number> <6:date> BANKGIROT
61
92
  raise CorruptHeader unless columns[2] == 'BANKGIROT'
93
+ @service_number = $2
62
94
  @raw_file_date = columns[1]
63
95
  @file_date = Time.parse(@raw_file_date)
64
96
  when '10'
65
97
  when '20'
66
98
  # Specifies the bankgiro number:
67
99
  # <8:bankgiro number>
68
- raise InvalidBankgiroNumber unless columns[1] == @bankgiro_number
100
+ @bankgiro_number = columns[1]
101
+ raise InvalidBankgiroNumber unless @bankgiro_number
69
102
  when '30'
70
103
  # Specifies the bankgiro number with the transaction date after:
71
104
  # <8:bankgiro number><6:date>
72
105
  raise FileFormatError unless columns[1] == @bankgiro_number + @raw_file_date
73
106
  when '40'
74
107
  # Transaction row:
75
- # <17:OCR-number><13:Amount with ören)
76
- if r = columns[1].match(/^(\d{17})(\d{13})$/)
77
- ocr = r[1]
78
- raw_amount = r[2]
79
- self << Rbankgiro::Transaction.new(ocr, raw_amount, @file_date)
108
+ # <17:reference number><13:Amount with öre or overpunch> <2:LB flag if "Leverantörsbetalning">
109
+ if r = columns[1].match(/^(\d+)(.{13})$/)
110
+ reference_number = r[1]
111
+ raw_amount = r[2]
112
+ lb_flag = columns[2] == 'LB'
113
+ self << Rbankgiro::Transaction.new(reference_number, raw_amount, @file_date, @bankgiro_number, lb_flag, @service_number)
80
114
  else
81
- raise FileFormatError
115
+ raise FileFormatError, "Transaction row"
82
116
  end
83
117
  when '50'
84
118
  # Part payment check
85
- # <8:Rbankgiro number><6:file_date><7:number of transactions><part payments with öre>
86
- if r = columns[1].match(/^(\d{8})(\d{6})(\d{7})(\d{15})$/)
119
+ # <8:Bankgiro or postgiro number><6:file_date><7:number of transactions><part payments in sek><part payments öre>
120
+ if r = columns[1].match(/^(\d+)(\d{6})(\d{7})(\d{13})(\d{2})$/)
87
121
  bankgiro_number_control = r[1]
88
122
  file_date_control = r[2]
89
- number_of_transactions = r[3]
90
- payments_raw_sum = r[4]
91
- payments_sum = payments_raw_sum.split('')[0..-3].join.to_i # Remove the Öre
92
-
123
+ number_of_transactions = r[3].to_i
124
+ payments_sum = r[4].to_i
93
125
  else
94
- raise FileFormatError
126
+ raise FileFormatError, "Part payment row"
95
127
  end
96
128
 
97
- raise PartSumError unless payments_sum == self.collect {|t| t.amount }.inject {|s,n| s + n }
98
- raise TransactionCountError unless number_of_transactions.to_i == self.length
129
+ transactions_sum = self.select_with(@bankgiro_number).sum
130
+ unless payments_sum == transactions_sum
131
+ raise PartSumError, "part payment row is #{payments_sum}, transaction sum is #{transactions_sum}"
132
+ end
133
+ raise TransactionCountError unless number_of_transactions == self.select_with(@bankgiro_number).length
99
134
  when '90'
100
135
  # Total payment check
101
- # <6:file_date><7:number of transactions><part payments with öre>
102
- if r = columns[1].match(/^(\d{6})(\d{7})(\d{15})$/)
136
+ # <6:file_date><7:number of transactions><total payments in sek><total payments öre>
137
+ if r = columns[1].match(/^(\d{6})(\d{7})(\d{13})(\d{2})$/)
103
138
  file_date_control = r[1]
104
- number_of_transactions = r[2]
105
- payments_raw_sum = r[3]
106
- payments_sum = payments_raw_sum.split('')[0..-3].join.to_i # Remove the Öre
139
+ number_of_transactions = r[2].to_i
140
+ payments_sum = r[3].to_i
107
141
  else
108
- raise FileFormatError
142
+ raise FileFormatError, "Total payment row, syntax error"
109
143
  end
110
-
111
- raise PartSumError unless payments_sum == self.collect {|t| t.amount }.inject {|s,n| s + n }
112
- raise TransactionCountError unless number_of_transactions.to_i == self.length
144
+
145
+ raise PartSumError, "Total payment row" unless payments_sum == self.sum
146
+ raise TransactionCountError unless number_of_transactions == self.length
113
147
  else
114
148
  # Should be handled by previous cases, if it goes here something is wrong
115
- raise FileFormatError
149
+ raise FileFormatError, "Unknown error"
116
150
  end
117
151
  end
118
152
  end
data/rbankgiro.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rbankgiro}
8
- s.version = "0.1.3"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Johan Eckerstr\303\266m"]
12
- s.date = %q{2009-12-06}
12
+ s.date = %q{2009-12-08}
13
13
  s.description = %q{Parsing transaction files from swedish Bankgiro central}
14
14
  s.email = %q{johan@duh.se}
15
15
  s.extra_rdoc_files = [
@@ -23,9 +23,13 @@ Gem::Specification.new do |s|
23
23
  "rbankgiro.gemspec",
24
24
  "test/fixtures/corrupt_header_09_02_27.txt",
25
25
  "test/fixtures/file_format_error_09_02_27.txt",
26
+ "test/fixtures/invalid_bankgiro_number_09_02_27.txt",
26
27
  "test/fixtures/missing_transaction_09_02_27.txt",
28
+ "test/fixtures/multiple_transactions_06_06_20.txt",
29
+ "test/fixtures/multiple_transactions_with_plusgiro_06_06_20.txt",
27
30
  "test/fixtures/one_too_many_transactions_09_02_27.txt",
28
31
  "test/fixtures/one_transaction_09_02_27.txt",
32
+ "test/fixtures/overpunch_transaction_with_missing_lb_flag_06_06_20.txt",
29
33
  "test/helper.rb",
30
34
  "test/test_transaction.rb",
31
35
  "test/test_transactions.rb"
@@ -0,0 +1,7 @@
1
+ 00909897 090227 BANKGIROT
2
+ 10
3
+ 20
4
+ 30 53090965090227
5
+ 40 860421037000000120000000000100 5670574005
6
+ 50 530909650902270000001000000000000100
7
+ 90 0902270000001000000000000100
@@ -0,0 +1,45 @@
1
+ 00 060620 BANKGIROT
2
+ 10
3
+ 20 9912346
4
+ 30 9912346060620
5
+ 40 39407150000000147700 5540020977
6
+ 40 39407640000000198100 5511115706
7
+ 40 39408300000000190700 5541008608
8
+ 40 39408890000000073100 5540093777
9
+ 40 39408890000000132100 5540006858
10
+ 40 39409620000000087600 5540094494
11
+ 40 39410690000000078500 5517551977
12
+ 40 39410770000000094900 5540021183
13
+ 40 39410850000000169300 5517035205
14
+ 40 39410930000000084100 5547510501
15
+ 40 39411010000000084900 5511100321
16
+ 40 39411190000000074200 5540022584
17
+ 40 39411350000000076900 5540025566
18
+ 40 39411430000000229300 5517540398
19
+ 40 39411500000000075500 5540097588
20
+ 40 39411680000000082700 5540009276
21
+ 40 39411760000000123900 5540021117
22
+ 40 39411840000000248300 5511053245
23
+ 40 39411840000000201100 5541008627
24
+ 40 39412000000000147700 5517043623
25
+ 40 39412180000000123000 5547510510
26
+ 40 39412260000000082700 5540022386
27
+ 40 39412340000000087700 5517003480
28
+ 40 39412420000000153800 5517537838
29
+ 40 39412590000000100000 5504092053
30
+ 40 39412750000000034000 5514040512
31
+ 40 39412750000000194000 5517061500
32
+ 40 39412910000000200395 LB 0002582200
33
+ 40 39413740000000113700 5517041901
34
+ 40 39413740000000191300 5540043993
35
+ 40 39413900000000113400 LB 0005550731
36
+ 40 39414080000000158800 LB 0003334451
37
+ 40 39414240000000201700 5540020428
38
+ 40 39414570000000113400 5541008602
39
+ 40 39416060000000119900 5540026099
40
+ 40 39417050000000320800 5540011036
41
+ 40 8841298000000009989N LB 0002582200
42
+ 40 8841397000000010000- LB 0005550731
43
+ 50 99123460606200000038000000004709300
44
+ 90 0606200000038000000004709300
45
+
@@ -0,0 +1,46 @@
1
+ 00 060620 BANKGIROT
2
+ 10
3
+ 20 99123465
4
+ 30 99123465060620 9912346
5
+ 40 49523470000000010000 5540020978
6
+ 40 49524530000000797800 5540094949
7
+ 50 991234650606200000002000000000807800 9912346
8
+ 20 9912346
9
+ 30 9912346060620
10
+ 40 39407150000000147700 5540020977
11
+ 40 39407640000000198100 5511115706
12
+ 40 39408300000000190700 5541008608
13
+ 40 39408890000000073100 5540093777
14
+ 40 39408890000000132100 5540006858
15
+ 40 39409620000000087600 5540094494
16
+ 40 39410690000000078500 5517551977
17
+ 40 39410770000000094900 5540021183
18
+ 40 39410850000000169300 5517035205
19
+ 40 39410930000000084100 5547510501
20
+ 40 39411010000000084900 5511100321
21
+ 40 39411190000000074200 5540022584
22
+ 40 39411350000000076900 5540025566
23
+ 40 39411430000000229300 5517540398
24
+ 40 39411500000000075500 5540097588
25
+ 40 39411680000000082700 5540009276
26
+ 40 39411760000000123900 5540021117
27
+ 40 39411840000000248300 5511053245
28
+ 40 39411840000000201100 5541008627
29
+ 40 39412000000000147700 5517043623
30
+ 40 39412180000000123000 5547510510
31
+ 40 39412260000000082700 5540022386
32
+ 40 39412340000000087700 5517003480
33
+ 40 39412420000000153800 5517537838
34
+ 40 39412590000000100000 5504092053
35
+ 40 39412750000000034000 5514040512
36
+ 40 39412750000000194000 5517061500
37
+ 40 39413740000000113700 5517041901
38
+ 40 39413740000000191300 5540043993
39
+ 40 39413900000000113400 LB 0005550731
40
+ 40 39414080000000158800 LB 0003334451
41
+ 40 39414240000000201700 5540020428
42
+ 40 39414570000000113400 5541008602
43
+ 40 39416060000000119900 5540026099
44
+ 40 39417050000000320800 5540011036
45
+ 50 99123460606200000035000000004708800
46
+ 90 0606200000037000000005516600
@@ -0,0 +1,45 @@
1
+ 00 060620 BANKGIROT
2
+ 10
3
+ 20 9912346
4
+ 30 9912346060620
5
+ 40 39407150000000147700 5540020977
6
+ 40 39407640000000198100 5511115706
7
+ 40 39408300000000190700 5541008608
8
+ 40 39408890000000073100 5540093777
9
+ 40 39408890000000132100 5540006858
10
+ 40 39409620000000087600 5540094494
11
+ 40 39410690000000078500 5517551977
12
+ 40 39410770000000094900 5540021183
13
+ 40 39410850000000169300 5517035205
14
+ 40 39410930000000084100 5547510501
15
+ 40 39411010000000084900 5511100321
16
+ 40 39411190000000074200 5540022584
17
+ 40 39411350000000076900 5540025566
18
+ 40 39411430000000229300 5517540398
19
+ 40 39411500000000075500 5540097588
20
+ 40 39411680000000082700 5540009276
21
+ 40 39411760000000123900 5540021117
22
+ 40 39411840000000248300 5511053245
23
+ 40 39411840000000201100 5541008627
24
+ 40 39412000000000147700 5517043623
25
+ 40 39412180000000123000 5547510510
26
+ 40 39412260000000082700 5540022386
27
+ 40 39412340000000087700 5517003480
28
+ 40 39412420000000153800 5517537838
29
+ 40 39412590000000100000 5504092053
30
+ 40 39412750000000034000 5514040512
31
+ 40 39412750000000194000 5517061500
32
+ 40 39412910000000200395 LB 0002582200
33
+ 40 39413740000000113700 5517041901
34
+ 40 39413740000000191300 5540043993
35
+ 40 39413900000000113400 LB 0005550731
36
+ 40 39414080000000158800 LB 0003334451
37
+ 40 39414240000000201700 5540020428
38
+ 40 39414570000000113400 5541008602
39
+ 40 39416060000000119900 5540026099
40
+ 40 39417050000000320800 5540011036
41
+ 40 8841298000000009989N 0002582200
42
+ 40 8841397000000010000- LB 0005550731
43
+ 50 99123460606200000038000000004709300
44
+ 90 0606200000038000000004709300
45
+
@@ -2,12 +2,14 @@ require 'helper'
2
2
 
3
3
  class TestTransaction < Test::Unit::TestCase
4
4
  def test_transaction
5
- transactions = Rbankgiro::Transactions.new(fixture_file_path('one_transaction_09_02_27.txt'), '53090965')
5
+ transactions = Rbankgiro::Transactions.new(fixture_file_path('one_transaction_09_02_27.txt'))
6
6
  transaction = transactions.first
7
7
 
8
8
  assert_equal(false, transaction.rounding?)
9
- assert_equal('86042103700000012', transaction.ocr)
9
+ assert_equal('86042103700000012', transaction.reference_number)
10
10
  assert_equal(1, transaction.amount)
11
+ assert_equal('53090965', transaction.bankgiro_number)
12
+ assert_equal('909897', transaction.service_number)
11
13
  assert_equal(Time.parse('Fri Feb 27 00:00:00 +0100 2009'), transaction.file_date)
12
14
  end
13
15
  end
@@ -2,41 +2,83 @@ require 'helper'
2
2
 
3
3
  class TestTransactions < Test::Unit::TestCase
4
4
  def test_one_transaction
5
- transactions = Rbankgiro::Transactions.new(fixture_file_path('one_transaction_09_02_27.txt'), '53090965')
5
+ transactions = Rbankgiro::Transactions.new(fixture_file_path('one_transaction_09_02_27.txt'))
6
6
 
7
7
  assert_equal(1, transactions.sum)
8
8
  assert_equal(1, transactions.length)
9
9
  assert_equal(Time.parse('Fri Feb 27 00:00:00 +0100 2009'), transactions.file_date)
10
10
  end
11
11
 
12
+ def test_multiple_transactions
13
+ transactions = Rbankgiro::Transactions.new(fixture_file_path('multiple_transactions_06_06_20.txt'))
14
+
15
+ # Test SEK
16
+ assert_equal(47093, transactions.sum)
17
+ assert_equal(38, transactions.length)
18
+ assert_equal(Time.parse('Tue Jun 20 00:00:00 +0200 2006'), transactions.file_date)
19
+
20
+ # Test LB flag
21
+ assert_equal(false, transactions[28].lb_flag)
22
+ assert transactions[27].lb_flag
23
+ assert transactions[30].lb_flag
24
+ assert transactions[31].lb_flag
25
+ assert transactions[36].lb_flag
26
+ assert transactions[37].lb_flag
27
+
28
+ # Test Öre
29
+ assert_equal(95, transactions[27].ore)
30
+ assert_equal(-95, transactions[36].ore)
31
+ end
32
+
33
+ def test_multiple_transaction_with_postgiro
34
+ transactions = Rbankgiro::Transactions.new(fixture_file_path('multiple_transactions_with_plusgiro_06_06_20.txt'))
35
+
36
+ assert_equal(55166, transactions.sum)
37
+ assert_equal(37, transactions.length)
38
+ assert_equal(Time.parse('Tue Jun 20 00:00:00 +0200 2006'), transactions.file_date)
39
+
40
+ for i in 0..1
41
+ assert_equal('99123465', transactions[i].bankgiro_number)
42
+ end
43
+
44
+ for i in 2..36
45
+ assert_equal('9912346', transactions[i].bankgiro_number)
46
+ end
47
+ end
48
+
49
+ def test_overpunch_without_lb_flag
50
+ assert_raise(Rbankgiro::FileFormatError) do
51
+ Rbankgiro::Transactions.new(fixture_file_path('overpunch_transaction_with_missing_lb_flag_06_06_20.txt'))
52
+ end
53
+ end
54
+
12
55
  def test_missing_transaction
13
56
  assert_raise(Rbankgiro::PartSumError) do
14
- Rbankgiro::Transactions.new(fixture_file_path('missing_transaction_09_02_27.txt'), '53090965')
57
+ Rbankgiro::Transactions.new(fixture_file_path('missing_transaction_09_02_27.txt'))
15
58
  end
16
59
  end
17
60
 
18
61
  def test_corrupt_header
19
62
  assert_raise(Rbankgiro::CorruptHeader) do
20
- Rbankgiro::Transactions.new(fixture_file_path('corrupt_header_09_02_27.txt'), '53090965')
63
+ Rbankgiro::Transactions.new(fixture_file_path('corrupt_header_09_02_27.txt'))
21
64
  end
22
65
  end
23
66
 
24
67
  def test_invalid_bankgiro_number
25
68
  assert_raise(Rbankgiro::InvalidBankgiroNumber) do
26
- Rbankgiro::Transactions.new(fixture_file_path('one_transaction_09_02_27.txt'), '53090966')
69
+ Rbankgiro::Transactions.new(fixture_file_path('invalid_bankgiro_number_09_02_27.txt'))
27
70
  end
28
71
  end
29
72
 
30
73
  def test_file_format_error
31
74
  assert_raise(Rbankgiro::FileFormatError) do
32
- Rbankgiro::Transactions.new(fixture_file_path('file_format_error_09_02_27.txt'), '53090965')
75
+ Rbankgiro::Transactions.new(fixture_file_path('file_format_error_09_02_27.txt'))
33
76
  end
34
77
  end
35
78
 
36
79
  def test_transaction_count_error
37
80
  assert_raise(Rbankgiro::TransactionCountError) do
38
- Rbankgiro::Transactions.new(fixture_file_path('one_too_many_transactions_09_02_27.txt'), '53090965')
81
+ Rbankgiro::Transactions.new(fixture_file_path('one_too_many_transactions_09_02_27.txt'))
39
82
  end
40
83
  end
41
-
42
84
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbankgiro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Johan Eckerstr\xC3\xB6m"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-06 00:00:00 +01:00
12
+ date: 2009-12-08 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,9 +29,13 @@ files:
29
29
  - rbankgiro.gemspec
30
30
  - test/fixtures/corrupt_header_09_02_27.txt
31
31
  - test/fixtures/file_format_error_09_02_27.txt
32
+ - test/fixtures/invalid_bankgiro_number_09_02_27.txt
32
33
  - test/fixtures/missing_transaction_09_02_27.txt
34
+ - test/fixtures/multiple_transactions_06_06_20.txt
35
+ - test/fixtures/multiple_transactions_with_plusgiro_06_06_20.txt
33
36
  - test/fixtures/one_too_many_transactions_09_02_27.txt
34
37
  - test/fixtures/one_transaction_09_02_27.txt
38
+ - test/fixtures/overpunch_transaction_with_missing_lb_flag_06_06_20.txt
35
39
  - test/helper.rb
36
40
  - test/test_transaction.rb
37
41
  - test/test_transactions.rb