treasurer 0.6.0 → 0.7.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: 92a0a6c8e0a23eecc1d69c1dd14ff399b8b227c4
4
- data.tar.gz: 66e9cab23527f7dd3f843e2601a8d2904dbe6301
3
+ metadata.gz: d2048cb90864a5b22bc6bb26e1d226040caeb731
4
+ data.tar.gz: 340e5a5daf1026576358fc596ce9894566fac808
5
5
  SHA512:
6
- metadata.gz: 9bc7d55859630ea044d03356f113a20edc1a33dbe357d06b3055c7c922b285944b13acce16f7e4c2a825b10baf83f9eeff182f69863387009fc730e223088973
7
- data.tar.gz: 8c5e101af682d340a99b283f0801ed7afd776e4df1185fa90e3921f4003877c489116b450e3fd951d48c5f27b3a6c7eef99981aa2ea302dff47065a8b11ff5b9
6
+ metadata.gz: c0ac2576887308f53d2e3f72f3e73ece698785c4798d0ae2d8a14a1f114670eb7b44f18462742cab5b7b97c634a20ce71a7cc600d4f816d47d75859e44c1b511
7
+ data.tar.gz: cc2da7e7611fc6cf38502565a2b3721e64c45084627e2adb6bb7df043060af09f377a314e24683591284820aaac63eef9d611f018a676c4006db755d927f608f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.7.0
@@ -13,6 +13,8 @@ class Treasurer::Reporter
13
13
  #ep ['sub_accounts333', name, @runs.size, runs.size]
14
14
  end
15
15
  end
16
+ class ReportAccount < Account
17
+ end
16
18
  class Account
17
19
  attr_reader :name, :external, :runs, :currency
18
20
  attr_accessor :projection, :average, :original_currency
@@ -23,21 +25,66 @@ class Treasurer::Reporter
23
25
  @currency = options[:currency]
24
26
  #@projected_accounts_info =Hash[projected_accounts_info.find_all{|k,v| v[:account] == name}]
25
27
  @external = external
26
- @runs = runs.find_all do |r|
27
- #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency and @external
28
- #@external ? r.external_account : r.account) == name}
29
- if not @external
30
- r.account == name
31
- elsif @currency and info and cur = info[:currencies] and cur.size > 1
32
- #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency
33
- r.external_account == name and acinfo = ACCOUNT_INFO[r.account] and acinfo[:currencies] == [@currency]
34
- else
35
- r.external_account == name
28
+ unless @runs = options[:input_runs]
29
+ @runs = runs.find_all do |r|
30
+ #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency and @external
31
+ #@external ? r.external_account : r.account) == name}
32
+ if not @external
33
+ r.account == name
34
+ elsif @currency and info and cur = info[:currencies] and cur.size > 1
35
+ #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency
36
+ r.external_account == name and acinfo = ACCOUNT_INFO[r.account] and acinfo[:currencies] == [@currency]
37
+ else
38
+ r.external_account == name
39
+ end
36
40
  end
41
+
42
+ if should_report?
43
+ if @external
44
+ @report_runs = runs.find_all do |r|
45
+ r.external_account == name
46
+ end
47
+ else
48
+ @report_runs = @runs
49
+ end
50
+ end
51
+ else
52
+ @report_runs = []
37
53
  end
38
54
  #p ['Accountinf', name, @currency, @runs.size, runs.size]
39
55
  info[:external] = external if info
40
56
  end
57
+
58
+ # Make the account object that does the reporting. This only
59
+ # gets called if we are doing a currency conversion and
60
+ # this account is in the reeport currency.
61
+ def generate_report_account
62
+ p [name_c, @report_runs.class, @runs.class]
63
+ @report_account = ReportAccount.new(@name, @reporter, @runner, nil, @external, {currency: @currency, input_runs: @report_runs})
64
+ @report_account.instance_variable_set(:@currency, @reporter.report_currency)
65
+ @report_account.instance_variable_set(:@original_currency, currency)
66
+ end
67
+
68
+ # The object that actually does the reporting. If there is no
69
+ # currency conversion this is just self.
70
+ # A separate report object is needed as just lumping all the
71
+ # different currencies together across the board results
72
+ # in double counting.
73
+ #
74
+ # The report account is used for reporting information
75
+ # regarding a particular account. The main accoun is
76
+ # used for calculations e.g. Equity
77
+ def report_account
78
+ @report_account || self
79
+ end
80
+
81
+ # Should I report? If there is no currency conversion
82
+ # all accounts report. If there is currency conversion
83
+ # only non-external accounts and accounts in the
84
+ # right currency report.
85
+ def should_report?
86
+ !@reporter.report_currency or !@external or (@original_currency||currency) == @reporter.report_currency
87
+ end
41
88
  def sub_accounts
