class SPS::Message

Attributes

account[R]
grouped_transactions[R]

Public Class Methods

new(account_options={}) click to toggle source
# File lib/sps_king/message.rb, line 19
def initialize(account_options={})
  @grouped_transactions = {}
  @account = account_class.new(account_options)
end

Public Instance Methods

add_transaction(options) click to toggle source
# File lib/sps_king/message.rb, line 24
def add_transaction(options)
  transaction = transaction_class.new(options)
  raise ArgumentError.new(transaction.errors.full_messages.join("\n")) unless transaction.valid?
  @grouped_transactions[transaction_group(transaction)] ||= []
  @grouped_transactions[transaction_group(transaction)] << transaction
end
amount_total(selected_transactions=transactions) click to toggle source
# File lib/sps_king/message.rb, line 53
def amount_total(selected_transactions=transactions)
  selected_transactions.inject(0) { |sum, t| sum + t.amount }
end
batch_id(transaction_reference) click to toggle source

Returns the id of the batch to which the given transaction belongs Identified based upon the reference of the transaction

# File lib/sps_king/message.rb, line 102
def batch_id(transaction_reference)
  grouped_transactions.each do |group, transactions|
    if transactions.select { |transaction| transaction.reference == transaction_reference }.any?
      return payment_information_identification(group)
    end
  end
end
batches() click to toggle source
# File lib/sps_king/message.rb, line 110
def batches
  grouped_transactions.keys.collect { |group| payment_information_identification(group) }
end
creation_date_time() click to toggle source

Get creation date time for the message (with fallback to Time.now.iso8601)

# File lib/sps_king/message.rb, line 96
def creation_date_time
  @creation_date_time ||= Time.now.iso8601
end
creation_date_time=(value) click to toggle source

Set creation date time for the message p.s. Rabobank in the Netherlands only accepts the more restricted format [0-9]4[0-9]2,2[0-9]2,2[0-9]2,2[0-9]2,2[0-9]{2,2}

# File lib/sps_king/message.rb, line 86
def creation_date_time=(value)
  raise ArgumentError.new('creation_date_time must be a string!') unless value.is_a?(String)

  regex = /[0-9]{4}[-][0-9]{2,2}[-][0-9]{2,2}(?:\s|T)[0-9]{2,2}[:][0-9]{2,2}[:][0-9]{2,2}/
  raise ArgumentError.new("creation_date_time does not match #{regex}!") unless value.match(regex)

  @creation_date_time = value
end
message_identification() click to toggle source

Get unique identifer for the message (with fallback to a random string)

# File lib/sps_king/message.rb, line 80
def message_identification
  @message_identification ||= "SPS-KING/#{SecureRandom.hex(11)}"
end
message_identification=(value) click to toggle source

Set unique identifer for the message

# File lib/sps_king/message.rb, line 70
def message_identification=(value)
  raise ArgumentError.new('message_identification must be a string!') unless value.is_a?(String)

  regex = /\A([A-Za-z0-9]|[\+|\?|\/|\-|\:|\(|\)|\.|\,|\'|\ ]){1,35}\z/
  raise ArgumentError.new("message_identification does not match #{regex}!") unless value.match(regex)

  @message_identification = value
end
schema_compatible?(schema_name) click to toggle source
# File lib/sps_king/message.rb, line 57
def schema_compatible?(schema_name)
  raise ArgumentError.new("Schema #{schema_name} is unknown!") unless self.known_schemas.include?(schema_name)

  case schema_name
    when PAIN_001_001_03_CH_02
      transactions.all? { |t| t.schema_compatible?(schema_name) }
    when PAIN_008_001_02_CH_03
      transactions.all? { |t| t.schema_compatible?(schema_name) } &&
      !account.iban.to_s.match(/^(CH|LI)/).nil? # Only allowed for switzerland or liechtenstein
  end
end
to_xml(schema_name=self.known_schemas.first) click to toggle source

@return [String] xml

# File lib/sps_king/message.rb, line 36
def to_xml(schema_name=self.known_schemas.first)
  raise SPS::Error.new(errors.full_messages.join("\n")) unless valid?
  raise SPS::Error.new("Incompatible with schema #{schema_name}!") unless schema_compatible?(schema_name)

  builder = Nokogiri::XML::Builder.new do |builder|
    builder.Document(xml_schema(schema_name)) do
      builder.__send__(xml_main_tag) do
        build_group_header(builder)
        build_payment_informations(builder)
      end
    end
  end

  validate_final_document!(builder.doc, schema_name)
  builder.to_xml
end
transactions() click to toggle source
# File lib/sps_king/message.rb, line 31
def transactions
  grouped_transactions.values.flatten
end

Private Instance Methods

build_group_header(builder) click to toggle source
# File lib/sps_king/message.rb, line 124
def build_group_header(builder)
  builder.GrpHdr do
    builder.MsgId(message_identification)
    builder.CreDtTm(creation_date_time)
    builder.NbOfTxs(transactions.length)
    builder.CtrlSum('%.2f' % amount_total)
    builder.InitgPty do
      builder.Nm(account.name)
      builder.Id do
        builder.OrgId do
          builder.Othr do
            builder.Id(account.creditor_identifier)
          end
        end
      end if account.respond_to? :creditor_identifier
    end
  end
end
payment_information_identification(group) click to toggle source

Unique and consecutive identifier (used for the <PmntInf> blocks)

# File lib/sps_king/message.rb, line 144
def payment_information_identification(group)
  "#{message_identification}/#{grouped_transactions.keys.index(group)+1}"
end
transaction_group(transaction) click to toggle source

Returns a key to determine the group to which the transaction belongs

# File lib/sps_king/message.rb, line 149
def transaction_group(transaction)
  transaction
end
validate_final_document!(document, schema_name) click to toggle source
# File lib/sps_king/message.rb, line 153
def validate_final_document!(document, schema_name)
  xsd = Nokogiri::XML::Schema(
          File.read(
            File.expand_path("../../../lib/schema/#{schema_name}.xsd", __FILE__)
          )
        )
  errors = xsd.validate(document).map { |error| error.message }
  raise SPS::Error.new("Incompatible with schema #{schema_name}: #{errors.join(', ')}") if errors.any?
end
xml_schema(schema_name) click to toggle source

@return {Hash<Symbol=>String>} xml schema information used in output xml

# File lib/sps_king/message.rb, line 116
def xml_schema(schema_name)
  {
    :xmlns                => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd",
    :'xmlns:xsi'          => 'http://www.w3.org/2001/XMLSchema-instance',
    :'xsi:schemaLocation' => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd #{schema_name}.xsd"
  }
end