module Clieop module Payment class Batch attr_accessor :transactions, :batch_info def initialize(batch_info) raise "Required: :description, :account_nr, :account_owner" unless ([:account_nr, :account_owner] - batch_info.keys).empty? @transactions = [] @batch_info = batch_info end # Adds a transaction to the batch # # :amount The amount involved with this transaction # :account_nr The bank account from the other party # :account_owner The name of the owner of the bank account # :reference_number A reference number to identify this transaction # :description A description for this transaction (4 lines max) def add_transaction (transaction) raise "No :account_nr given" if transaction[:account_nr].nil? raise "No :amount given" if transaction[:amount].nil? raise "No :account_owner given" if transaction[:account_owner].nil? @transactions << transaction end alias_method :<<, :add_transaction def to_clieop # generate batch header records batch_data = "" batch_data << Clieop::Payment::Record.new(:batch_header, :transaction_group => @batch_info[:transaction_group] || 0, :acount_nr => @batch_info[:account_nr] || 0, :serial_nr => @batch_info[:serial_nr] || 1, :currency => @batch_info[:currency] || "EUR").to_clieop # split batch discription into lines and make a record for the first 4 lines unless @batch_info[:description].nil? || @batch_info[:description] == '' @batch_info[:description].split(/\r?\n/)[0, 4].each do |line| # FIXME raise warning when line is longer than 32 chars/description longer than 4 lines batch_data << Clieop::Payment::Record.new(:batch_description, :description => line.strip).to_s unless line == '' end end batch_data << Clieop::Payment::Record.new(:batch_owner, :process_date => @batch_info[:process_date] || 0, :owner => @batch_info[:account_owner]).to_clieop # initialize checksums total_account = @batch_info[:account_nr].to_i * @transactions.length total_amount = 0 # add transactions to batch @transactions.each do |tr| # prepare data for this transaction's records transaction_type = tr[:transaction_type] || (transaction_is_payment? ? 1002 : 0) to_account = transaction_is_payment? ? @batch_info[:account_nr] : tr[:account_nr] from_account = transaction_is_payment? ? tr[:account_nr] : @batch_info[:account_nr] amount_in_cents = (tr[:amount] * 100).round.to_i # update checksums total_account += tr[:account_nr].to_i total_amount += amount_in_cents # generate transaction record batch_data << Clieop::Payment::Record.new(:transaction_info, :transaction_type => transaction_type, :amount => amount_in_cents, :to_account => to_account, :from_account => from_account).to_clieop # generate record with transaction information if transaction_is_payment? batch_data << Clieop::Payment::Record.new(:invoice_name, :name => tr[:account_owner]).to_clieop batch_data << Clieop::Payment::Record.new(:invoice_city, :city => tr[:account_city]).to_clieop unless tr[:account_city].nil? end batch_data << Clieop::Payment::Record.new(:transaction_reference, :reference_number => tr[:reference_number]).to_clieop unless tr[:reference_number].nil? # split discription into lines and make a record for the first 4 lines unless tr[:description].nil? || tr[:description] == '' tr[:description].split(/\r?\n/)[0, 4].each do |line| # FIXME raise warning when line is longer than 32 chars/description longer than 4 lines batch_data << Clieop::Payment::Record.new(:transaction_description, :description => line.strip).to_s unless line == '' end end unless transaction_is_payment? batch_data << Clieop::Payment::Record.new(:payment_name, :name => tr[:account_owner]).to_clieop batch_data << Clieop::Payment::Record.new(:payment_city, :city => tr[:account_city]).to_clieop unless tr[:account_city].nil? end end # generate batch footer record including some checks batch_data << Clieop::Payment::Record.new(:batch_footer, :transaction_count => @transactions.length, :total_amount => total_amount, :account_checksum => account_checksum(total_account)).to_clieop end alias_method :to_s, :to_clieop # creates a batch for payments from a given account def self.payment_batch(batch_info = {}) batch_info[:transaction_group] ||= 0 Clieop::Payment::Batch.new(batch_info) end # creates a batch for invoices to a given account def self.invoice_batch(batch_info = {}) batch_info[:transaction_group] ||= 10 Clieop::Payment::Batch.new(batch_info) end # the checksum on the total of accounts is in fact the last 10 chars of total amount def account_checksum(total) total.to_s.split('').last(10).join('') # ruby 1.8.6 # total.to_s.chars.last(10).join('') # ruby 1.8.7 end private def transaction_is_payment? @batch_info[:transaction_group] == 10 end end end end