budgetcrmod 0.2.3 → 0.3.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: 690a66a464147f4818488e427d9556a46a2f5352
4
- data.tar.gz: 90406cb37a7885adf871b362c44e52049747fc66
3
+ metadata.gz: 2015715dae350f93b7931297fa1696a27ab988f3
4
+ data.tar.gz: 719be9cb86645aa5a7ecc46c4588fb6baa2b17d4
5
5
  SHA512:
6
- metadata.gz: c12a9b4c4a0b764f3f3c003970dcb6a6bcb358fcfdb4d5c6da95c96aef192b00fe8539c259463ef9e74df93d50bcac6759ed0f85a8a25f8a29ae5a57cd74ddd7
7
- data.tar.gz: 5c0b29941d7ae468b5eb6ccf51dcc89baeb8e6e0c454c4c1608a4e55144ffd635294c2c8f73ff7b6d95700eb9604e2c9112dd0fd462858226c109833d7af81ba
6
+ metadata.gz: 11dfb82752c234ca805a69b9abe16456201adf18adc849c29799ea927d0e317705f30dba08c9907f041a536da483980ee7fffc1d6c6664b9c876b5d01a9de432
7
+ data.tar.gz: 969c97060b903b1c2661823f3c4df19d05700a4724249b41e9a03f9219a7b2dc111d549b9cce62dc4597be274785b01a0aaded206b0d815a84c84ae8133a32fe
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.3.0
data/budgetcrmod.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: budgetcrmod 0.2.3 ruby lib
5
+ # stub: budgetcrmod 0.3.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "budgetcrmod".freeze
9
- s.version = "0.2.3"
9
+ s.version = "0.3.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-09"
14
+ s.date = "2018-04-10"
15
15
  s.description = "A CodeRunner module to help you do your budget".freeze
16
16
  s.email = "edmundhighcock@users.sourceforge.net".freeze