42
89
  @sub_accounts ||= @runs.map{|r| r.sub_account}.uniq.compact.map{|acc| SubAccount.new(acc, @reporter, @runner, @runs, @external, currency: @currency)}
43
90
  end
@@ -137,7 +184,7 @@ EOF
137
184
  def summary_line(today, days_before)
138
185
 
139
186
  <<EOF
140
- #{name_c} & #{balance} & #{deposited(today, days_before)} & #{withdrawn(today, days_before)}
187
+ #{name_c} & #{balance.to_tex} & #{deposited(today, days_before).to_tex} & #{withdrawn(today, days_before).to_tex}
141
188
  EOF
142
189
  end
143
190
  def money_in_sign
@@ -237,13 +284,15 @@ EOF
237
284
  #exit
238
285
  @reporter.projected_account_factor = nil
239
286
  kit += ( kit4 + kit5 + kit2)
240
- kit.yrange = [kit.data.map{|dk| dk.y.data.min}.min, kit.data.map{|dk| dk.y.data.max}.max]
287
+ kit.yrange = [(m = kit.data.map{|dk| dk.y.data.min}.min; m-m.abs*0.1), (m=kit.data.map{|dk| dk.y.data.max}.max; m+m.abs*0.1)]
241
288
  #kit += (kit2)
242
289
  kit = kit3 + kit
243
290
  kit.title = "Balance for #{name_c}"
244
291
  kit.xlabel = %['Date' offset 0,-2]
245
292
  kit.xlabel = nil
246
293
  kit.ylabel = "Balance"
294
+ kit.gp.mytics= "5"
295
+ kit.gp.grid = "ytics mytics lw 2,lw 1"
247
296
 
248
297
 
249
298
  kit.data[0].gp.title = 'Limit'
@@ -255,14 +304,20 @@ EOF
255
304
  kit.data.each{|dk| dk.gp.with = "l lw 5"}
256
305
  kit.data[4].gp.with = "l lw 5 dt 2 lc rgb 'black' "
257
306
  kit.gp.key = ' bottom left '
258
- kit.gp.key = ' rmargin '
307
+ kit.gp.key = ' rmargin samplen 2'
259
308
 
260
309
  #(p kit; STDIN.gets) if name == :LloydsCreditCard
261
310
  CodeRunner::Budget.kit_time_format_x(kit)
311
+ size = case type
312
+ when :Equity
313
+ "4.0in,4.0in"
314
+ else
315
+ "4.0in,2.5in"
316
+ end
262
317
 
263
318
  fork do
