module Transaction

Constants

VERSION

Public Instance Methods

parse(cmd) click to toggle source

Public: This is the actual parser for generating financial reports.

cmd - A String for the command to run through parser. Must be 'balance',

'register', or 'print'.

Examples

require 'transactions'
t = Transaction::Parser.new
ARGV[0] == ""  # The function requires ARGV[0] even if it's empty
t.parse 'balance'
t.parse 'register'
t.parse 'print'
ARGV[1] = 'checking'
t.parse 'register'
ARGV[1] = 'income'
ARGV[2] = 'expenses'
t.parse 'balance'

Returns Hash containing accounts and totals if cmd is 'balance'

# File lib/transactions/parser.rb, line 23
  def parse(cmd)

    @accounts = {}
    @running_total = 0

    def transaction_print(x)
      puts "#{x['date']} #{x['transaction']}"
      x.each do |k, v |
        puts sprintf("    %-30.30s % .2f", k, v) if v.is_a? Numeric
      end
      puts ""
    end

    def transaction_balance(k, v)
      @accounts[k] += v if v.is_a? Numeric
    end

    def transaction_register(x, k, v, running_total)
      if v.is_a? Numeric
        t = "%10s %-44.42s %-44.42s %15.2f %15.2f" if @options[:wide]
        t = "%10s %-20.18s %-24.22s %10.2f %10.2f" unless @options[:wide]
        puts sprintf(t, x['date'], x['transaction'], k, v, running_total)
      end
    end

    def transaction_command(cmd, x, k, v)
      ARGV.map! { |z| z.downcase }
      if ARGV[1..-1].any? { |arg| k.downcase.include? arg } || !ARGV[1]
        @running_total += v if v.is_a? Numeric
        transaction_print(x) if cmd == 'print'
        transaction_balance(k, v) if cmd == 'balance'
        transaction_register(x, k, v, @running_total) if cmd == 'register'
      end
    end

    @ledger.each do |x|
      total = 0
      x.each do |k, v|
        total += v if v.is_a? Numeric
        @accounts[k] ||= 0 if v.is_a? Numeric

        if @options[:current]
          if @options[:begin]
            if x['date'] <= @date && x['date'] >= @options[:begin]
              transaction_command(cmd, x, k, v); break if cmd == 'print'
            end
          else
            if x['date'] <= @date
              transaction_command(cmd, x, k, v); break if cmd == 'print'
            end
          end
        elsif @options[:begin] || @options[:end]
          if @options[:begin] && @options[:end]
            if @options[:begin] <= x['date'] and x['date'] <= @options[:end]
              transaction_command(cmd, x, k, v); break if cmd == 'print'
            end
          elsif @options[:begin]
            if x['date'] >= @options[:begin]
              transaction_command(cmd, x, k, v); break if cmd == 'print'
            end
          elsif @options[:end]
            if x['date'] <= @options[:end]
              transaction_command(cmd, x, k, v); break if cmd == 'print'
            end
          end
        else
          transaction_command(cmd, x, k, v); break if cmd == 'print'
        end
      end
      if total.round(2) != 0
        abort <<-EOF
        You have an UNBALANCED Transaction
        #{x}
        Your total is off by #{sprintf("%.2f", -total)}
        EOF
      end
    end


    if cmd == 'balance'
      accounts_total = 0
      main_accounts = {}

      if ARGV[1] && !@options[:subtotal]
        ARGV[1..-1].each do |arg|
          @accounts.sort.each do |k, v|
            if k.downcase.include? arg
              accounts_total += v
              v = v.round(2)
              if @options[:empty]
                puts sprintf("%16.2f  %s", v, k)
              else
                puts sprintf("%16.2f  %s", v, k) if v != 0
              end
            end
          end
        end
        puts "#{'-' * 16}"
        puts sprintf("%16.2f", accounts_total)

      elsif @options[:subtotal]
        summary_total = 0
        @accounts.each do |k, v|
          x = k.split(':')
          main_accounts[x[0].to_sym] ||= 0
          main_accounts[x[0].to_sym] += v
          main_accounts.each do |account, value|
            main_accounts[account] = value.round(2)
          end
        end
        main_accounts.sort.each do |k, v|
          if ARGV[1]
            ARGV.map! { |x| x.downcase }
            ARGV[1..-1].each do |arg|
              puts "#{sprintf("%16.2f  %s", v, k)}" if k.to_s.downcase.include? arg
              summary_total += v if k.to_s.downcase.include? arg
            end
          else
            puts "#{sprintf("%16.2f  %s", v, k)}"
            summary_total += v
          end
        end
        puts "#{"-" * 16}"
        puts "#{sprintf("%16.2f", summary_total.round(2))}"

      else
        @accounts.sort.each do |k, v|
          v = v.round(2)
          if @options[:empty]
            puts sprintf("%16.2f  %s", v, k)
          else
            puts sprintf("%16.2f  %s", v, k) if v != 0
          end
        end
      end
      @accounts
    end

  end
transaction_balance(k, v) click to toggle source
# File lib/transactions/parser.rb, line 36
def transaction_balance(k, v)
  @accounts[k] += v if v.is_a? Numeric
end
transaction_command(cmd, x, k, v) click to toggle source
# File lib/transactions/parser.rb, line 48
def transaction_command(cmd, x, k, v)
  ARGV.map! { |z| z.downcase }
  if ARGV[1..-1].any? { |arg| k.downcase.include? arg } || !ARGV[1]
    @running_total += v if v.is_a? Numeric
    transaction_print(x) if cmd == 'print'
    transaction_balance(k, v) if cmd == 'balance'
    transaction_register(x, k, v, @running_total) if cmd == 'register'
  end
end
transaction_print(x) click to toggle source
# File lib/transactions/parser.rb, line 28
def transaction_print(x)
  puts "#{x['date']} #{x['transaction']}"
  x.each do |k, v |
    puts sprintf("    %-30.30s % .2f", k, v) if v.is_a? Numeric
  end
  puts ""
end
transaction_register(x, k, v, running_total) click to toggle source
# File lib/transactions/parser.rb, line 40
def transaction_register(x, k, v, running_total)
  if v.is_a? Numeric
    t = "%10s %-44.42s %-44.42s %15.2f %15.2f" if @options[:wide]
    t = "%10s %-20.18s %-24.22s %10.2f %10.2f" unless @options[:wide]
    puts sprintf(t, x['date'], x['transaction'], k, v, running_total)
  end
end