Class: QuickPep

Inherits:
Object
  • Object
show all
Defined in:
lib/quickpep.rb

Overview

Quick Personal Expenses Planner - for people too lazy to use a

spreadsheet or finance app

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(s, balance: 0, currency: '', today: Date.today, ignorewarnings: false, end_date: nil, debug: false) ⇒ QuickPep

end_date: should be in natural english format e.g. 2nd October



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/quickpep.rb', line 20

def initialize(s, balance: 0, currency: '', today: Date.today,
               ignorewarnings: false, end_date: nil, debug: false)

  @balance, @currency, @debug = balance, currency, debug
  
  @today = if today.is_a?(String) then
    Chronic.parse(today).to_date
  else
    today
  end
  
  @end_date = end_date
  @warnings = []
  @to_s = calc_expenses(s)

  warnings() if @warnings.any? and not ignorewarnings
  
  @weblet_file = weblet_file ||= File.join(File.dirname(__FILE__), '..', 'data',
                            'quickpep.txt')      

end

Instance Attribute Details

#inputObject (readonly)

Returns the value of attribute input.



16
17
18
# File 'lib/quickpep.rb', line 16

def input
  @input
end

#to_dxObject (readonly)

Returns the value of attribute to_dx.



16
17
18
# File 'lib/quickpep.rb', line 16

def to_dx
  @to_dx
end

#to_sObject (readonly)

Returns the value of attribute to_s.



16
17
18
# File 'lib/quickpep.rb', line 16

def to_s
  @to_s
end

Instance Method Details

#annual_costs(perx = :year, per: perx) ⇒ Object

options: year, month, weel, day



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
# File 'lib/quickpep.rb', line 44

def annual_costs(perx=:year, per: perx)

  rows = @date_events.map do |date, title|

    amount = @h[title].amount

    prefix = amount[0] == '+' ? '' : '-'
    amountx = (prefix + amount.gsub(/\D/,'')).to_f

    [date, title, amountx]

  end

  a = rows.group_by {|date,title, amount| title }\
      .map {|key, rows| [key, rows.map(&:last).sum]}.sort_by(&:last)

  a.map do |title, total|

    amount = case per.to_sym
    when :year
      total
    when :month
      total / (12 - @today.month)
    when :week
      total / (52 - @today.cweek )
    when :day
      total / (365 - @today.yday)
    end

    [title, amount.round(2)]
  end

end

#breakdownObject

Each expense annually as a percentage of total expenses



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/quickpep.rb', line 80

def breakdown()

  tot = total_expenses().abs
  r = annual_costs()
  a = r.select {| _, cost | cost < 0 }\
      .map {|title, cost| [title, (100 / (tot / cost.abs)).round] }

  def a.to_table()
    TableFormatter.new(source: self,
                      labels: %w(Item %:), markdown: true).display
  end

  return a
end

#costs_summaryObject



95
96
97
98
99
100
101
102
103
# File 'lib/quickpep.rb', line 95

def costs_summary()

  a = %i(year month day).map {|x| annual_costs x}.transpose\
      .map do |x|
    [x.first.first, *x.map {|y| "%s%0.2f" % [@currency, y.last.abs]}]
  end
  TableFormatter.new(source: a, labels: %w(Title Year: Month: Day:),
                     markdown: true).display
end

#to_html(titlex = "Personal Budget #{@today.year}", title: titlex) ⇒ Object



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
# File 'lib/quickpep.rb', line 105

def to_html(titlex="Personal Budget #{@today.year}", title: titlex)

  dx = to_dx()
  t = dx.to_table
  t.labels =  %w(date: title debit: credit: balance: uid:)
  table = t.display markdown: true

  tot = total_expenses().abs
  costs_per_interval = "
* daily: #{"%s%0.2f" % [@currency, (tot / 365.0)]}
* weekly: #{"%s%0.2f" % [@currency, (tot / 52.0)]}
* monthly: #{"%s%0.2f" % [@currency, (tot / 12.0)]}
* yearly: #{@currency + tot.to_s}
"

  t2 = @input.to_table
  t2.labels = %w(Title Amount: :Day: :Recurring: :Notes:)
  table2 = t2.display markdown: true

  html_table  = RDiscount.new(table).to_html
  html_breakdown = RDiscount.new(breakdown().to_table()).to_html
  html_cs = RDiscount.new(costs_summary()).to_html
  html_cpi = RDiscount.new(costs_per_interval).to_html
  html_table2 = RDiscount.new(table2).to_html
  time_now = Time.now.strftime("%d %b %Y")
  
  w = Weblet.new(@weblet_file)

  w.render :html, binding
  
end

#total_expensesObject



137
138
139
# File 'lib/quickpep.rb', line 137

def total_expenses()
  to_dx().all.map {|x| x.debit.sub(/\D/,'').to_f}.sum
end

#warningsObject



141
142
143
# File 'lib/quickpep.rb', line 141

def warnings()
  @warnings.each {|warning| puts warning.warn }
end

#year_end_balanceObject



145
146
147
# File 'lib/quickpep.rb', line 145

def year_end_balance()
  to_dx().all.last.balance.sub(/[^-0-9]+/,'').to_f
end