treasurer 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7093dd3826d606b0ba1f76ae379ea9ff02d74211
4
- data.tar.gz: 54f3cde9ccd02559074114f691dc03d48f44d55f
3
+ metadata.gz: 6aa2a2dc0c5bcd8c4cc5bc4bc905e4c99e317497
4
+ data.tar.gz: 0208ef5153cfb46947fce5ca8079ead628180fb2
5
5
  SHA512:
6
- metadata.gz: cbcec24e8990da5ed2131023662c5cfee4d65332f90ca1547f96d648865dbc5051a511dde77c78f27580b56832ff827b3bdc8d483efc65e351673304ccf568da
7
- data.tar.gz: d78965e3d3b81edb9fec098aa33a2b58e17a254c71c85e1ad490ed4407434e1279cc9f187d16a6f8cec3539d1758114bb914c3751886ac56c7267bd944c59daf
6
+ metadata.gz: 891b64d30e9cc11a6fe2793b88751e20bfb84630a14c39370f35bea6d485b47621be03ee06ee9db3d5ab77f159c7bf5458e9dd6af76396e06b4b63d9192cd6cb
7
+ data.tar.gz: 3694e108f72e3f72b90f2e21660f5939a52b4c931e5b0f4d196f3a2e358ad58e5e5d3b297a4e17dbf1f485e20d211ac66320e5748946f7c0ba63266536b0438f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -6,7 +6,7 @@ class << self
6
6
  ep 'entries', Dir.entries
7
7
  CodeRunner.submit(p: "{data_file: '#{File.expand_path(file)}', account: :#{account}}")
8
8
  end
9
- def add_folder(folder, copts={})
9
+ def add_folder_of_files(folder, copts={})
10
10
  #Dir.chdir(folder) do
11
11
  files = Dir.entries(folder).grep(/\.csv$/)
12
12
  accounts = files.map{|f| f.sub(/\.csv/, '')}
@@ -18,6 +18,11 @@ class << self
18
18
  def check_is_treasurer_folder
19
19
  raise "This folder has not been set up to use with Treasurer; please initialise a folder with treasurer init" unless FileTest.exist? '.code_runner_script_defaults.rb' and eval(File.read('.code_runner_script_defaults.rb'))[:code] == 'budget'
20
20
  end
21
+ def create_report(copts = {})
22
+ load_treasurer_folder
23
+ reporter = Reporter.new(CodeRunner.fetch_runner(h: :component), days_before: copts[:b]||360, days_ahead: copts[:a]||180, today: copts[:t])
24
+ reporter.report()
25
+ end
21
26
  def init_root_folder(folder, copts={})
22
27
  raise "Folder already exists" if FileTest.exist? folder
23
28
  FileUtils.makedirs(folder)
@@ -32,13 +37,8 @@ class << self
32
37
  Treasurer::Reporter.send(:include, Treasurer::LocalCustomisations)
33
38
  Treasurer::Reporter::Account.send(:include, Treasurer::LocalCustomisations)
34
39
  Treasurer::Reporter::Analysis.send(:include, Treasurer::LocalCustomisations)
35
- CodeRunner::Budget.send(:include, Treasurer::LocalCustomisations)
36
40
  runner = CodeRunner.fetch_runner
37
- end
38
- def report(copts = {})
39
- load_treasurer_folder
40
- reporter = Reporter.new(CodeRunner.fetch_runner(h: :component), days_before: copts[:b]||360, days_ahead: copts[:a]||180, today: copts[:t])
41
- reporter.report()
41
+ CodeRunner::Budget.send(:include, Treasurer::LocalCustomisations)
42
42
  end
43
43
 
44
44
  def method_missing(meth, *args)
@@ -52,6 +52,8 @@ def account_type(account)
52
52
  :Asset
53
53
  when :PersonalLoans
54
54
  :Liability
55
+ else
56
+ :Expense
55
57
  end
56
58
  end
57
59
 
@@ -66,8 +66,9 @@ class Reporter
66
66
  def report
67
67
  get_actual_budgets
68
68
  get_projected_budgets
69
- @accounts = @runs.map{|r| r.account}.uniq.map{|acc| Account.new(acc, self, @runner, @runs, @projected_budgets, false)} +
70
- @runs.map{|r| r.external_account}.uniq.map{|acc| Account.new(acc, self, @runner, @runs, @projected_budgets, true)}
69
+ accounts = @runs.map{|r| r.account}.uniq.map{|acc| Account.new(acc, self, @runner, @runs, @projected_budgets, false)}
70
+ external_accounts = (@runs.map{|r| r.external_account}.uniq - accounts.map{|acc| acc.name}).map{|acc| Account.new(acc, self, @runner, @runs, @projected_budgets, true)}
71
+ @accounts = accounts + external_accounts
71
72
  @accounts.unshift (@equity = Equity.new(self, @runner, @accounts))