264
- (kit).gnuplot_write("#{name_c_file}_balance.eps", size: "4.0in,1.5in") #, latex: true)
265
- %x[epspdf #{name_c_file}_balance.eps]
319
+ (kit).gnuplot_write("#{name_c_file}_balance.eps", size: size) #, latex: true)
320
+ %x[epspdf -b #{name_c_file}_balance.eps]
266
321
  end
267
322
  #%x[epspdf #{name}_balance.eps]
268
323
  end
@@ -281,6 +336,9 @@ EOF
281
336
  @accounts = accounts #.find_all{|acc| not acc.external}
282
337
  @currency = options[:currency]
283
338
  end
339
+ def should_report?
340
+ true
341
+ end
284
342
  def type
285
343
  :Equity
286
344
  end
@@ -336,7 +394,7 @@ Balance & #{balance} \\\\
336
394
  EOF
337
395
  end
338
396
  def summary_line(today, days_before)
339
- "#{name_c} & #{balance(today)} & & "
397
+ "#{name_c} & #{balance(today).to_tex} & & "
340
398
  end
341
399
  end
342
400
  end
@@ -22,7 +22,8 @@ module Analysis
22
22
  #start_date = [(account.info[:start]||@start_date), @start_date].max
23
23
  expenditure = 0
24
24
  items_temp = []
25
- items = @runner.component_run_list.values.find_all{|r| r.external_account == account.name and r.in_date(account.info) and @accounts_hash[r.account].original_currency == account.original_currency}
25
+ #items = @runner.component_run_list.values.find_all{|r| r.external_account == account.name and r.in_date(account.info) and @accounts_hash[r.account].original_currency == account.original_currency}
26
+ items = account.runs.find_all{|r| r.in_date(account.info)}
26
27
  #ep ['items', items.map{|i| i.date}]
27
28
  #ep ['account', account.name_c]
28
29
  counter = 0
@@ -142,7 +143,7 @@ module Analysis
142
143
  sum_out = regular_items.inject(0) do |sum, (account, item)|
143
144
  item = [item] unless item.kind_of? Array
144
145
  # ep item
145
- value = item.inject(0) do |value,info|
146
+ value_out = item.inject(0) do |value,info|
146
147
  finish = (info[:end] and info[:end] < end_date) ? info[:end] : end_date
147
148
  #today = (Time.now.to_i / (24.0*3600.0)).round
148
149
 
@@ -212,7 +213,7 @@ module Analysis
212
213
  value + nunits * (info[:size]||account.projection*(@projected_account_factor||1.0))
213
214
 
214
215
  end
215
- sum + value
216
+ sum + value_out
216
217
  #(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value
217
218
  end
218
219
  sum_out
@@ -11,39 +11,44 @@ class Float
11
11
  sprintf("%.2f", self)
12
12
  end
13
13
  end
14
+ class Numeric
15
+ def to_tex
16
+ sprintf("%.2f", self).reverse.gsub(/(\d{3})(?=\d)/){"#$1,\\"}.reverse
17
+ end
18
+ end
14
19
  class Date
15
20
  def inspect
16
21
  "Date.parse('#{to_s}')"
17
22
  end
18
23
  end
19
- # Some thoughts on double entry accounting:
24
+ # Some thoughts on double entry accounting:
20
25
  #
21
26
  # assets - liabilities = equity
22
27
  # where equity = equity_at_start + income - expenses
23
28
  #
24
- # so
29
+ # so
25
30
  #
26
31
  # assets - liabilities = equity_at_start + income - expenses
27
32
  #
28
- # or alternatively
33
+ # or alternatively
29
34
  #
30
35
  # assets + expenses = equity_at_start + income + liabilities (1)
31
36
  #
32
37
  # Good things:
33
38
  # Positive equity_at_start, positive assets, positive income, negative liabilities, negative expenses
34
39
  #
35
- # A debit on the left of (1) must be matched by a credit on the right of (1) and
36
- # vice versa.
40
+ # A debit on the left of (1) must be matched by a credit on the right of (1) and
41
+ # vice versa.
37
42
  #
38
43
  #
39
44
  # A debit to an asset account increases the value of the asset. This means buying some land
40
- # or supplies or depositing some cash in a bank account. You can think of it as a debit because
45
+ # or supplies or depositing some cash in a bank account. You can think of it as a debit because
41
46
  # you are locking up your equity in a way that may not be realisable. A credit to the asset account
42
47
  # means drawing down on the asset, for example selling a bit of land or taking money out of a
43
48
  # bank account.
44
49
  #
45
50
  # Similarly, a debit to an expense account, effectively, spending money on that expense,
46
- # increases the value of that account. Debits here are clearly negative things from
51
+ # increases the value of that account. Debits here are clearly negative things from
47
52
  # the point of view of your wealth! (Credits to expense accounts would be something like
48
53
  # travel reimbursements).
49
54
  #
@@ -52,16 +57,16 @@ end
52
57
  # example a bank account, i.e. you must effectively spend it by buying an asset: remember
53
58
  # a bank may fail... a bank account is an asset with risk just as much as a painting).
54
59
  #
55
- # A credit to liabilities increases the value of the liability, for example taking out a
60
+ # A credit to liabilities increases the value of the liability, for example taking out a
56
61
  # loan. Once you credit a liability you have to either buy (debit) an asset, or buy (debit)
57
62
  # an expense directly (for example a loan to pay some fees).
58
- #
63
+ #
59
64
  # In any accounting period, the sum of all debits and credits should be 0. Also, at the end
60
65
  # of the accounting period,
61
66
  #
62
67
  # equity_at_end = assets - liabilities = equity_at_start + income - expenses
63
68
  #
64
- # This seems obvious to me!!
69
+ # This seems obvious to me!!
65
70
  class Treasurer
66
71
  class Reporter
67
72
  #include LocalCustomisations
@@ -72,7 +77,7 @@ class Treasurer
72
77
  attr_reader :accounts
73
78
  attr_reader :equity
74
79
  attr_reader :projected_accounts_info
75
- attr_reader :days_before
80
+ attr_reader :days_before
76
81
  attr_reader :report_currency
77
82
  attr_reader :accounts_hash
78
83
  def initialize(runner, options)
@@ -87,30 +92,30 @@ class Treasurer
87
92
  @report_currency = options[:report_currency]
88
93
 
89
94
  if run = @runs.find{|r| not r.external_account}
90
- raise "External_account not specified for #{run.data_line}"
95
+ raise "External_account not specified for #{run.data_line}"
91
96
  end
92
97
  @indateruns = @runs.find_all{|r| r.days_ago(@today) < @days_before}
93
98
  @stable_discretionary_account_factors = {}
94
99
  @in_limit_discretionary_account_factors = {}
95
- #p 'accounts256',@runs.size, @runs.map{|r| r.account}.uniq
100
+ #p 'accounts256',@runs.size, @runs.map{|r| r.account}.uniq
96
101
 
97
102
  end
98
103
  def generate_accounts
99
- accounts = @runs.map{|r| r.account}.uniq.map{|acc| Account.new(acc, self, @runner, @runs, false)}
100
- external_accounts = (@runs.map{|r| r.external_account}.uniq - accounts.map{|acc| acc.name}).map{|acc| Account.new(acc, self, @runner, @runs, true)}
104
+ accounts = @runs.map{|r| r.account}.uniq.map{|acc| Account.new(acc, self, @runner, @runs, false)}
105
+ external_accounts = (@runs.map{|r| r.external_account}.uniq - accounts.map{|acc| acc.name}).map{|acc| Account.new(acc, self, @runner, @runs, true)}
101
106
  #if not @report_currency
102
- external_accounts = external_accounts.map do |acc|
103
- if acc_inf = ACCOUNT_INFO[acc.name] and currencies = acc_inf[:currencies] and currencies.size > 1
104
- raise "Only expense accounts can have multiple currencies: #{acc.name} has type #{acc.type}" unless acc.type == :Expense
105
- new_accounts = currencies.map do |curr|
106
- Account.new(acc.name, self, @runner, @runs, true, currency: curr)
107
- end
108
- new_accounts.delete_if{|a| a.runs.size == 0}
109
- new_accounts
110
- else
111
- acc
107
+ external_accounts = external_accounts.map do |acc|
108
+ if acc_inf = ACCOUNT_INFO[acc.name] and currencies = acc_inf[:currencies] and currencies.size > 1
109
+ raise "Only expense accounts can have multiple currencies: #{acc.name} has type #{acc.type}" unless acc.type == :Expense
110
+ new_accounts = currencies.map do |curr|
111
+ Account.new(acc.name, self, @runner, @runs, true, currency: curr)
112
112
  end
113
+ new_accounts.delete_if{|a| a.runs.size == 0}
114
+ new_accounts
115
+ else
116
+ acc
113
117
  end
118
+ end
114
119
  #end
115
120
  external_accounts = external_accounts.flatten
116
121
  @accounts = accounts + external_accounts
@@ -148,6 +153,10 @@ class Treasurer
148
153
  acc.info[:opening_balance] *= EXCHANGE_RATES[[acc.currency, @report_currency]]
149
154
  end
150
155
  end
156
+ if acc.should_report?
157
+ #p acc.name_c
158
+ acc.generate_report_account
159
+ end
151
160
  acc.instance_variable_set(:@original_currency, acc.currency)
152
161
  acc.instance_variable_set(:@currency, @report_currency)
153
162
  acc.info[:currencies] = [@report_currency]
@@ -164,7 +173,7 @@ class Treasurer
164
173
  end
165
174
  @equities = @equities.to_h
166
175
  end
167
-
176
+
168
177
  def report
169
178
  generate_accounts
170
179
  #get_actual_accounts
@@ -199,18 +208,18 @@ class Treasurer
199
208
  <<EOF
200
209
  \\section{Summary of Accounts}
201
210
  #{[:Equity, :Asset, :Liability, :Income, :Expense].map{|type|
202
- accs = @accounts.find_all{|acc| acc.type == type }
211
+ accs = @accounts.find_all{|acc| acc.type == type and acc.should_report?}
203
212
  "\\subsection{#{type}}
204
- \\begin{tabulary}{0.9\\textwidth}{ R | c | c | c}
213
+ \\begin{tabulary}{0.9\\textwidth}{ R | r | r | r}
205
214
  Account & Balance & Deposited & Withdrawn \\\\
206
215
  \\hline
207
216
  \\Tstrut
208
- #{(accs.map{|acc| acc.summary_line(@today, @days_before)} +
209
- (type == :Asset ? ASSETS.map{|n,details| "#{n} (#{details[:currency]}) & #{details[:size]} & & "} : [])).join("\\\\\n")}
217
+ #{(accs.map{|acc| acc.report_account.summary_line(@today, @days_before)} +
218
+ (type == :Asset ? ASSETS.map{|n,details| "#{n} (#{details[:currency]}) & #{details[:size].to_tex} & & "} : [])).join("\\\\\n")}
210
219
  #{type!=:Equity&&false ? "
