Module: Transaction

Included in:
Parser
Defined in:
lib/transactions/main.rb,
lib/transactions/parser.rb,
lib/transactions/options.rb,
lib/transactions/version.rb

Defined Under Namespace

Classes: Options, Parser

Constant Summary collapse

VERSION =
"0.1.1"

Instance Method Summary collapse

Instance Method Details

#parse(cmd) ⇒ Object

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’



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# 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 |, value|
          main_accounts[] = 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) ⇒ Object



36
37
38
# 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) ⇒ Object



48
49
50
51
52
53
54
55
56
# 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) ⇒ Object



28
29
30
31
32
33
34
# 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) ⇒ Object



40
41
42
43
44
45
46
# 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