Class: BankPayments::SpisuRecord

Inherits:
Object
  • Object
show all
Defined in:
lib/bank_payments/spisu_record.rb

Overview

An “abstract” class that is used by records that conforms to the SPISU-format for Swedbank international payments. It’s a flat file format that lets implementations easily describe each row similar to how the documentation is structured by the bank.

Author:

  • Michael Litton

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = ' ' * 80) {|_self| ... } ⇒ SpisuRecord

Returns a new instance of SpisuRecord.

Yields:

  • (_self)

Yield Parameters:



13
14
15
16
17
# File 'lib/bank_payments/spisu_record.rb', line 13

def initialize(data = ' ' * 80)
  @data   = data

  yield self if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *arguments, &block) ⇒ Object

Attempts to handle serialization and deserialization of numeric and text values in the SPISU



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/bank_payments/spisu_record.rb', line 82

def method_missing(method_name, *arguments, &block)
  record_fields   = self.class.defined_fields.keys
  requested_field = method_name.to_s.sub('=','').to_sym

  if record_fields.include?(requested_field)
    is_setter_field = method_name =~ /=/
    definition      = self.class.definition_for(requested_field)

    if is_setter_field
      args = [definition.start, definition.stop, arguments.first]
      case definition.type
        when 'N'  then set_numeric_value(*args)
        when 'AN' then set_text_value(*args)
      end
    else
      extract_field_value(definition)
    end
  else
    super
  end
end

Class Method Details

.define_field(field, definition) ⇒ Object

Used to set the attributes in child records during initialization. An example definition is

define_field :account, ‘2:9:N’

which means that the account is available in position 2 to 9. The third part of the definition includes the format of the field which can be

N: Numeric, zero pad to the left of the value AN: Alpha numeric, blank pad to the right of the value

define_field :f1, ‘2:9:N’ define_field :f2, ‘10:12:AN’



32
33
34
35
# File 'lib/bank_payments/spisu_record.rb', line 32

def self.define_field(field, definition)
  field_class = BankPayments::SwedbankExport::FieldDefinition
  (@fields ||= {})[field] = field_class.new(field, definition)
end

.defined_fieldsObject



37
38
39
# File 'lib/bank_payments/spisu_record.rb', line 37

def self.defined_fields
  @fields || {}
end

.definition_for(field) ⇒ Object



41
42
43
# File 'lib/bank_payments/spisu_record.rb', line 41

def self.definition_for(field)
  @fields[field]
end

.inherited(base) ⇒ Object

Ensure that we include the defined fields in the parent but still allow them to be overwritten. We can’t use @@fields because certain fields that share their name between classes will be overwritten



126
127
128
# File 'lib/bank_payments/spisu_record.rb', line 126

def self.inherited(base)
  base.instance_variable_set(:@fields, @fields)
end

Instance Method Details

#extract_date(field) ⇒ Object

Used in some child classes in order to construct a ruby Date from the the underlying data. Only used for imports of transaction confirmations



112
113
114
115
116
# File 'lib/bank_payments/spisu_record.rb', line 112

def extract_date(field)
  value      = extract_raw_value(field)
  parts      = value.scan(/\d{2}/)
  Date.new(2000 + parts[0].to_i, parts[1].to_i, parts[2].to_i)
end

#extract_field_value(definition) ⇒ Object



104
105
106
107
# File 'lib/bank_payments/spisu_record.rb', line 104

def extract_field_value(definition)
  return_value = @data[definition.start-1, definition.length]
  (return_value.sub(/^0+/, "") ||

#extract_raw_value(field) ⇒ Object



118
119
120
121
# File 'lib/bank_payments/spisu_record.rb', line 118

def extract_raw_value(field)
  definition = self.class.definition_for(field.to_sym)
  @data[definition.start-1, definition.length]
end

#serialize_value(val) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/bank_payments/spisu_record.rb', line 60

def serialize_value(val)
  if val.is_a?(Date)
    val.strftime('%y%m%d')
  else
    val.to_s
  end
end

#set_numeric_value(start, stop, value) ⇒ Object



50
51
52
# File 'lib/bank_payments/spisu_record.rb', line 50

def set_numeric_value(start, stop, value)
  set_value(start, stop, value, :rjust, '0')
end

#set_text_value(start, stop, value) ⇒ Object



45
46
47
48
# File 'lib/bank_payments/spisu_record.rb', line 45

def set_text_value(start, stop, value)
  value = UnicodeUtils.upcase(value, :sv)
  set_value(start, stop, value, :ljust, ' ')
end

#set_value(start, stop, value, direction = :ljust, padstr = ' ') ⇒ Object



54
55
56
57
58
# File 'lib/bank_payments/spisu_record.rb', line 54

def set_value(start, stop, value, direction = :ljust, padstr = ' ')
  value   = serialize_value(value)
  length  = stop - start + 1
  @data[start-1,length] = value[0,length].send(direction, *[length, padstr])
end

#to_sObject



76
77
78
# File 'lib/bank_payments/spisu_record.rb', line 76

def to_s
  @data
end

#typeObject



72
73
74
# File 'lib/bank_payments/spisu_record.rb', line 72

def type
  @data[0,1]
end

#type=(type) ⇒ Object



68
69
70
# File 'lib/bank_payments/spisu_record.rb', line 68

def type=(type)
  @data[0,1] = type.to_s
end