211
220
  \\\\ \\hline
212
221
  \\Tstrut
213
- Totals & #{accs.map{|a| a.balance}.sum} & #{accs.map{|a| a.deposited(@today, @days_before)}.sum} & #{accs.map{|a| a.withdrawn(@today, @days_before)}.sum} \\\\ " : "\\\\"}
222
+ Totals & #{accs.map{|a| a.balance}.sum.to_tex} & #{accs.map{|a| a.deposited(@today, @days_before)}.sum.to_tex} & #{accs.map{|a| a.withdrawn(@today, @days_before)}.sum.to_tex} \\\\ " : "\\\\"}
214
223
  \\end{tabulary}"
215
224
  }.join("\n\n")}
216
225
  EOF
@@ -219,7 +228,7 @@ EOF
219
228
  <<EOF
220
229
  \\section{Graphs of Recent Balances}
221
230
  #{[:Equity, :Asset, :Liability].map{|typ|
222
- "\\subsection{#{typ}}\\vspace{3em}" +
231
+ "\\subsection{#{typ}}\\vspace{3em}" +
223
232
  @accounts.find_all{|acc| acc.type == typ}.map{|acc|
224
233
  acc.write_balance_graph(@today, @days_before, @days_ahead)
225
234
  acc.balance_graph_string
@@ -234,9 +243,10 @@ EOF
234
243
  \\subsection{Totals for #@days_before-day Budget Period}
235
244
  #{expense_pie_charts_by_currency('accountperiod', @expense_accounts){|r| r.days_ago(@today) < @days_before}}
236
245
  \\subsection{Expense Account Breakdown}
237
- #{@expense_accounts.map{|account|
238
- #ep ['sub_accounts2124', account.sub_accounts.map{|sa| sa.name}]
239
- "\\subsection{#{account.name_c}}
246
+ #{@expense_accounts.find_all{|exaccount| exaccount.should_report?}.map{|exaccount|
247
+ account = exaccount.report_account
248
+ "
249
+ \\subsection{#{account.name_c}}
240
250
  #{expense_pie_chart(account.name_c_file + 'breakdown', account.sub_accounts, account){|r|r.days_ago(@today) < @days_before }}"
241
251
  }.join("\n\n")}
242
252
  EOF
@@ -258,7 +268,7 @@ EOF
258
268
  currencies.map do |curr|
259
269
  str = ""
260
270
  str << "\\subsubsection{#{curr}}\n" if curr
261
- str << expense_pie_chart(name + curr.to_s, accounts.find_all{|acc| acc.currency == curr}, &block)
271
+ str << expense_pie_chart(name + curr.to_s, accounts.find_all{|acc| acc.currency == curr and acc.should_report?}.map{|acc| acc.report_account}, &block)
262
272
  str
263
273
  end
264
274
  ).join("\n\n")