72
73
  get_in_limit_discretionary_budget_factor
73
74
  get_stable_discretionary_budget_factor
@@ -80,7 +81,7 @@ class Reporter
80
81
  report << expense_account_summary
81
82
  report << budget_expenditure_graphs
82
83
  report << '\end{multicols}'
83
- report << budget_resolutions
84
+ #report << budget_resolutions
84
85
  report << budget_breakdown
85
86
  report << transactions_by_account
86
87
  report << footer
@@ -112,12 +113,17 @@ class Reporter
112
113
  #if !date
113
114
  #@runs.sort_by{|r| r.date}[-1].balance
114
115
  if @external
115
- @runs.find_all{|r| r.date < date}.map{|r| (r.deposit - r.withdrawal) * (@external ? -1 : 1)}.sum || 0.0
116
+ #p ['name is ', name, type]
117
+ #
118
+ #@runs.find_all{|r| r.date < date}.map{|r| (r.deposit - r.withdrawal) * (@external ? -1 : 1)}.sum || 0.0
119
+ # Temporary....
120
+ 0.0
116
121
  else
117
122
  @runs.sort_by{|r| (r.date.to_datetime.to_time.to_i - date.to_datetime.to_time.to_i).to_f.abs}[0].balance
118
123
  end
119
124
  end
120
125
  def expenditure(today, days_before, &block)
126
+ p ['name22 is ', name, type]
121
127
  @runs.find_all{|r| r.days_ago(today) < days_before and (!block or yield(r)) }.map{|r| @external ? r.withdrawal : r.deposit }.sum || 0
122
128
  end
123
129
  def income(today, days_before)
@@ -143,6 +149,7 @@ EOF
143
149
  end
144
150
  end
145
151
  def projected_balance(date)
152
+ return 0.0 if @external # Temporary Hack
146
153
  non_discretionary_projected_balance(date) -
147
154
  @reporter.sum_regular(@projected_budgets, date)
148
155
  end
@@ -194,7 +201,7 @@ EOF
194
201
  stable = futuredates.map{|date| projected_balance(date)}
195
202
  kit5 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, stable])
196
203
  #exit
197
- @projected_budget_factor = nil
204
+ @reporter.projected_budget_factor = nil
198
205
  kit += (kit2 + kit4 + kit5)
199
206
  kit = kit3 + kit
200
207
  kit.title = "Balance for #{name}"
@@ -287,19 +294,19 @@ EOF
287
294
  \\subsection{Equity}
288
295
  #{@accounts.find{|acc| acc.type == :Equity }.summary_table(@today, @days_before)}
289
296
  \\subsection{Assets}
290
- #{@accounts.find_all{|acc| account_type(acc.name) == :Asset }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
297
+ #{@accounts.find_all{|acc| acc.type == :Asset }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
291
298
  \\subsection{Liabilities}
292
- #{@accounts.find_all{|acc| account_type(acc.name) == :Liability }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
299
+ #{@accounts.find_all{|acc| acc.type == :Liability }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
293
300
  \\subsection{Income}
294
- #{@accounts.find_all{|acc| account_type(acc.name) == :Income }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
301
+ #{@accounts.find_all{|acc| acc.type == :Income }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
295
302
  \\subsection{Expenses}
296
- #{@accounts.find_all{|acc| account_type(acc.name) == :Expense }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
303
+ #{@accounts.find_all{|acc| acc.type == :Expense }.map{|acc| acc.summary_table(@today, @days_before)}.join("\n\n") }
297
304
  EOF
298
305
  end
299
306
  def account_balance_graphs
300
307
  <<EOF
301
308
  \\section{Graphs of Recent Balances}
302
- #{@accounts.find_all{|acc| account_type(acc.name) != :Expense}.map{|acc|
309
+ #{@accounts.find_all{|acc| acc.type != :Expense}.map{|acc|
303
310
  acc.write_balance_graph(@today, @days_before, @days_ahead)
304
311
  acc.balance_graph_string
305
312
  }.join("\n\n")
@@ -326,9 +333,12 @@ EOF
326
333
  EOF
327
334
  end
328
335
  def expense_pie_chart(name, &block)
329
- expaccs = @accounts.find_all{|acc| account_type(acc.name) == :Expense}
336
+ expaccs = @accounts.find_all{|acc| acc.type == :Expense}
330
337
  labels = expaccs.map{|acc| acc.name}
