rbankgiro 0.1.0 → 0.1.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.
- data/lib/rbankgiro.rb +119 -0
- metadata +3 -3
data/lib/rbankgiro.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Rbankgiro
|
4
|
+
class CorruptHeader < StandardError; end
|
5
|
+
class InvalidBankgiroNumber < StandardError; end
|
6
|
+
class FileFormatError < StandardError; end
|
7
|
+
class TransactionCountError < StandardError; end
|
8
|
+
class PartSumError < StandardError; end
|
9
|
+
|
10
|
+
# A Rbankgiro transaction, contains OCR-number for the transaction
|
11
|
+
# amount in SEK and the transaction date
|
12
|
+
class Transaction
|
13
|
+
attr_reader :amount, :ocr, :file_date
|
14
|
+
|
15
|
+
def initialize(ocr, raw_amount, file_date)
|
16
|
+
@raw_amount = raw_amount
|
17
|
+
@ocr = ocr
|
18
|
+
@amount = raw_amount.split('')[0..-3].join.to_i
|
19
|
+
@file_date = file_date
|
20
|
+
end
|
21
|
+
|
22
|
+
# If the amount last two characters aren't 00,
|
23
|
+
# there has been some kind of rounding
|
24
|
+
def rounding?
|
25
|
+
@raw_amount.split('')[-2..-1].join != '00'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Transactions < Array
|
30
|
+
attr_reader :file_date
|
31
|
+
|
32
|
+
# Parses an OCR transaction file from Rbankgirocentralen
|
33
|
+
# 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|
|
39
|
+
next if row.strip.empty? # Skip empty rows
|
40
|
+
parse_row(row)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def sum
|
45
|
+
self.collect {|t| t.amount }.reduce(:+)
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
sprintf("#<%s:0x%x %s>", self.class.name, __id__,
|
50
|
+
"@sum=#{self.sum}, @length=#{self.length}, @file_date=#{self.file_date}")
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def parse_row(row)
|
56
|
+
columns = row.scan(/\w+/).collect {|c| c.strip }
|
57
|
+
case columns.first
|
58
|
+
when '00909897'
|
59
|
+
# The first row if a File header, should look like:
|
60
|
+
# 00909897 <6:date> BANKGIROT
|
61
|
+
raise CorruptHeader unless columns[2] == 'BANKGIROT'
|
62
|
+
@raw_file_date = columns[1]
|
63
|
+
@file_date = Time.parse(@raw_file_date)
|
64
|
+
when '10'
|
65
|
+
when '20'
|
66
|
+
# Specifies the bankgiro number:
|
67
|
+
# <8:bankgiro number>
|
68
|
+
raise InvalidBankgiroNumber unless columns[1] == @bankgiro_number
|
69
|
+
when '30'
|
70
|
+
# Specifies the bankgiro number with the transaction date after:
|
71
|
+
# <8:bankgiro number><6:date>
|
72
|
+
raise FileFormatError unless columns[1] == @bankgiro_number + @raw_file_date
|
73
|
+
when '40'
|
74
|
+
# 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)
|
80
|
+
else
|
81
|
+
raise FileFormatError
|
82
|
+
end
|
83
|
+
when '50'
|
84
|
+
# 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})$/)
|
87
|
+
bankgiro_number_control = r[1]
|
88
|
+
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
|
+
|
93
|
+
else
|
94
|
+
raise FileFormatError
|
95
|
+
end
|
96
|
+
|
97
|
+
raise PartSumError unless payments_sum == self.collect {|t| t.amount }.reduce(:+)
|
98
|
+
raise TransactionCountError unless number_of_transactions.to_i == self.length
|
99
|
+
when '90'
|
100
|
+
# 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})$/)
|
103
|
+
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
|
107
|
+
else
|
108
|
+
raise FileFormatError
|
109
|
+
end
|
110
|
+
|
111
|
+
raise PartSumError unless payments_sum == self.collect {|t| t.amount }.reduce(:+)
|
112
|
+
raise TransactionCountError unless number_of_transactions.to_i == self.length
|
113
|
+
else
|
114
|
+
# Should be handled by previous cases, if it goes here something is wrong
|
115
|
+
raise FileFormatError
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
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.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Johan Eckerstr\xC3\xB6m"
|
@@ -21,8 +21,8 @@ extensions: []
|
|
21
21
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
|
-
files:
|
25
|
-
|
24
|
+
files:
|
25
|
+
- lib/rbankgiro.rb
|
26
26
|
has_rdoc: true
|
27
27
|
homepage: http://github.com/jage/rbankgiro
|
28
28
|
licenses: []
|