@@ -269,27 +279,27 @@ EOF
269
279
  #ep ['labels22539', name, labels, exps]
270
280
 
271
281
  kit = if subacc
272
- start_dates, end_dates, _exps, _items = account_expenditure(subacc)
273
- end_dates = end_dates.reverse #Now from earliest to latest
274
- start_dates = start_dates.reverse
275
- pp ['DATES', start_dates, end_dates, subacc.name]
276
- return "No expenditure in account period." if end_dates.size==0
277
- k = (
278
- end_dates.size.times.map do |i|
279
- exps = accounts.map{|acc| acc.deposited(end_dates[i], end_dates[i] - start_dates[i], &block)}
280
- kt = GraphKit.quick_create([labels.size.times.to_a.map{|l| l.to_f + i.to_f/end_dates.size.to_f}, exps])
281
- kt.data[0].gp.title = "Ending #{end_dates[i].strftime("#{end_dates[i].mday.ordinalize} %B")}; total = #{exps.sum}"
282
- kt.gp.key = "tmargin"
283
- kt
284
- end
285
- ).sum
286
- k
287
- else
288
- exps = accounts.map{|acc| acc.deposited(@today, 50000, &block)}
289
- labels, exps = [labels, exps].transpose.find_all{|l, e| e != 0.0}.transpose
290
- return "No expenditure in account period." if not labels #<F8> labels.size==0
291
- GraphKit.quick_create([labels.size.times.to_a, exps])
292
- end
282
+ start_dates, end_dates, _exps, _items = account_expenditure(subacc)
283
+ end_dates = end_dates.reverse #Now from earliest to latest
284
+ start_dates = start_dates.reverse
285
+ pp ['DATES', start_dates, end_dates, subacc.name]
286
+ return "No expenditure in account period." if end_dates.size==0
287
+ k = (
288
+ end_dates.size.times.map do |i|
289
+ exps = accounts.map{|acc| acc.deposited(end_dates[i], end_dates[i] - start_dates[i], &block)}
290
+ kt = GraphKit.quick_create([labels.size.times.to_a.map{|l| l.to_f + i.to_f/end_dates.size.to_f}, exps])
291
+ kt.data[0].gp.title = "Ending #{end_dates[i].strftime("#{end_dates[i].mday.ordinalize} %B")}; total = #{exps.sum}"
292
+ kt.gp.key = "tmargin"
293
+ kt
294
+ end
295
+ ).sum
296
+ k
297
+ else
298
+ exps = accounts.map{|acc| acc.deposited(@today, 50000, &block)}
299
+ labels, exps = [labels, exps].transpose.find_all{|l, e| e != 0.0}.transpose
300
+ return "No expenditure in account period." if not labels #<F8> labels.size==0
301
+ GraphKit.quick_create([labels.size.times.to_a, exps])
302
+ end
293
303
 