17
17
  s.extra_rdoc_files = [
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  "VERSION",
28
28
  "budgetcrmod.gemspec",
29
29
  "lib/budgetcrmod.rb",
30
+ "lib/budgetcrmod/account_choices.rb",
30
31
  "lib/budgetcrmod/budget.rb",
31
32
  "lib/budgetcrmod/defaults_files/budget_defaults.rb",
32
33
  "test/helper.rb",
@@ -0,0 +1,145 @@
1
+
2
+ class CodeRunner::Budget
3
+ # All transactions occur between two accounts.
4
+ # One of those accounts is always physical (e.g. bank account, loan, credit card)
5
+ # and the other can be either physical or a virtual account of the users choice,
6
+ # e.g. Food or Petrol or Energy, or maybe WeeklyBudget and LongTermBudget etc.
7
+ def external_account
8
+ return @external_account if @external_account
9
+ ext_account = false
10
+ Dir.chdir(@runner.root_folder) do
11
+ chosen = false
12
+ Hash.phoenix('account_choices.rb') do |choices_hash|
13
+ if choices_hash[data_line]
14
+ #choices_hash[data_line][:external_account] =
15
+ #choices_hash[data_line][:external_account].to_sym #fixes earlier bug
16
+ #choices_hash[data_line][:sub_account] =
17
+ #choices_hash[data_line][:sub_account].to_sym #fixes earlier bug
18
+ chosen = choices_hash[data_line][:external_account]
19
+ end
20
+ end
21
+ return @external_account = chosen if chosen
22
+ chosen = false
23
+ sym = nil
24
+ while not chosen
25
+ Hash.phoenix('external_accounts.rb') do |account_hash|
26
+ #account_hash.each{|k,v| v[:name] = v[:name].to_sym} #Fixes an earlier bug
27
+ #choices = account_arr.size.times.map{|i| [i,account_arr[i][:name]]}
28
+ choices = account_hash.map{|k,v| [v[:sym], k]}.to_h
29
+ puts Terminal.default_colour
30
+ puts
31
+ puts "-" * data_line.size
32
+ puts data_line
33
+ puts "-" * data_line.size
34
+ puts
35
+ puts choices.inspect
36
+ puts
37
+ puts "Please choose from the above external accounts for this transaction."
38
+ puts "If you wish to add a new account type 0. To quit type q"
39
+ puts "To start again for this transaction, type z"
40
+ while not chosen
41
+ require 'io/console'
42
+ choice = STDIN.getch
43
+ if choice == "q"
44
+ throw :quit_data_entry
45
+ elsif choice == "0"
46
+ puts "Please type the name of the new account"
47
+ name = STDIN.gets.chomp.to_sym
48
+ puts "Please enter a symbol to represent this account (e.g. digit, letter, punctuation)."
49
+ sym = false
50
+ until sym
51
+ sym = STDIN.getch
52
+ if choices.keys.include? sym
53
+ puts "This symbol is taken"
54
+ sym = false
55
+ end
56
+ end
57
+ account_hash[name] = {name: name, sym: sym, sub_accounts: {}}
58
+ #choices_hash[@id] = name
59
+ chosen = name
60
+ elsif choice == "z"
61
+ chosen = false
62
+ break
63
+ elsif not choices.keys.include? choice
64
+ puts "Error: this symbol does not correspond to an account"
65
+ else
66
+ chosen = choices[choice] #account_hash[choice][:name]
67
+ end
68
+ end
69
+ #Hash.phoenix('account_choices.rb') do |choices_hash|
70
+ #choices_hash[data_line] = {external_account: chosen}
71
+ #end
72
+ end
73
+ ext_account = chosen
74
+ next if not chosen
75
+ chosen = false
76
+ Hash.phoenix('external_accounts.rb') do |account_hash|
77
+ #choices = account_arr.size.times.map{|i| [i,account_arr[i][:name]]}
78
+ sub_accounts = account_hash[ext_account][:sub_accounts]
79
+ sub_accounts.each{|k,v| v[:name] = v[:name].to_sym} #Fixes an earlier bug
80
+ choices = sub_accounts.map{|k,v| [v[:sym], k]}.to_h
81
+ puts "-" * data_line.size
82
+ puts
83
+ puts choices.inspect
84
+ puts
85
+ puts "Please choose from the above sub-accounts for this transaction."
86
+ puts "If you wish to add a new sub account, type 0. To quit, type q"
87
+ puts "To start again for this transaction, type z"
88
+ while not chosen
89
+ require 'io/console'
90
+ choice = STDIN.getch
91
+ if choice == "q"
92
+ throw :quit_data_entry
93
+ elsif choice == "0"
94
+ puts "Please type the name of the new sub account"
95
+ name = STDIN.gets.chomp.to_sym
96
+ puts "Please enter a symbol to represent this account (e.g. digit, letter, punctuation)."
97
+ sym = false
98
+ until sym
99
+ sym = STDIN.getch
100
+ if choices.keys.include? sym
101
+ puts "This symbol is taken"
102
+ sym = false
103
+ end
104
+ end
105
+ sub_accounts[name] = {name: name, sym: sym}
106
+ #choices_hash[@id] = name
107
+ chosen = name
108
+ elsif choice == "z"
109
+ chosen = false
110
+ break
111
+ elsif not choices.keys.include? choice
112
+ puts "Error: this symbol does not correspond to a sub-account"
113
+ else
114
+ chosen = choices[choice] #sub_accounts[choice][:name]
115
+ end
116
+ end
117
+ end
118
+ next if not chosen
119
+ Hash.phoenix('account_choices.rb') do |choices_hash|
120
+ choices_hash[data_line] = {external_account: ext_account, sub_account: chosen}
121
+ end
122
+ end #while not chosen
123
+
124
+ end
125
+ ext_account
126
+ end
127
+ # All transactions have a subaccount. For transactions between
128
+ # physical accounts this will almost always be just 'Transfer'
129
+ # or similar, but virtual accounts will have more meaningful
130
+ # sub_accounts, e.g. Food might have Groceries, EatingOut
131
+ # or WeeklyBudget might have Transport, Food, Clothes... depending
132
+ # on the users preferred way of organising things.
133
+ # The sub_accounts are primarily a labelling exercise, but done
134
+ # well can be very helpful in showing a breakdown of expenditure.
135
+ def sub_account
136
+ return @sub_account if @sub_account
137
+ Dir.chdir(@runner.root_folder) do
138
+ external_account until (
139
+ choices = Hash.phoenix('account_choices.rb'){|choices_hash| choices_hash[data_line]}
140
+ p [choices, data_line]
141
+ ) and choices[:sub_account]
142
+ @sub_account = choices[:sub_account]
143
+ end
144
+ end
145
+ end
@@ -39,15 +39,6 @@ class CodeRunner
39
39
 
40
40
  @code_module_folder = File.dirname(File.expand_path(__FILE__)) # i.e. the directory this file is in
41
41
 
42
- # ["05/07/2010",
43
- # "DEB",
44
- # "308760",
45
- # "25387560",
46
- # "ANGELSCD 0655",
47
- # "",
48
- # "11.50",
49
- # "4506.80"]
50
- #
51
42
  @component_results = [:date, :type, :sc, :ac, :description, :deposit, :withdrawal, :balance]
52
43
  @results = [:date_i, :data, :data_line, :dataset] + @component_results
53
44
  def generate_input_file
@@ -241,10 +232,6 @@ class CodeRunner
241
232
  end
242
233
  end
243
234
  def days_ago(today = Date.today)
244
- #ep ['today', today, date]
245
- # sprintf("%04d%02d%02d", date.year, date.month, date.day).to_i
246
- #cache[:days_ago] ||= {}
247
- #cache[:days_ago][today.to_s] ||=
248
235
  - ((date.to_datetime.to_time.to_i - today.to_datetime.to_time.to_i) / 24 / 3600).to_i
249
236
  end
250
237
  def idate
@@ -255,164 +242,7 @@ class CodeRunner
255
242
  end
256
243
 
257
244
 
258
- #def self.sum_future(future_items, end_date, options={})
259
- #sum = future_items.inject(0) do |sum, (name, item)|
260
- #item = [item] unless item.kind_of? Array
261
- #value = item.inject(0) do |value,info|
262
- #value += info[:size] unless (options[:today]||Date.today > info[:date]) or (info[:date] > end_date) # add unless we have already passed that date
263
- #value
264
- #end
265
- #rcp.excluding.include?(name) ? sum : sum + value
266
- #end
267
- #sum
268
- #end
269
-
270
- #def self.budget_expenditure(runner, budget, budget_info, start_date, options={})
271
- #dates = []
272
- #expenditures = []
273
- #budget_items = []
274
- #date = budget_info[:end]||options[:today]||Date.today
275
- #start_date = [(budget_info[:start]||start_date), start_date].max
276
- #expenditure = 0
277
- #items_temp = []
278
- #items = runner.component_run_list.values.find_all{|r| r.budget == budget and r.in_date(budget_info)}
279
- ##ep ['items', items]
280
- ##ep ['budget', budget]
281
- #counter = 0
282
- #if not budget_info[:period]
283
- #dates.push date
284
- #budget_items.push items
285
- #expenditures.push (items.map{|r| r.debit - r.credit}+[0]).sum
286
- #else
287
-
288
- #case budget_info[:period][1]
289
- #when :month
290
- #while date > start_date
291
- #items_temp += items.find_all{|r| r.date == date}
292
- #if date.mday == (budget_info[:monthday] or 1)
293
- #counter +=1
294
- #if counter % budget_info[:period][0] == 0
295
- #expenditure = (items_temp.map{|r| r.debit - r.credit}+[0]).sum
296
- #dates.push date
297
- #expenditures.push expenditure
298
- #budget_items.push items_temp
299
- #items_temp = []
300
- #expenditure = 0
301
- #end
302
- #end
303
- #date-=1
304
- #end
305
- #when :day
306
- #while date > start_date
307
- #items_temp += items.find_all{|r| r.date == date}
308
- ##expenditure += (budget_items[-1].map{|r| r.debit}+[0]).sum
309
- #counter +=1
310
- #if counter % budget_info[:period][0] == 0
311
- #expenditure = (items_temp.map{|r| r.debit - r.credit}+[0]).sum
312
- #dates.push date
313
- #expenditures.push expenditure
314
- #budget_items.push items_temp
315
- #items_temp = []
316
- #expenditure = 0
317
- #end
318
- #date-=1
319
- #end
320
- #end
321
- #end
322
-
323
- #[dates, expenditures, budget_items]
324
-
325
- #end
326
-
327
- #def self.sum_regular(regular_items, end_date, options={})
328
- #today = options[:today]||Date.today
329
- #sum = regular_items.inject(0) do |sum, (name, item)|
330
- #item = [item] unless item.kind_of? Array
331
- ## ep item
332
- #value = item.inject(0) do |value,info|
333
- #finish = (info[:end] and info[:end] < end_date) ? info[:end] : end_date
334
- ##today = (Time.now.to_i / (24.0*3600.0)).round
335
-
336
- #nunits = 0
337
- #counter = info[:period][0] == 1 ? 0 : nil
338
- #####################unless counter
339
- #####################date = today
340
- #####################counter = 0
341
- #####################case info[:period][1]
342
- #####################when :month
343
- #####################while date >= (info[:start] or Date.today)
344
- #####################counter +=1 if date.mday == (info[:monthday] or 1)
345
- #####################date -= 1
346
- #####################end
347
- #####################when :year
348
- #####################while date >= (info[:start] or Date.today)
349
- #####################counter +=1 if date.yday == (info[:yearday] or 1)
350
- #####################date -= 1
351
- #####################end
352
- #####################when :day
353
- #####################while date > (info[:start] or Date.today)
354
- #####################counter +=1
355
- #####################date -= 1
356
- #####################end
357
- #####################end
358
- #####################end
359
- #date = today
360
- #########################case info[:period][1]
361
- #########################when :month
362
- ##########################p date, info
363
- #########################while date <= finish
364
- #########################if date.mday == (info[:monthday] or 1)
365
- #########################nunits += 1 if counter % info[:period][0] == 0
366
- #########################counter +=1
367
- #########################end
368
- #########################date += 1
369
- #########################end
370
- #########################when :year
371
- #########################while date <= finish
372
- #########################if date.yday == (info[:yearday] or 1)
373
- #########################nunits += 1 if counter % info[:period][0] == 0
374
- #########################counter +=1
375
- #########################end
376
- #########################date += 1
377
- #########################end
378
- #########################when :day
379
- #########################while date <= finish
380
- #########################nunits += 1 if counter % info[:period][0] == 0
381
- #########################counter +=1
382
- #########################date += 1
383
- #########################end
384
- #########################end
385
-
386
-
387
-
388
-
389
-
390
- ##nyears = (finish.year - today.year)
391
- ##nmonths = nyears * 12 + (finish.month - today.month)
392
- ##(puts "Number of Months: #{nmonths}"; @pnmonths=true) unless @pnmonths
393
- ##ndays = nyears * 12 + (finish.yday - today.yday)
394
- ##number = case info[:period][1]
395
- ##when :month
396
- ##(nmonths / info[:period][0]).ceil
397
- ##when :day
398
- ##(ndays / info[:period][0]).ceil
399
- ##end
400
- ##value + number * info[:size]
401
- ##eputs "Regular Expenditure Item: #{sprintf("%10s", name)} -- #{nunits} payments, total #{nunits * info[:size]}"
402
- #value + nunits * info[:size]
403
-
404
- #end
405
- #(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value
406
- #end
407
- #sum
408
- #end
409
245
  def self.predictable_component_ids(runner)
410
- #runner.instance_variable_set(:@component_run_list, {})
411
- #runner.instance_variable_set(:@component_ids, [])
412
- #runner.instance_variable_set(:@component_id, -1)
413
- #runner.run_list.each{|r| r.instance_variable_set(:@component_runs, [])}
414
- #runner.run_list.values.sort_by{|r| r.id}.each{|r| r.generate_component_runs}
415
- #runner.save_large_cache
416
246
  end
417
247
  def self.kit_time_format_x(kit)
418
248
  kit.gp.timefmt = %["%s"]
@@ -425,289 +255,8 @@ class CodeRunner
425
255
  kit.gp.xtics = "rotate by 340 offset 0,-0.5 2629746"
426
256
  end
427
257
 
428
- def self.print_budget(options={})
429
- @excluding = (options[:excluding] or [])
430
- runner = CodeRunner.fetch_runner(Y: Dir.pwd)
431
- puts "------------------------------"
432
- puts " Budget Report"
433
- puts "------------------------------"
434
- balance = runner.component_run_list.values.sort_by{|r| [r.date, r.id]}.map{|r| r.balance}[-1]
435
- puts "Balance: #{balance}"
436
- end_date = Date.parse("01/10/2011")
437
- puts "Regular Expenditure: #{total_regular = sum_regular(REGULAR_EXPENDITURE, end_date)}"
438
- puts "Future Expenditure: #{total_future = sum_future(FUTURE_EXPENDITURE, end_date)}"
439
- puts "Total Expenditure: #{total_expenditure = total_future + total_regular}"
440
- puts "Total Income: #{total_incoming = sum_future(FUTURE_INCOME, end_date)}"
441
- total = balance + total_incoming - total_expenditure
442
- puts "Weekly Budget: #{total/((end_date.to_datetime.to_time.to_i - Time.now.to_i) / 3600 / 24 / 7)}"
443
- end
444
-
445
- #def self.budgets_with_averages(runner, budgets, start_date, options={})
446
- #projected_budgets = budgets.dup
447
- #projected_budgets.each{|key,v| projected_budgets[key]=projected_budgets[key].dup}
448
- #projected_budgets.each do |budget, budget_info|
449
- ##budget_info = budgets[budget]
450
- #dates, expenditures, items = budget_expenditure(runner, budget, budget_info, start_date, today: options[:today])
451
- #budget_info[:size] = expenditures.mean rescue 0.0
452
- #end
453
- #projected_budgets
454
- #end
455
-
456
- #def self.latex_budget_transfers(runner, budgets, options)
457
- #numdays = options[:days]
458
- #today = options[:today]||Date.today
459
- #"#{budgets.map{|budget, budget_info|
460
- #dates, expenditures, items = budget_expenditure(runner, budget, budget_info, today - numdays, today: options[:today])
461
- ##ep ['budget', budget, dates, expenditures]
462
- #kit = GraphKit.quick_create([dates.map{|d| d.to_time.to_i}, expenditures])
463
- #kit.data.each{|dk| dk.gp.with="boxes"}
464
- #kit.gp.style = "fill solid"
465
- #kit.xlabel = nil
466
- #kit.ylabel = "Expenditure"
467
- #unless options[:transfers]
468
- #kits = budgets_with_averages(runner, {budget => budget_info}, today - numdays, today: today).map{|budget, budget_info|
469
- ##ep 'Budget is ', budget
470
- #kit2 = GraphKit.quick_create([
471
- #[dates[0], dates[-1]].map{|d| d.to_time.to_i},
472
- #[budget_info[:size], budget_info[:size]]
473
- #])
474
- #kit2.data[0].gp.with = 'lp lw 4'
475
- #kit2
476
- #}
477
- ##$debug_gnuplot = true
478
- ##kits.sum.gnuplot
479
- #kit += kits.sum
480
-
481
- #else
482
- #kit.data[0].y.data.map!{|expen| expen*-1.0}
483
- #end
484
- #kit.title = "#{budget} Expenditure with average (Total = #{kit.data[0].y.data.sum})"
485
- #kit_time_format_x(kit)
486
- ##kit.gnuplot
487
- #kit.gnuplot_write("#{budget}.eps")
488
- #"\\begin{center}\\includegraphics[width=4.0in]{#{budget}.eps}\\vspace{1em}\\end{center}"
489
- #}.join("\n\n")
490
- #}"
491
- #end
492
-
493
- #def self.latex_report(options={})
494
- #runner = CodeRunner.fetch_runner(Y: Dir.pwd, h: :component)
495
- #numdays = options[:days]
496
- #today = options[:today] || Date.today
497
- ## Delete budgets that contain no items
498
- #actual_budgets = BUDGETS.dup
499
- #BUDGETS.keys.each do |budget|
500
- #actual_budgets.delete(budget) if budget_expenditure(runner, budget, BUDGETS[budget], today - numdays, today: today)[0].size == 0
501
- #end
502
- ##predictable_component_ids(runner)
503
- #days_ahead = options[:days_ahead]
504
- #runs = runner.component_run_list.values
505
- #indateruns = runs.find_all{|r| r.days_ago < numdays}
506
- #accounts = runs.map{|r| r.account}.uniq
507
- #ep 'Accounts', accounts
508
- #projected_budgets = Hash[actual_budgets.dup.find_all{|k,v| v[:discretionary]}]
509
- #projected_budgets = budgets_with_averages(runner,projected_budgets, today - numdays, today: today)
510
- ##projected_budgets.each{|key,v| projected_budgets[key]=projected_budgets[key].dup}
511
- ##projected_budgets.each do |budget, budget_info|
512
- ###budget_info = budgets[budget]
513
- ##dates, expenditures, items = budget_expenditure(runner, budget, budget_info, today - numdays)
514
- ##budget_info[:size] = expenditures.mean
515
- ##end
516
- #ep 'projected_budgets', projected_budgets
517
- #File.open('report.tex', 'w') do |file|
518
- #file.puts <<EOF
519
- #\\documentclass{article}
520
- #\\usepackage[cm]{fullpage}
521
- #\\usepackage{tabulary}
522
- #\\usepackage{graphicx}
523
- #%\\usepackage{hyperlink}
524
- #\\newcommand\\Tstrut{\\rule{0pt}{2.8ex}}
525
- #\\begin{document}
526
- #\\title{#{numdays}-day Budget Report}
527
- #\\maketitle
528
- #\\tableofcontents
529
-
530
- #\\section{Summary of Accounts}
531
- ##{accounts.map{|acc|
532
- #"\\subsection{#{acc}}
533
- #\\begin{tabulary}{0.8\\textwidth}{ r l}
534
- ###Balance & #{runs.find_all{|r| r.account==acc}.sort_by{|r|
535
- ###r.date
536
- ###}[-1].balance} \\\\
537
- #####Expenditure & #{runs.find_all{|r| r.account==acc &&
538
- #####r.days_ago < numdays
539
- #####}.map{|r|
540
- #####r.debit
541
- #####}.sum} \\\\
542
- ###Income & #{runs.find_all{|r| r.account==acc &&
543
- ###r.days_ago < numdays
544
- ###}.map{|r| r.credit}.sum} \\\\
545
- #\\end{tabulary}"}.join("\n\n")
546
- #}
547
-
548
- #\\section{Graphs of Recent Balances}
549
- ##{accounts.map{|acc|
550
- #balance = runs.find_all{|r| r.account==acc}.sort_by{|r| r.date }[-1].balance
551
- #accshort = acc.gsub(/\s/, '')
552
- #kit = runner.graphkit(['date.to_time.to_i', 'balance'], {conditions: "account == #{acc.inspect} and days_ago < #{numdays}", sort: 'date'})
553
- #futuredates = (today..today+days_ahead).to_a
554
- ##p ["Regtrans", REGULAR_TRANSFERS.values_at(*REGULAR_TRANSFERS.keys.find_all{|from,to| to == acc})]
555
-
556
- #budgets = Hash[projected_budgets.find_all{|k,v| v[:account] == acc}]
557
- #ep ['budgets', budgets]
558
- #projection = futuredates.map{|date| balance -
559
- #sum_regular(REGULAR_EXPENDITURE[acc], date, today: today) +
560
- #sum_regular(REGULAR_INCOME[acc], date, today: today) -
561
- #sum_regular(budgets, date, today: today) -
562
- #sum_future(FUTURE_EXPENDITURE[acc], date, today: today) +
563
- #sum_future(FUTURE_INCOME[acc], date, today: today) +
564
- #(REGULAR_TRANSFERS.keys.find_all{|from,to| to == acc}.map{|key|
565
- ##p [acc, 'to', "key", key]
566
- #sum_regular( REGULAR_TRANSFERS[key], date, today: today)
567
- #}.sum||0) -
568
- #(REGULAR_TRANSFERS.keys.find_all{|from,to| from == acc}.map{|key|
569
- ##p [acc, 'from',"key", key]
570
- #sum_regular( REGULAR_TRANSFERS[key], date, today: today)
571
- #}.sum||0)
572
- #}
573
- #kit2 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, projection])
574
- #kit += kit2
575
- #kit.title = "Balance for #{acc}"
576
- #kit.xlabel = %['Date' offset 0,-2]
577
- #kit.xlabel = nil
578
- #kit.ylabel = "Balance"
579
-
580
- #kit.data[0].gp.title = 'Previous'
581
- #kit.data[1].gp.title = '0 GBP Discretionary'
582
- #kit.data[1].gp.title = 'Projection'
583
- #kit.data.each{|dk| dk.gp.with = "lp"}
584
-
585
- #kit_time_format_x(kit)
586
-
587
- #(kit).gnuplot_write("#{accshort}_balance.eps", size: "4.0in,3.0in")
588
- #"\\begin{center}\\includegraphics[width=4.0in]{#{accshort}_balance.eps}\\end{center}"
589
- #}.join("\n\n")
590
- #}
591
-
592
-
593
- #\\section{Budget Expenditure}
594
- ##{latex_budget_transfers(runner,actual_budgets, options)}
595
-
596
- #\\section{Transfers}
597
- ##{latex_budget_transfers(runner, TRANSFERS, options.dup.absorb({transfers: true}))}
598
-
599
-
600
-
601
- #\\section{Budget Resolutions}
258
+ require 'budgetcrmod/account_choices.rb'
602
259
 
603
- #This section sums items from budgets drawn from an alternate account, i.e. it determines how much should be transferred from one account to another as a result of expenditure from a given budget.
604
-
605
- ##{actual_budgets.map{|budget, budget_info|
606
-
607
- ########################################"\\subsection{#{budget} }
608
- ########################################\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{r l}
609
- ########################################%\\hline
610
- ########################################Account Owed & Amount \\\\
611
- ########################################\\hline
612
- ########################################\\Tstrut
613
- #########################################{budget_items = indateruns.find_all{|r| r.budget == budget}
614
- ########################################alternate_accounts = budget_items.map{|r| r.account}.uniq - [budget_info[:account]]
615
- ########################################alternate_accounts.map{|acc|
616
- ########################################alternate_items = budget_items.find_all{|r| r.account == acc}
617
- ########################################total = alternate_items.map{|r| r.debit - r.credit}.sum
618
- ########################################"#{acc} & #{total} \\\\"
619
- ########################################}.join("\n\n")
620
- ########################################}
621
-
622
- ########################################\\\\
623
- ########################################\\hline
624
- ########################################\\end{tabulary}
625
- ########################################\\normalsize
626
- ########################################\\vspace{1em}\n\n
627
-
628
- #########################################{ alternate_accounts.map{|acc|
629
- ########################################alternate_items = budget_items.find_all{|r| r.account == acc}
630
- ########################################alternate_items.pieces((alternate_items.size.to_f/50.to_f).ceil).map{|piece|
631
- ########################################"\\footnotesize\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 3 }}
632
- #########################################{budget}: & #{budget_info[:account]} & owes & #{acc} &&&&\\\\
633
- ########################################\\hline
634
-
635
- ########################################\\Tstrut
636
-
637
- #########################################{piece.map{|r|
638
- ########################################([:id] + rcp.component_results - [:sc]).map{|res|
639
- ########################################r.send(res).to_s.latex_escape
640
- #########################################rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
641
- ########################################}.join(" & ")
642
- ########################################}.join("\\\\\n")
643
- ########################################}
644
- ########################################\\end{tabulary}\\normalsize"}.join("\n\n")
645
- ########################################}.join("\n\n")}
646
- ########################################"
647
- #}.join("\n\n")
648
- #}
649
-
650
-
651
-
652
- #\\section{Budget and Transfer Breakdown}
653
- ##{(TRANSFERS + actual_budgets).map{|budget, budget_info|
654
- #dates, expenditures, budget_items = budget_expenditure(runner, budget, budget_info, today - numdays, today: today)
655
- #pp budget, budget_items.map{|items| items.map{|i| i.date.to_s}}
656
- #"\\subsection{#{budget}}" +
657
- ########################budget_items.zip(dates, expenditures).map{|items, date, expenditure|
658
- ########################if items.size > 0
659
- ########################"
660
- ########################\\footnotesize
661
- ########################\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 2 }}
662
- ########################%\\hline
663
- ########################& #{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
664
- ########################\\hline
665
- ########################\\Tstrut
666
- #########################{items.map{|r|
667
- ########################([:id] + rcp.component_results - [:sc, :balance]).map{|res|
668
- ########################r.send(res).to_s.latex_escape
669
- ########################}.join(" & ")
670
- ########################}.join("\\\\\n")
671
- ########################}
672
- ########################\\\\
673
- ########################\\hline
674
- ########################\\end{tabulary}
675
- ########################\\normalsize
676
- ########################\\vspace{1em}\n\n"
677
- ########################else
678
- ########################""
679
- ########################end
680
- ########################}.join("\n\n")
681
- #}.join("\n\n")
682
- #}
683
-
684
-
685
-
686
- #\\section{Recent Transactions}
687
- ##{accounts.map{|acc|
688
- #"\\subsection{#{acc}}
689
- #\\footnotesize
690
- ##{all = runs.find_all{|r| r.account == acc and r.days_ago < numdays}.sort_by{|r| [r.date, r.id]}.reverse
691
- #ep ['acc', acc, 'ids', all.map{|r| r.id}, 'size', all.size]
692
- ########all.pieces((all.size.to_f/50.to_f).ceil).map{|piece|
693
- ########"\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 3 + "l"}}
694
- #########{piece.map{|r|
695
- ########([:id] + rcp.component_results - [:sc] + [:budget]).map{|res| r.send(res).to_s.latex_escape
696
- #########rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
697
- ########}.join(" & ")
698
- ########}.join("\\\\\n")}
699
- ########\\end{tabulary}"}.join("\n\n")}"
700
- #}.join("\n\n")}
701
- #\\end{document}
702
- #EOF
703
-
704
-
705
- #end
706
- #system "latex report.tex && latex report.tex"
707
- #end
708
- #require 'treasurer'
709
- #require 'local_customisations.rb'
710
- #include Treasurer::LocalCustomisations
711
260
 
712
261
  end # class Budget
713
262
  end #class CodeRunner
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: budgetcrmod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.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-09 00:00:00.000000000 Z
11
+ date: 2018-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coderunner
@@ -96,6 +96,7 @@ files:
96
96
  - VERSION
97
97
  - budgetcrmod.gemspec
98
98
  - lib/budgetcrmod.rb
99
+ - lib/budgetcrmod/account_choices.rb
99
100
  - lib/budgetcrmod/budget.rb
100
101
  - lib/budgetcrmod/defaults_files/budget_defaults.rb
101
102
  - test/helper.rb