abo.rb

Zdrojový kód, ze kterého jsem vycházel, je odsud. https://github.com/hexmotive/ABO/blob/master/lib/abo.rb

Fio má ale trochu jinou verzi ABO http://www.fio.cz/docs/cz/struktura-abo.pdf, dále byly provedeny změny takové, co umožní kód trochu zkrátit (např. oddělání nicneříkajících poznámek, nadefinování defaultních konstruktorů a pod.)

require 'date'
require 'time'
 
# některé verze ruby vyžadují následující, jinak hlásí chybu, že metoda to_date je private
class Time
  public :to_date
end
 
module ABO 
 
  class WrongFormatError < StandardError; end 
 
  class Writer  
 
    attr_accessor :file_header #Hlavička účetního souboru
    attr_accessor :group_header #Hlavička skupiny
    attr_accessor :payment_orders # pole s jednotlivými příkazy
 
    class FileHeader
      PAYMENT = "1501"
      INKASO = "1502"
      attr_accessor :date_type
      attr_accessor :file_number
      attr_accessor :bank_code
      def end_block
        "5 +\r\n"
      end 
 
     def initialize(date_type=INKASO,file_number="001",bank_code="2010")
        @date_type=date_type
        @file_number=file_number
        @bank_code=bank_code
     end   
 
      def to_abo
        "1 #{date_type} #{file_number}000 #{bank_code}\r\n"
      end 
 
    end 
 
    class GroupHeader
      attr_accessor :payers_account_number
      attr_accessor :group_amount    #celková částka skupiny v haléřích - bude automaticky dopočítáno
      attr_accessor :due_date #datum splatnosti
 
      def due_date=(value)
        raise ABO::WrongFormatError unless value.instance_of?(Date)
        @due_date = value 
      end 
 
      def payers_account_number
        if @payers_account_number.include?("-")
          pole=@payers_account_number.split("-")
          ("%06d" % pole[0].to_i) + "-" + ("%010d" %  pole[1].to_i)
        else
          ("%016d" % @payers_account_number.to_i).insert(6,"-")
        end
#        "%017d" % @payers_account_number.to_i
      end 
 
      def due_date
        raise ABO::WrongFormatError unless @due_date.instance_of?(Date)
        @due_date.strftime("%d%m%y")
      end 
 
      def end_block
        "3 +\r\n"
      end 
 
      def initialize(payers_account_number="292920",due_date=(Time.now()+60*60*24).to_date)
         @payers_account_number=payers_account_number
         @due_date=due_date # defaultně zítra
      end 
 
      def to_abo
        "2 #{payers_account_number} #{group_amount} #{due_date}\r\n"
      end 
    end 
 
    class PaymentOrder
      attr_accessor :credit_account_number
      attr_accessor :credit_account_bank_code
      attr_accessor :text
      attr_accessor :amount
      attr_accessor :variable_symbol
      attr_accessor :constant_symbol
 
      def credit_account_number
        if @credit_account_number.include?("-")
          pole=@credit_account_number.split("-")
          ("%06d" % pole[0].to_i) + "-" + ("%010d" %  pole[1].to_i)
        else
          ("%016d" % @credit_account_number.to_i).insert(6,"-")
        end                
      end 
 
      def credit_account_bank_code
        "%004d" % @credit_account_bank_code.to_i
      end 
 
      def amount
        "%008d" % @amount
      end 
 
      def variable_symbol
        "%010d" % @variable_symbol.to_i
      end 
 
      def constant_symbol
        "%004d" % @constant_symbol.to_i
      end 
 
      def to_abo
        "#{credit_account_number} #{amount} #{variable_symbol} #{credit_account_bank_code}#{constant_symbol} 0 AV:#{text}\r\n"
      end 
 
      def initialize(ucet,kod_banky,castka,vs,ks="0000",text="Odorik.cz - inkaso")
        @credit_account_number=ucet
        @amount=castka.to_f*100
        @variable_symbol=vs
        @credit_account_bank_code=kod_banky
        @constant_symbol=ks
        @text=text
     end 
    end 
 
    def initialize
        @file_header = FileHeader.new
        @group_header = GroupHeader.new
        @payment_orders = []
     end 
 
    def to_abo
      prepare
      string = ""
      string << "UHL1#{Time.now().to_date.strftime('%d%m%y')}#{'miniTEL s.r.o.'.ljust(20)}#{'0'*10}001001\r\n"
      string << @file_header.to_abo
      string << @group_header.to_abo
      @payment_orders.each do |p| 
        string << p.to_abo
      end 
      string << @group_header.end_block
      string << @file_header.end_block
 
      string
    end 
 
    private
 
    def prepare
      @group_header.group_amount = sum_amounts
    end 
 
    def sum_amounts
      @payment_orders.inject(0){|p,c| p + c.amount.to_i}
    end 
 
 end 
end

Příklad použití

aboTest.rb

require './abo.rb'
 
myAbo= ABO::Writer.new
myAbo.payment_orders << ABO::Writer::PaymentOrder.new("1748030001","5500",1.5,608424631) <<
ABO::Writer::PaymentOrder.new("1748030001","5500",1.9,608424631)
# z účtu 1748030001/5500 vyinkasuji dvě platby 1.5 Kč a  1.9 Kč s variabilním symbolem 608424631
puts myAbo.to_abo

Vygenerování dávkového souboru pro FIO:

ruby aboTest.rb > inkaso.txt
cat inkaso.txt
UHL1150814miniTEL s.r.o.      0000000000001001
1 1502 001000 2010
2 00000000000292920 340 160814
00000001748030001 00000150 0608424631 55000000 0 AV:Odorik.cz - inkaso
00000001748030001 00000190 0608424631 55000000 0 AV:Odorik.cz - inkaso
3 +
5 +

Nyní po přihlášení ve FIO bance zvolte podání příkazuABO import

A vyberte soubor inkaso.txt

Před potvrzením sms zprávou je možné dávku vizuálně namátkou zkontrolovat.

Přehled zadaných, nepodepsaných, podepsaných, realizovaných a zamítnutých inkas najdete v menu platbyPřevody Ve filtru vlevo Směr pohybu: vyberte možnost inkasa.