294
304
 
295
305
  #sum = exps.sum
@@ -311,7 +321,7 @@ EOF
311
321
  i = -1
312
322
  kit.gp.xtics = "(#{labels.map{|l| %["#{l}" #{i+=1}]}.join(', ')}) rotate by 315"
313
323
  pp ['kit222', kit, labels]
314
- fork do
324
+ fork do
315
325
  kit.gnuplot_write("#{name}.eps", size: "4.0in,2.0in")
316
326
  %x[epspdf #{name}.eps]
317
327
  end
@@ -362,16 +372,18 @@ EOF
362
372
  #exit
363
373
  end
364
374
  def discretionary_account_table(currency)
365
- discretionary_accounts = accounts_with_averages(@projected_accounts_info.find_all{|acc,inf| acc.currency == currency}.to_h)
375
+ discretionary_accounts = accounts_with_averages(
376
+ @projected_accounts_info.find_all{|acc,inf| acc.currency == currency and acc.should_report?}.map{|acc,inf| [acc.report_account,inf]}.to_h)
377
+ accounts_with_projections(discretionary_accounts.keys)
366
378
 
367
379
  <<EOF
368
380
  \\section{Discretionary Budget Summary (#{currency})}
369
- \\begin{tabulary}{0.9\\textwidth}{ R | c c c c }
381
+ \\begin{tabulary}{0.9\\textwidth}{ R | r r r r }
370
382
  Budget & Average & Projection & Limit & Stable \\\\
371
383
  #{discretionary_accounts.map{|account, info|
372
384
  #ep info
373
385
  "#{account.name_c} & #{account.average} & #{account.projection} & #{
374
- (account.projection * @in_limit_discretionary_account_factors[currency]).round(2)} &
386
+ (account.projection * @in_limit_discretionary_account_factors[currency]).round(2)} &
375
387
  #{(account.projection * @stable_discretionary_account_factors[currency]).round(2)} \\\\"
376
388
  }.join("\n\n")
