konto_check_ruby 1.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +26 -0
- data/COPYRIGHT +22 -0
- data/LICENSE +504 -0
- data/README.md +295 -0
- data/bin/konto_check_ruby +202 -0
- data/data/README.md +17 -0
- data/data/blz.lut2f +0 -0
- data/data/iban_regeln.txt +1260 -0
- data/lib/konto_check_ruby/bank_data.rb +421 -0
- data/lib/konto_check_ruby/blz_file.rb +705 -0
- data/lib/konto_check_ruby/check_methods/part1.rb +1634 -0
- data/lib/konto_check_ruby/check_methods/part2.rb +1604 -0
- data/lib/konto_check_ruby/check_methods/part3.rb +1905 -0
- data/lib/konto_check_ruby/check_methods/part4.rb +1738 -0
- data/lib/konto_check_ruby/check_methods/part5.rb +1407 -0
- data/lib/konto_check_ruby/check_methods.rb +147 -0
- data/lib/konto_check_ruby/collation.rb +52 -0
- data/lib/konto_check_ruby/engine.rb +1006 -0
- data/lib/konto_check_ruby/iban_rules.rb +1060 -0
- data/lib/konto_check_ruby/konto_check.rb +1578 -0
- data/lib/konto_check_ruby/lut_file.rb +457 -0
- data/lib/konto_check_ruby/raw.rb +614 -0
- data/lib/konto_check_ruby/retvals.rb +826 -0
- data/lib/konto_check_ruby/search.rb +440 -0
- data/lib/konto_check_ruby/update.rb +176 -0
- data/lib/konto_check_ruby/version.rb +18 -0
- data/lib/konto_check_ruby.rb +42 -0
- metadata +112 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of konto_check_ruby, a Ruby port of the C library
|
|
4
|
+
# konto_check, Copyright (C) 2002-2023 Michael Plugge <konto_check@yahoo.com>.
|
|
5
|
+
# Ruby port Copyright (C) 2026 tickettoaster GmbH <https://tickettoaster.de>.
|
|
6
|
+
#
|
|
7
|
+
# konto_check_ruby is free software; you can redistribute it and/or modify it
|
|
8
|
+
# under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
# the Free Software Foundation; either version 2.1 of the License, or (at
|
|
10
|
+
# your option) any later version. It is distributed WITHOUT ANY WARRANTY; see
|
|
11
|
+
# the file LICENSE for details.
|
|
12
|
+
|
|
13
|
+
require_relative "retvals"
|
|
14
|
+
require_relative "lut_file"
|
|
15
|
+
require_relative "blz_file"
|
|
16
|
+
|
|
17
|
+
module KontoCheckRuby
|
|
18
|
+
# In-memory representation of the bank directory: the arrays of the C
|
|
19
|
+
# library (blz, pz_methoden, filialen, startidx, name, ort, ...) plus a hash
|
|
20
|
+
# for the BLZ lookup. The data can be loaded either from a LUT2 file (block
|
|
21
|
+
# by block, like kto_check_init() in C) or directly from the records of a
|
|
22
|
+
# Bundesbank file (BlzFile.parse_file).
|
|
23
|
+
#
|
|
24
|
+
# Indexing follows the C library: the "main office" arrays (blz, pz,
|
|
25
|
+
# filialen, startidx) are indexed 0...cnt_hs, the per-branch arrays (name,
|
|
26
|
+
# name_kurz, plz, ort, pan, bic, nr, aenderung, loeschung, nachfolge_blz,
|
|
27
|
+
# iban_regel) are indexed startidx[idx] + zweigstelle (0...cnt).
|
|
28
|
+
class BankData
|
|
29
|
+
# main office arrays
|
|
30
|
+
attr_reader :cnt_hs, :cnt, :blz, :pz, :filialen, :startidx
|
|
31
|
+
# per branch arrays (nil if the block was not loaded)
|
|
32
|
+
attr_reader :name, :name_kurz, :plz, :ort, :pan, :bic, :bic_h, :nr, :aenderung, :loeschung,
|
|
33
|
+
:nachfolge_blz, :iban_regel, :hs_idx, :startidx_r
|
|
34
|
+
# IBAN blacklist (Array of BLZ Integers, first element 2718281 marks the list) or nil
|
|
35
|
+
attr_reader :own_iban
|
|
36
|
+
# meta data
|
|
37
|
+
attr_reader :info, :valid_from, :valid_to, :lut_id, :block_status, :source, :set
|
|
38
|
+
attr_accessor :level
|
|
39
|
+
|
|
40
|
+
EMPTY_BIC = " " # 11 blanks, like the C library for a missing BIC
|
|
41
|
+
|
|
42
|
+
def initialize
|
|
43
|
+
@cnt_hs = 0
|
|
44
|
+
@cnt = 0
|
|
45
|
+
@blz = []
|
|
46
|
+
@pz = nil
|
|
47
|
+
@filialen = nil
|
|
48
|
+
@startidx = []
|
|
49
|
+
@hs_idx = []
|
|
50
|
+
@startidx_r = []
|
|
51
|
+
@block_status = {}
|
|
52
|
+
@info = nil
|
|
53
|
+
@valid_from = 0
|
|
54
|
+
@valid_to = 0
|
|
55
|
+
@lut_id = ""
|
|
56
|
+
@source = nil
|
|
57
|
+
@set = 0
|
|
58
|
+
@level = -1
|
|
59
|
+
@index = {}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# ---------------------------------------------------------------- lookup
|
|
63
|
+
|
|
64
|
+
# Index of a BLZ (Integer) in the main office arrays, or nil
|
|
65
|
+
def index(blz_int)
|
|
66
|
+
@index[blz_int]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def loaded?(typ)
|
|
70
|
+
@block_status[typ] == OK
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def branches?
|
|
74
|
+
!@filialen.nil?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Number of branches of the bank at idx (1 if the file has no branches)
|
|
78
|
+
def filialen_at(idx)
|
|
79
|
+
@filialen ? @filialen[idx] : 1
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Validity of the loaded data set for the given date (Integer JJJJMMTT)
|
|
83
|
+
def valid(current_date)
|
|
84
|
+
return LUT2_NO_VALID_DATE if @valid_from == 0 || @valid_to == 0
|
|
85
|
+
return LUT2_VALID if current_date >= @valid_from && current_date <= @valid_to
|
|
86
|
+
return LUT2_NOT_YET_VALID if current_date < @valid_from
|
|
87
|
+
LUT2_NO_LONGER_VALID
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Info text of the loaded set plus the list of loaded blocks (lut_info in C)
|
|
91
|
+
def info_text
|
|
92
|
+
return nil unless @info
|
|
93
|
+
loaded = (1..LutFile::SET_OFFSET - 1).select { |t| @block_status[t] == OK }.map { |t| LutFile.block_name(t) }
|
|
94
|
+
"#{@info}\nin den Speicher geladene Blocks:\n #{loaded.join(', ')}\n"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# ------------------------------------------------------ loading from LUT
|
|
98
|
+
|
|
99
|
+
# Loads the requested blocks from a LUT2 file. required is an Array of
|
|
100
|
+
# block types (the mandatory blocks BLZ, FILIALEN, PZ and AENDERUNG are
|
|
101
|
+
# always added), set 0 selects the currently valid data set.
|
|
102
|
+
# Returns [code, BankData]; code is OK, LUT2_PARTIAL_OK (some requested
|
|
103
|
+
# blocks are missing) or an error code.
|
|
104
|
+
def self.from_lut(filename, required: BlzFile::LUT_SETS[5], set: 0, current_date: LutFile.today_int)
|
|
105
|
+
data = new
|
|
106
|
+
code = data.load_lut(filename, required: required, set: set, current_date: current_date)
|
|
107
|
+
[code, data]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def load_lut(filename, required:, set: 0, current_date: LutFile.today_int)
|
|
111
|
+
return FILE_READ_ERROR unless File.file?(filename)
|
|
112
|
+
code, info1, info2, v1, v2 = LutFile.info(filename, current_date)
|
|
113
|
+
return code if [FILE_READ_ERROR, INVALID_LUT_FILE, LUT1_FILE_USED].include?(code)
|
|
114
|
+
if code == OK
|
|
115
|
+
if set == 0
|
|
116
|
+
# the valid set; if none is valid the younger one (the C library
|
|
117
|
+
# always falls back to the first set)
|
|
118
|
+
set = if v1 == LUT2_VALID then 1
|
|
119
|
+
elsif v2 == LUT2_VALID then 2
|
|
120
|
+
elsif v1 == LUT2_NO_VALID_DATE then 1
|
|
121
|
+
elsif v2 == LUT2_NO_VALID_DATE then 2
|
|
122
|
+
elsif v2 == LUT2_NO_LONGER_VALID_BETTER then 2
|
|
123
|
+
else 1
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
@info = set == 1 ? info1 : info2
|
|
127
|
+
return LUT2_BLOCK_NOT_IN_FILE unless @info
|
|
128
|
+
@valid_from, @valid_to = LutFile.parse_validity(@info)
|
|
129
|
+
@lut_id = LutFile.file_id(@info) || ""
|
|
130
|
+
else
|
|
131
|
+
set = 1 if set == 0
|
|
132
|
+
@info = nil
|
|
133
|
+
@valid_from = @valid_to = 0
|
|
134
|
+
@lut_id = ""
|
|
135
|
+
end
|
|
136
|
+
@source = filename
|
|
137
|
+
@set = set
|
|
138
|
+
load_blocks(required)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Loads further blocks from the LUT file the data came from (incremental
|
|
142
|
+
# initialisation). Returns OK, LUT2_PARTIAL_OK or an error code.
|
|
143
|
+
def load_blocks(required)
|
|
144
|
+
return LUT2_NOT_INITIALIZED unless @source && File.file?(@source)
|
|
145
|
+
offset = @set == 2 ? LutFile::SET_OFFSET : 0
|
|
146
|
+
wanted = [LUT2_BLZ, LUT2_FILIALEN, LUT2_PZ, LUT2_AENDERUNG]
|
|
147
|
+
required.each { |t| wanted << (t > LutFile::SET_OFFSET ? t - LutFile::SET_OFFSET : t) }
|
|
148
|
+
wanted.uniq!
|
|
149
|
+
alles_ok = true
|
|
150
|
+
File.open(@source, "rb") do |io|
|
|
151
|
+
code, dir = LutFile.read_directory(io)
|
|
152
|
+
return code unless code == OK
|
|
153
|
+
queue = wanted.dup
|
|
154
|
+
until queue.empty?
|
|
155
|
+
typ1 = queue.shift
|
|
156
|
+
next if @block_status[typ1] == OK
|
|
157
|
+
typ = typ1 + offset
|
|
158
|
+
code, data = LutFile.read_block_io(io, dir, typ: typ)
|
|
159
|
+
case code
|
|
160
|
+
when OK
|
|
161
|
+
@block_status[typ] = @block_status[typ1] = OK
|
|
162
|
+
parse_block(typ1, data)
|
|
163
|
+
when LUT2_BLOCK_NOT_IN_FILE
|
|
164
|
+
if typ1 == LUT2_NAME_NAME_KURZ
|
|
165
|
+
# name and short name may be stored in separate blocks
|
|
166
|
+
queue.unshift(LUT2_NAME_KURZ)
|
|
167
|
+
c2, d2 = LutFile.read_block_io(io, dir, typ: LUT2_NAME + offset)
|
|
168
|
+
if c2 == OK
|
|
169
|
+
@block_status[LUT2_NAME + offset] = @block_status[LUT2_NAME] = OK
|
|
170
|
+
parse_block(LUT2_NAME, d2)
|
|
171
|
+
next
|
|
172
|
+
end
|
|
173
|
+
elsif typ1 == LUT2_NAME || typ1 == LUT2_NAME_KURZ
|
|
174
|
+
c2, d2 = LutFile.read_block_io(io, dir, typ: LUT2_NAME_NAME_KURZ + offset)
|
|
175
|
+
if c2 == OK
|
|
176
|
+
@block_status[LUT2_NAME_NAME_KURZ + offset] = @block_status[LUT2_NAME_NAME_KURZ] = OK
|
|
177
|
+
parse_block(LUT2_NAME_NAME_KURZ, d2)
|
|
178
|
+
next
|
|
179
|
+
end
|
|
180
|
+
elsif typ1 == LUT2_OWN_IBAN
|
|
181
|
+
# the blacklist may be stored in the other set
|
|
182
|
+
other = typ == LUT2_OWN_IBAN ? LUT2_2_OWN_IBAN : LUT2_OWN_IBAN
|
|
183
|
+
c2, d2 = LutFile.read_block_io(io, dir, typ: other)
|
|
184
|
+
if c2 == OK
|
|
185
|
+
@block_status[typ] = @block_status[typ1] = OK
|
|
186
|
+
parse_block(LUT2_OWN_IBAN, d2)
|
|
187
|
+
next
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
@block_status[typ] = @block_status[typ1] = code
|
|
191
|
+
# missing branch counts or blacklist are not an error
|
|
192
|
+
alles_ok = false unless [LUT2_FILIALEN, LUT2_OWN_IBAN].include?(typ1)
|
|
193
|
+
when LUT2_FILE_CORRUPTED, KTO_CHECK_UNSUPPORTED_COMPRESSION
|
|
194
|
+
@block_status[typ] = @block_status[typ1] = code
|
|
195
|
+
return code
|
|
196
|
+
else
|
|
197
|
+
@block_status[typ] = @block_status[typ1] = code
|
|
198
|
+
alles_ok = false
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
return LUT2_NOT_INITIALIZED if @blz.empty? || @pz.nil?
|
|
203
|
+
finish_indexes
|
|
204
|
+
return OK if alles_ok
|
|
205
|
+
case valid(LutFile.today_int)
|
|
206
|
+
when LUT2_NO_LONGER_VALID then LUT2_NO_LONGER_VALID_PARTIAL_OK
|
|
207
|
+
when LUT2_NOT_YET_VALID then LUT2_NOT_YET_VALID_PARTIAL_OK
|
|
208
|
+
else LUT2_PARTIAL_OK
|
|
209
|
+
end
|
|
210
|
+
rescue SystemCallError
|
|
211
|
+
FILE_READ_ERROR
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def parse_block(typ, data)
|
|
215
|
+
case typ
|
|
216
|
+
when LUT2_BLZ then parse_blz(data)
|
|
217
|
+
when LUT2_FILIALEN then parse_filialen(data)
|
|
218
|
+
when LUT2_PZ then @pz = data.unpack("C*")
|
|
219
|
+
when LUT2_NAME
|
|
220
|
+
strings = split_strings(data)
|
|
221
|
+
@name = resolve_hs_names(strings)
|
|
222
|
+
when LUT2_NAME_KURZ then @name_kurz = split_strings(data).map { |s| iso(s) }
|
|
223
|
+
when LUT2_NAME_NAME_KURZ
|
|
224
|
+
strings = split_strings(data)
|
|
225
|
+
names = []
|
|
226
|
+
kurz = []
|
|
227
|
+
strings.each_slice(2) do |n, k|
|
|
228
|
+
names << n
|
|
229
|
+
kurz << (k || "")
|
|
230
|
+
end
|
|
231
|
+
@name = resolve_hs_names(names)
|
|
232
|
+
@name_kurz = kurz.map { |s| iso(s) }
|
|
233
|
+
@block_status[LUT2_NAME] = OK
|
|
234
|
+
@block_status[LUT2_NAME_KURZ] = OK
|
|
235
|
+
when LUT2_PLZ then @plz = unpack_u24(data)
|
|
236
|
+
when LUT2_ORT then @ort = split_strings(data).map { |s| iso(s) }
|
|
237
|
+
when LUT2_IBAN_REGEL then @iban_regel = unpack_u24(data)
|
|
238
|
+
when LUT2_PAN then @pan = unpack_u24(data)
|
|
239
|
+
when LUT2_BIC then parse_bic(data)
|
|
240
|
+
when LUT2_NR then @nr = unpack_u24(data)
|
|
241
|
+
when LUT2_AENDERUNG then @aenderung = data.chars.map { |c| c.force_encoding("UTF-8") }
|
|
242
|
+
when LUT2_LOESCHUNG then @loeschung = data.chars.map { |c| c.force_encoding("UTF-8") }
|
|
243
|
+
when LUT2_NACHFOLGE_BLZ then @nachfolge_blz = data.unpack("V*")
|
|
244
|
+
when LUT2_OWN_IBAN
|
|
245
|
+
cnt = data.unpack1("V")
|
|
246
|
+
@own_iban = data.byteslice(4, cnt * 4).unpack("V*")
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
private
|
|
251
|
+
|
|
252
|
+
def iso(s)
|
|
253
|
+
s.force_encoding("ISO-8859-1").encode("UTF-8")
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def split_strings(data)
|
|
257
|
+
# strings are NUL terminated; a trailing NUL produces no extra element
|
|
258
|
+
parts = data.split("\0", -1)
|
|
259
|
+
parts.pop if parts.last == ""
|
|
260
|
+
parts
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Byte 1 at the start marks a main office name, an empty string means
|
|
264
|
+
# "same name as the main office".
|
|
265
|
+
def resolve_hs_names(strings)
|
|
266
|
+
hs = ""
|
|
267
|
+
strings.map do |s|
|
|
268
|
+
if s.getbyte(0) == 1
|
|
269
|
+
hs = iso(s.byteslice(1..))
|
|
270
|
+
hs
|
|
271
|
+
elsif s.empty?
|
|
272
|
+
hs
|
|
273
|
+
else
|
|
274
|
+
iso(s)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def unpack_u24(data)
|
|
280
|
+
out = []
|
|
281
|
+
i = 0
|
|
282
|
+
n = data.bytesize
|
|
283
|
+
while i + 2 < n
|
|
284
|
+
out << (data.getbyte(i) | (data.getbyte(i + 1) << 8) | (data.getbyte(i + 2) << 16))
|
|
285
|
+
i += 3
|
|
286
|
+
end
|
|
287
|
+
out
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def parse_blz(data)
|
|
291
|
+
@cnt_hs, @cnt = data.unpack("vv")
|
|
292
|
+
@blz = []
|
|
293
|
+
pos = 4
|
|
294
|
+
prev = 0
|
|
295
|
+
while @blz.size < @cnt_hs && pos < data.bytesize
|
|
296
|
+
j = data.getbyte(pos)
|
|
297
|
+
pos += 1
|
|
298
|
+
case j
|
|
299
|
+
when 254
|
|
300
|
+
prev += data.byteslice(pos, 2).unpack1("v")
|
|
301
|
+
pos += 2
|
|
302
|
+
when 255
|
|
303
|
+
prev = data.byteslice(pos, 4).unpack1("V")
|
|
304
|
+
pos += 4
|
|
305
|
+
else
|
|
306
|
+
prev += j
|
|
307
|
+
end
|
|
308
|
+
@blz << prev
|
|
309
|
+
end
|
|
310
|
+
@startidx = (0...@cnt_hs).to_a
|
|
311
|
+
@index = {}
|
|
312
|
+
@blz.each_with_index { |b, i| @index[b] = i }
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def parse_filialen(data)
|
|
316
|
+
@filialen = data.unpack("C*")
|
|
317
|
+
j = 0
|
|
318
|
+
@filialen.each_with_index do |f, i|
|
|
319
|
+
@startidx[i] = i + j
|
|
320
|
+
j += f - 1
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def parse_bic(data)
|
|
325
|
+
@bic = []
|
|
326
|
+
pos = 0
|
|
327
|
+
n = data.bytesize
|
|
328
|
+
while pos < n && @bic.size < [@cnt, 1].max
|
|
329
|
+
c = data.getbyte(pos)
|
|
330
|
+
if c == 0
|
|
331
|
+
@bic << EMPTY_BIC
|
|
332
|
+
pos += 1
|
|
333
|
+
elsif c == 1
|
|
334
|
+
@bic << data.byteslice(pos + 1, 11).force_encoding("UTF-8")
|
|
335
|
+
pos += 12
|
|
336
|
+
else
|
|
337
|
+
s = data.byteslice(pos, 9)
|
|
338
|
+
@bic << (s[0, 4] + "DE" + s[4, 5]).force_encoding("UTF-8")
|
|
339
|
+
pos += 9
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Builds the reciprocal indexes (hs_idx, startidx_r) and bic_h.
|
|
345
|
+
def finish_indexes
|
|
346
|
+
# without the FILIALEN block only the main offices are in the arrays
|
|
347
|
+
@cnt = @cnt_hs if @filialen.nil?
|
|
348
|
+
@hs_idx = Array.new(@cnt, 0)
|
|
349
|
+
@startidx_r = Array.new(@cnt, 0)
|
|
350
|
+
@cnt_hs.times do |i|
|
|
351
|
+
f = filialen_at(i)
|
|
352
|
+
s = @startidx[i]
|
|
353
|
+
f.times do |k|
|
|
354
|
+
@hs_idx[s + k] = s
|
|
355
|
+
@startidx_r[s + k] = i
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
@bic_h = @bic ? @bic.each_index.map { |j| @bic[@hs_idx[j] || j] || EMPTY_BIC } : nil
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
public
|
|
362
|
+
|
|
363
|
+
# ------------------------------------------- loading from Bundesbank data
|
|
364
|
+
|
|
365
|
+
# Builds the data set directly from BankRecords (see BlzFile). All blocks
|
|
366
|
+
# are available afterwards.
|
|
367
|
+
def self.from_records(records, source: nil, info: nil, valid_from: 0, valid_to: 0)
|
|
368
|
+
data = new
|
|
369
|
+
data.load_records(records, source: source, info: info, valid_from: valid_from, valid_to: valid_to)
|
|
370
|
+
data
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
def load_records(records, source: nil, info: nil, valid_from: 0, valid_to: 0)
|
|
374
|
+
sorted = BlzFile.sort_records(records)
|
|
375
|
+
@source = source
|
|
376
|
+
@set = 1
|
|
377
|
+
@cnt = sorted.size
|
|
378
|
+
@blz = []
|
|
379
|
+
@pz = []
|
|
380
|
+
@filialen = []
|
|
381
|
+
@startidx = []
|
|
382
|
+
@index = {}
|
|
383
|
+
sorted.each_with_index do |r, i|
|
|
384
|
+
if @blz.last == r.blz
|
|
385
|
+
@filialen[-1] += 1
|
|
386
|
+
@pz[-1] = r.pz if @pz_from_branch && (r.hauptstelle == "1" || r.hauptstelle == "3")
|
|
387
|
+
else
|
|
388
|
+
@index[r.blz] = @blz.size
|
|
389
|
+
@blz << r.blz
|
|
390
|
+
@pz << r.pz
|
|
391
|
+
@pz_from_branch = !(r.hauptstelle == "1" || r.hauptstelle == "3")
|
|
392
|
+
@filialen << 1
|
|
393
|
+
@startidx << i
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
@pz_from_branch = nil
|
|
397
|
+
@cnt_hs = @blz.size
|
|
398
|
+
@name = sorted.map(&:name)
|
|
399
|
+
@name_kurz = sorted.map(&:name_kurz)
|
|
400
|
+
@plz = sorted.map(&:plz)
|
|
401
|
+
@ort = sorted.map(&:ort)
|
|
402
|
+
@pan = sorted.map(&:pan)
|
|
403
|
+
@bic = sorted.map { |r| r.bic.empty? ? EMPTY_BIC : r.bic.ljust(11) }
|
|
404
|
+
@nr = sorted.map(&:nr)
|
|
405
|
+
@aenderung = sorted.map(&:aenderung)
|
|
406
|
+
@loeschung = sorted.map(&:loeschung)
|
|
407
|
+
@nachfolge_blz = sorted.map(&:nachfolge_blz)
|
|
408
|
+
@iban_regel = sorted.map(&:iban_regel)
|
|
409
|
+
[LUT2_BLZ, LUT2_FILIALEN, LUT2_PZ, LUT2_NAME, LUT2_NAME_KURZ, LUT2_NAME_NAME_KURZ, LUT2_PLZ, LUT2_ORT,
|
|
410
|
+
LUT2_PAN, LUT2_BIC, LUT2_NR, LUT2_AENDERUNG, LUT2_LOESCHUNG, LUT2_NACHFOLGE_BLZ,
|
|
411
|
+
LUT2_IBAN_REGEL].each { |t| @block_status[t] = OK }
|
|
412
|
+
@valid_from = valid_from
|
|
413
|
+
@valid_to = valid_to
|
|
414
|
+
@info = info || format("Gueltigkeit der Daten: %08d-%08d (Erster Datensatz)\nEnthaltene Felder: BLZ, PZ, FILIALEN, AENDERUNG, NAME_NAME_KURZ, PLZ, ORT, IBAN_REGEL, BIC, NACHFOLGE_BLZ, LOESCHUNG, PAN, NR\n\nDatensatz aus %s\nAnzahl Banken: %d, davon Hauptstellen: %d\n",
|
|
415
|
+
valid_from, valid_to, source || "Bundesbank-Datei", @cnt, @cnt_hs)
|
|
416
|
+
@lut_id = ""
|
|
417
|
+
finish_indexes
|
|
418
|
+
OK
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|