lib/sepa_king/message/direct_debit.rb
# encoding: utf-8
module SEPA
class DirectDebit < Message
self.account_class = CreditorAccount
self.transaction_class = DirectDebitTransaction
self.xml_main_tag = 'CstmrDrctDbtInitn'
self.known_schemas = [ PAIN_008_001_02, PAIN_008_003_02, PAIN_008_002_02 ]
validate do |record|
if record.transactions.map(&:local_instrument).uniq.size > 1
errors.add(:base, 'CORE, COR1 AND B2B must not be mixed in one message!')
end
end
private
# Find groups of transactions which share the same values of some attributes
def transaction_group(transaction)
{ requested_date: transaction.requested_date,
local_instrument: transaction.local_instrument,
sequence_type: transaction.sequence_type,
batch_booking: transaction.batch_booking,
account: transaction.creditor_account || account
}
end
def build_payment_informations(builder, schema_name)
# Build a PmtInf block for every group of transactions
grouped_transactions.each do |group, transactions|
builder.PmtInf do
builder.PmtInfId(payment_information_identification(group))
builder.PmtMtd('DD')
builder.BtchBookg(group[:batch_booking])
builder.NbOfTxs(transactions.length)
builder.CtrlSum('%.2f' % amount_total(transactions))
builder.PmtTpInf do
builder.SvcLvl do
builder.Cd('SEPA')
end
builder.LclInstrm do
builder.Cd(group[:local_instrument])
end
builder.SeqTp(group[:sequence_type])
end
builder.ReqdColltnDt(group[:requested_date].iso8601)
builder.Cdtr do
builder.Nm(group[:account].name)
end
builder.CdtrAcct do
builder.Id do
builder.IBAN(group[:account].iban)
end
end
builder.CdtrAgt do
builder.FinInstnId do
if group[:account].bic
builder.BIC(group[:account].bic)
else
builder.Othr do
builder.Id('NOTPROVIDED')
end
end
end
end
builder.ChrgBr('SLEV')
builder.CdtrSchmeId do
builder.Id do
builder.PrvtId do
builder.Othr do
builder.Id(group[:account].creditor_identifier)
builder.SchmeNm do
builder.Prtry('SEPA')
end
end
end
end
end
transactions.each do |transaction|
build_transaction(builder, transaction)
end
end
end
end
def build_amendment_informations(builder, transaction)
builder.AmdmntInd(true)
builder.AmdmntInfDtls do
if transaction.original_debtor_account
builder.OrgnlDbtrAcct do
builder.Id do
builder.IBAN(transaction.original_debtor_account)
end
end
elsif transaction.same_mandate_new_debtor_agent
builder.OrgnlDbtrAgt do
builder.FinInstnId do
builder.Othr do
builder.Id('SMNDA')
end
end
end
end
if transaction.original_creditor_account
builder.OrgnlCdtrSchmeId do
if transaction.original_creditor_account.name
builder.Nm(transaction.original_creditor_account.name)
end
if transaction.original_creditor_account.creditor_identifier
builder.Id do
builder.PrvtId do
builder.Othr do
builder.Id(transaction.original_creditor_account.creditor_identifier)
builder.SchmeNm do
builder.Prtry('SEPA')
end
end
end
end
end
end
end
end
end
def build_transaction(builder, transaction)
builder.DrctDbtTxInf do
builder.PmtId do
if transaction.instruction.present?
builder.InstrId(transaction.instruction)
end
builder.EndToEndId(transaction.reference)
end
builder.InstdAmt('%.2f' % transaction.amount, Ccy: transaction.currency)
builder.DrctDbtTx do
builder.MndtRltdInf do
builder.MndtId(transaction.mandate_id)
builder.DtOfSgntr(transaction.mandate_date_of_signature.iso8601)
build_amendment_informations(builder, transaction) if transaction.amendment_informations?
end
end
builder.DbtrAgt do
builder.FinInstnId do
if transaction.bic
builder.BIC(transaction.bic)
else
builder.Othr do
builder.Id('NOTPROVIDED')
end
end
end
end
builder.Dbtr do
builder.Nm(transaction.name)
if transaction.debtor_address
builder.PstlAdr do
# Only set the fields that are actually provided.
# StrtNm, BldgNb, PstCd, TwnNm provide a structured address
# separated into its individual fields.
# AdrLine provides the address in free format text.
# Both are currently allowed and the actual preference depends on the bank.
# Also the fields that are required legally may vary depending on the country
# or change over time.
if transaction.debtor_address.street_name
builder.StrtNm transaction.debtor_address.street_name
end
if transaction.debtor_address.building_number
builder.BldgNb transaction.debtor_address.building_number
end
if transaction.debtor_address.post_code
builder.PstCd transaction.debtor_address.post_code
end
if transaction.debtor_address.town_name
builder.TwnNm transaction.debtor_address.town_name
end
if transaction.debtor_address.country_code
builder.Ctry transaction.debtor_address.country_code
end
if transaction.debtor_address.address_line1
builder.AdrLine transaction.debtor_address.address_line1
end
if transaction.debtor_address.address_line2
builder.AdrLine transaction.debtor_address.address_line2
end
end
end
end
builder.DbtrAcct do
builder.Id do
builder.IBAN(transaction.iban)
end
end
if transaction.remittance_information
builder.RmtInf do
builder.Ustrd(transaction.remittance_information)
end
end
end
end
end
end