rbankgiro 0.1.3 → 0.2.0

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