lib/cmxl/fields/transaction.rb
module Cmxl
module Fields
class Transaction < Field
self.tag = 61
self.parser = %r{^(?<date>\d{6})(?<entry_date>\d{4})?(?<storno_flag>R?)(?<funds_code>[CD]{1})(?<currency_letter>[a-zA-Z])?(?<amount>\d{1,12},\d{0,2})(?<swift_code>(?:N|F|S).{3})(?<reference>NONREF|(.(?!\/\/)){,16}([^\/]){,1})((?:\/\/)(?<bank_reference>[^\n]{,16}))?((?:\n)(?<supplementary>.{,34}))?$}
attr_accessor :details
def add_meta_data(content)
self.details = Cmxl::Fields::StatementDetails.parse(content) unless content.nil?
end
def sha
Digest::SHA2.new.update(source).to_s
end
def credit?
data['funds_code'].to_s.casecmp('C').zero?
end
def debit?
data['funds_code'].to_s.casecmp('D').zero?
end
def storno_credit?
credit? && storno?
end
def storno_debit?
debit? && storno?
end
def storno?
!storno_flag.empty?
end
def funds_code
data.values_at('storno_flag', 'funds_code').join
end
def storno_flag
data['storno_flag']
end
def sign
credit? ? 1 : -1
end
def amount
to_amount(data['amount'])
end
def amount_in_cents
to_amount_in_cents(data['amount'])
end
def date
to_date(data['date'])
end
def entry_date
return if !date || !data['entry_date']
e_date = to_date(data['entry_date'], date.year)
# we assume that valuta (date) and entry_date have a close connection. so valuta and entry_date should not be
# further apart than one month. this leads to some edge cases
# valuta is in january while entry_date is in december => entry_date was done the year before
e_date = to_date(data['entry_date'], date.year - 1) if date.month == 1 && e_date.month == 12
# valuta is in december but entry_date is in january => entry_date is actually in the year after valuta
e_date = to_date(data['entry_date'], date.year + 1) if date.month == 12 && e_date.month == 1
e_date
end
def supplementary
@supplementary ||= Cmxl::Fields::TransactionSupplementary.parse(data['supplementary'])
end
# Fields from supplementary
def initial_amount_in_cents
supplementary.initial_amount_in_cents
end
def initial_currency
supplementary.initial_currency
end
def charges_in_cents
supplementary.charges_in_cents
end
def charges_currency
supplementary.charges_currency
end
# Fields from details
def description
details.description if details
end
def information
details.information if details
end
def bic
details.bic if details
end
def name
details.name if details
end
def iban
details.iban if details
end
def sepa
details.sepa if details
end
def sub_fields
details.sub_fields if details
end
def primanota
details.primanota if details
end
def to_h
{
'sha' => sha,
'date' => date,
'entry_date' => entry_date,
'amount' => amount,
'amount_in_cents' => amount_in_cents,
'sign' => sign,
'debit' => debit?,
'credit' => credit?,
'storno' => storno?,
'funds_code' => funds_code,
'swift_code' => swift_code,
'reference' => reference,
'bank_reference' => bank_reference,
'currency_letter' => currency_letter
}.tap do |h|
h.merge!(details.to_h) if details
h.merge!(supplementary.to_h) if supplementary.source
end
end
def to_hash
to_h
end
def to_json(*args)
to_h.to_json(*args)
end
end
end
end