377
389
  }
@@ -381,15 +393,15 @@ EOF
381
393
  def account_expenditure_graphs
382
394
  <<EOF
383
395
  \\section{Expenditure by Account Period}
384
- #{currency_list.map{|curr|
385
- account_and_transfer_graphs(@expense_accounts.find_all{|acc|
386
- acc.info and acc.info[:period] and acc.currency == curr
387
- })
396
+ #{currency_list.map{|curr|
397
+ account_and_transfer_graphs(@expense_accounts.find_all{|acc|
398
+ acc.info and acc.info[:period] and acc.currency == curr and acc.should_report?
399
+ }.map{|acc| acc.report_account})
388
400
  }.join("\n")}
389
401
  EOF
390
402
  end
391
403
  def account_and_transfer_graphs(accounts, options={})
392
- "#{accounts.map{|account|
404
+ "#{accounts.map{|account|
393
405
  account_info = account.info
394
406
  #ep ['accountbadf', account, account_info]
395
407
  start_dates, dates, expenditures, _items = account_expenditure(account)
@@ -416,11 +428,11 @@ EOF
416
428
  kit.xlabel = nil
417
429
  kit.ylabel = nil
418
430
  unless options[:transfers]
419
- kits = accounts_with_averages({account => account_info}).map{|account, account_info|
431
+ kits = accounts_with_averages({account => account_info}).map{|acco, acco_info|
420
432
  #ep 'Budget is ', account
421
433
  kit2 = GraphKit.quick_create([
422
- [dates[0], dates[-1]].map{|d| d.to_time.to_i - barsize},
423
- [account.average, account.average]
434
+ [dates[0], dates[-1]].map{|d| d.to_time.to_i - barsize},
435
+ [acco.average, acco.average]
424
436
  ])
425
437
  kit2.data[0].gp.with = 'l lw 5'
426
438
  kit2
@@ -436,7 +448,7 @@ EOF
436
448
  CodeRunner::Budget.kit_time_format_x(kit)
437
449
  #kit.gnuplot
438
450
  #ep ['kit1122', account, kit]
439
- fork do
451
+ fork do
440
452
  kit.gnuplot_write("#{account.name_c_file}.eps", size: "4.0in,2.0in")
441
453
  exec "epspdf #{account.name_c_file}.eps"
442
454
  end
@@ -487,8 +499,8 @@ This section sums items from accounts drawn from an alternate account, i.e. it d
487
499
 
488
500
  \\Tstrut
489
501
 
490
- #{piece.map{|r|
491
- ([:id] + CodeRunner::Budget.rcp.component_results - [:sc]).map{|res|
502
+ #{piece.map{|r|
503
+ ([:id] + CodeRunner::Budget.rcp.component_results - [:sc]).map{|res|
492
504
  r.send(res).to_s.latex_escape
493
505
  #rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
494
506
  }.join(" & ")
@@ -517,12 +529,12 @@ EOF
517
529
  def account_breakdown
518
530
  <<EOF
519
531
  \\section{SubAccount Breakdown}
520
- #{(@actual_accounts).map{|account, account_info|
532
+ #{(@actual_accounts).map{|account, account_info|
521
533
  _start_dates, dates, expenditures, account_items = account_expenditure(account, account_info)
522
534
  #pp account, account_items.map{|items| items.map{|i| i.date.to_s}}
523
- "\\subsection{#{account}}" +
535
+ "\\subsection{#{account}}" +
524
536
  account_items.zip(dates, expenditures).map{|items, date, expenditure|
525
- if items.size > 0
537
+ if items.size > 0
526
538
  "
527
539
  \\small
528
540
  \\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " L " + " r " * 2 + " c " }}
@@ -530,8 +542,8 @@ EOF
530
542
  #{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
531
543
  \\hline
532
544
  \\Tstrut
533
- #{items.map{|r|
534
- ( CodeRunner::Budget.rcp.component_results + [:external_account] - [:sc, :balance ]).map{|res|
545
+ #{items.map{|r|
546
+ ( CodeRunner::Budget.rcp.component_results + [:external_account] - [:sc, :balance ]).map{|res|
535
547
  r.send(res).to_s.latex_escape
536
548
  }.join(" & ")
537
549
  }.join("\\\\\n")
@@ -541,7 +553,7 @@ EOF
541
553
  \\end{tabulary}
542
554
  \\normalsize
543
555
  \\vspace{1em}\n\n"
544
- else
556
+ else
545
557
  ""
546
558
  end
547
559
  }.join("\n\n")
@@ -553,7 +565,7 @@ EOF
553
565
  def transactions_by_account
554
566
  <<EOF
555
567
  \\section{Recent Transactions}
556
- #{@accounts.find_all{|acc| not acc.type == :Equity}.sort_by{|acc| acc.external ? 0 : 1}.map{|acc|
568
+ #{@accounts.find_all{|acc| not acc.type == :Equity}.sort_by{|acc| acc.external ? 0 : 1}.map{|acc|
557
569
  "\\subsection{#{acc.name_c}}
558
570
  \\tiny
559
571
  #{all = acc.runs.find_all{|r| r.days_ago(@today) < @days_before}
@@ -566,10 +578,10 @@ EOF
566
578
  #ep ['acc', acc, 'ids', all.map{|r| r.id}, 'size', all.size]
567
579
  all.pieces((all.size.to_f/50.to_f).ceil).map{|piece|
568
580
  "\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 3 + " l " + " r " * 3 + "l"}}
569
- #{piece.map{|r|
570
- (CodeRunner::Budget.rcp.component_results - [:sc] + [:sub_account]).map{|res|
581
+ #{piece.map{|r|
582
+ (CodeRunner::Budget.rcp.component_results - [:sc] + [:sub_account]).map{|res|
571
583
  entry = r.send(res).to_s.latex_escape
572
- #if
584
+ #if
573
585
  entry = entry[0...25] if entry.length > 25
574
586
  #if entry.length > 40
575
587
  #entry = entry.split(/.{40}/).join(" \\newline ")
@@ -596,9 +608,9 @@ EOF
596
608
  \\usepackage{libertine}
597
609
  \\usepackage{xcolor,listings}
598
610
  \\newcommand\\Tstrut{\\rule{0pt}{2.8ex}}
599
- \\newcommand\\myfigure[1]{\\vspace*{0em}\\begin{center}
611
+ \\newcommand\\myfigure[1]{\\vspace*{1em}\\begin{center}
600
612
 
601
- \\includegraphics[width=0.9\\textwidth]{#1}
613
+ \\includegraphics[width=0.99\\textwidth]{#1}
602
614
 
603
615
  \\end{center}\\vspace*{0em}
604
616
 
@@ -636,10 +648,10 @@ EOF
636
648
  end
637
649
  end
638
650
  #\\subsection{Last Week}
639
- ##{expense_pie_charts_by_currency('lastweekexpenses', @expense_accounts){|r|
640
- ##p ['r.daysago', r.days_ago(@today)];
641
- #r.days_ago(@today) < 7}}
651
+ ##{expense_pie_charts_by_currency('lastweekexpenses', @expense_accounts){|r|
652
+ ##p ['r.daysago', r.days_ago(@today)];
653
+ #r.days_ago(@today) < 7}}
642
654
  #\\subsection{Last Month}
643
- ##{expense_pie_charts_by_currency('lastmonthexpenses', @expense_accounts){|r| r.days_ago(@today) < 30}}
655
+ ##{expense_pie_charts_by_currency('lastmonthexpenses', @expense_accounts){|r| r.days_ago(@today) < 30}}
644
656
  #\\subsection{Last Year}
645
- ##{expense_pie_charts_by_currency('lastyearexpenses', @expense_accounts){|r| r.days_ago(@today) < 365}}
657
+ ##{expense_pie_charts_by_currency('lastyearexpenses', @expense_accounts){|r| r.days_ago(@today) < 365}}
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.6.0 ruby lib
5
+ # stub: treasurer 0.7.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "treasurer".freeze
9
- s.version = "0.6.0"
9
+ s.version = "0.7.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Edmund Highcock".freeze]
14
- s.date = "2018-04-05"
14
+ s.date = "2018-04-06"
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.".freeze
16
16
  s.email = "edmundhighcock@users.sourceforge.net".freeze
17
17
  s.executables = ["treasurer".freeze]
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.6.0
4
+ version: 0.7.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: 2018-04-05 00:00:00.000000000 Z
11
+ date: 2018-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport