treasurer 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/treasurer/commands.rb +7 -7
- data/lib/treasurer/local_customisations.rb +2 -0
- data/lib/treasurer/report.rb +26 -16
- data/lib/treasurer.rb +4 -0
- data/test/test_treasurer.rb +3 -3
- data/treasurer.gemspec +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aa2a2dc0c5bcd8c4cc5bc4bc905e4c99e317497
|
4
|
+
data.tar.gz: 0208ef5153cfb46947fce5ca8079ead628180fb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 891b64d30e9cc11a6fe2793b88751e20bfb84630a14c39370f35bea6d485b47621be03ee06ee9db3d5ab77f159c7bf5458e9dd6af76396e06b4b63d9192cd6cb
|
7
|
+
data.tar.gz: 3694e108f72e3f72b90f2e21660f5939a52b4c931e5b0f4d196f3a2e358ad58e5e5d3b297a4e17dbf1f485e20d211ac66320e5748946f7c0ba63266536b0438f
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/treasurer/commands.rb
CHANGED
@@ -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
|
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
|
-
|
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)
|
data/lib/treasurer/report.rb
CHANGED
@@ -66,8 +66,9 @@ class Reporter
|
|
66
66
|
def report
|
67
67
|
get_actual_budgets
|
68
68
|
get_projected_budgets
|
69
|
-
|
70
|
-
|
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
|
-
|
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|
|
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|
|
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|
|
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|
|
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|
|
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|
|
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 " *
|
513
|
+
\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " L " + " r " * 2 + " c " }}
|
504
514
|
%\\hline
|
505
|
-
|
515
|
+
#{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
|
506
516
|
\\hline
|
507
517
|
\\Tstrut
|
508
518
|
#{items.map{|r|
|
509
|
-
(
|
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 " *
|
547
|
+
"\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " L " + " r " * 3 + "l"}}
|
538
548
|
#{piece.map{|r|
|
539
|
-
(
|
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'
|
data/test/test_treasurer.rb
CHANGED
@@ -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.
|
14
|
+
Treasurer.add_folder_of_files('../multiple')
|
15
15
|
Treasurer.status h: :component
|
16
|
-
Treasurer.
|
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.
|
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.
|
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-
|
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.
|
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-
|
11
|
+
date: 2014-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coderunner
|