331
338
  exps = expaccs.map{|acc| acc.expenditure(@today, 50000, &block)}
339
+ labels, exps = [labels, exps].transpose.find_all{|l, e| e != 0.0}.transpose
340
+ return "No expenditure in budget period." if labels == nil
341
+ ep ['labels22539', labels, exps]
332
342
  kit = GraphKit.quick_create([exps])
333
343
  kit.data[0].gp.with = 'boxes'
334
344
  kit.gp.style = "fill solid"
@@ -500,13 +510,13 @@ EOF
500
510
  if items.size > 0
501
511
  "
502
512
  \\footnotesize
503
- \\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 2 }}
513
+ \\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " L " + " r " * 2 + " c " }}
504
514
  %\\hline
505
- & #{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
515
+ #{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
506
516
  \\hline
507
517
  \\Tstrut
508
518
  #{items.map{|r|
509
- ([:id] + CodeRunner::Budget.rcp.component_results - [:sc, :balance]).map{|res|
519
+ ( CodeRunner::Budget.rcp.component_results + [:external_account] - [:sc, :balance ]).map{|res|
510
520
  r.send(res).to_s.latex_escape
511
521
  }.join(" & ")
512
522
  }.join("\\\\\n")
@@ -534,9 +544,9 @@ EOF
534
544
  #{all = acc.runs.find_all{|r| r.days_ago(@today) < @days_before}.sort_by{|r| [r.date, r.id]}.reverse
535
545
  #ep ['acc', acc, 'ids', all.map{|r| r.id}, 'size', all.size]
536
546
  all.pieces((all.size.to_f/50.to_f).ceil).map{|piece|
537
- "\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 3 + "l"}}
547
+ "\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " L " + " r " * 3 + "l"}}
538
548
  #{piece.map{|r|
539
- ([:id] + CodeRunner::Budget.rcp.component_results - [:sc] + [:budget]).map{|res| r.send(res).to_s.latex_escape
549
+ (CodeRunner::Budget.rcp.component_results - [:sc] + [:budget]).map{|res| r.send(res).to_s.latex_escape
540
550
  #rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
541
551
  }.join(" & ")
542
552
  }.join("\\\\\n")}
data/lib/treasurer.rb CHANGED
@@ -91,6 +91,9 @@ class Treasurer
91
91
  # options (copts) hash
92
92
  def setup(copts)
93
93
  # None neededed
94
+ copts[:b] = copts[:b].to_i
95
+ copts[:a] = copts[:a].to_i
96
+ copts[:t] = Date.parse(copts[:t]) if copts[:t]
94
97
  end
95
98
  def verbosity
96
99
  2
@@ -100,6 +103,7 @@ class Treasurer
100
103
  end
101
104
 
102
105
  $has_put_startup_message_for_code_runner = true
106
+ require 'date'
103
107
  require 'coderunner'
104
108
  require 'treasurer/commands.rb'
105
109
  require 'treasurer/report.rb'
@@ -11,10 +11,10 @@ class TestTreasurer < Test::Unit::TestCase
11
11
  Treasurer.add_file('../bankaccountstatement.csv', 'FirstBank', {})
12
12
  Treasurer.status
13
13
  Treasurer.add_file('../otheraccountstatement.csv', 'SecondBank', {})
14
- Treasurer.add_folder('../multiple')
14
+ Treasurer.add_folder_of_files('../multiple')
15
15
  Treasurer.status h: :component
16
- Treasurer.report t: Date.parse('2010-09-07'), b: 40, a: 35
16
+ Treasurer.create_report t: Date.parse('2010-09-07'), b: 40, a: 35
17
17
  end
18
- FileUtils.rm_r(testfolder) if FileTest.exist? testfolder
18
+ #FileUtils.rm_r(testfolder) if FileTest.exist? testfolder
19
19
  end
20
20
  end
data/treasurer.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: treasurer 0.1.0 ruby lib
5
+ # stub: treasurer 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "treasurer"
9
- s.version = "0.1.0"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Edmund Highcock"]
14
- s.date = "2014-05-30"
14
+ s.date = "2014-06-02"
15
15
  s.description = "A simple command line tool for managing accounts and finances. Easily import internet banking spreadsheets and generate sophisticated reports and projections."
16
16
  s.email = "edmundhighcock@users.sourceforge.net"
17
17
  s.executables = ["treasurer"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: treasurer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edmund Highcock
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-30 00:00:00.000000000 Z
11
+ date: 2014-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coderunner