budgetcrmod 0.2.3 → 0.3.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 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