budgetcrmod 0.2.2 → 0.2.3

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: 5eb9c1cfe45e04c7b0b7b3900a5f306b3af5821b
4
- data.tar.gz: f860ba5fd4e5b1bd729d3b25be7a1c8eed176098
3
+ metadata.gz: 690a66a464147f4818488e427d9556a46a2f5352
4
+ data.tar.gz: 90406cb37a7885adf871b362c44e52049747fc66
5
5
  SHA512:
6
- metadata.gz: 19bea47404cf1e2bd70ca3b65a9aa0bcce84bf83660dde3f89a8b731457536ce4588b70791fb0b0f2b015a293358c759e5dcfb71c97dfdb1a9a60f2753e7f84e
7
- data.tar.gz: dfaaccb2045895cd5f4e35f74fbd12da3544c11af9d79eb5ff314797b7214105a5a1b1d596dc8bb5d791ee19f4041a5b7316e3c3723a2e1961fc552cea439bb3
6
+ metadata.gz: c12a9b4c4a0b764f3f3c003970dcb6a6bcb358fcfdb4d5c6da95c96aef192b00fe8539c259463ef9e74df93d50bcac6759ed0f85a8a25f8a29ae5a57cd74ddd7
7
+ data.tar.gz: 5c0b29941d7ae468b5eb6ccf51dcc89baeb8e6e0c454c4c1608a4e55144ffd635294c2c8f73ff7b6d95700eb9604e2c9112dd0fd462858226c109833d7af81ba
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
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.2 ruby lib
5
+ # stub: budgetcrmod 0.2.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "budgetcrmod".freeze
9
- s.version = "0.2.2"
9
+ s.version = "0.2.3"
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-03-07"
14
+ s.date = "2018-04-09"
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 = [
@@ -1,86 +1,78 @@
1
- class Float
2
- def to_str
3
- sprintf("%.2f", self)
4
- end
5
- def to_s
6
- sprintf("%.2f", self)
7
- end
8
- end
9
1
  require 'date'
10
2
  class String
11
- def latex_escape
12
- self.gsub(/(?<!\\)([$%_&^])/, '\\\\\1')
13
- end
14
- #alias :old_to_f :to_f
15
- #def to_f
16
- #gsub(/,/, '').old_to_f
17
- #end
3
+ def latex_escape
4
+ self.gsub(/(?<!\\)([$%_&^])/, '\\\\\1')
5
+ end
6
+ #alias :old_to_f :to_f
7
+ #def to_f
8
+ #gsub(/,/, '').old_to_f
9
+ #end
18
10
  end
19
11
 
20
12
  class Date
21
- attr_accessor :sortsign
22
- def -@
23
- #@sortsign ? @sortsign *= -1 : (@sortsign=-1)
24
- newdate = dup
25
- newdate.sortsign = -1
26
- newdate
27
- end
28
- alias :oldcompare :<=>
13
+ attr_accessor :sortsign
14
+ def -@
15
+ #@sortsign ? @sortsign *= -1 : (@sortsign=-1)
16
+ newdate = dup
17
+ newdate.sortsign = -1
18
+ newdate
19
+ end
20
+ alias :oldcompare :<=>
29
21
  def <=>(other)
30
- oldres = oldcompare(other)
31
- oldres *= -1 if @sortsign==-1 and other.sortsign == -1
32
- oldres
33
- end
22
+ oldres = oldcompare(other)
23
+ oldres *= -1 if @sortsign==-1 and other.sortsign == -1
24
+ oldres
25
+ end
34
26
  end
35
27
 
36
28
  require 'date'
37
29
  class CodeRunner
38
- class Budget < Run
39
- @code_long = "Budget Calculator"
40
- @uses_mpi = false
41
- @naming_pars = []
42
- @run_info = []
43
- @variables = [:data_file, :account]
44
- @excluded_sub_folders = []
45
- @modlet_required = false
46
- @defaults_file_name = "budget_defaults.rb"
47
-
48
- @code_module_folder = folder = File.dirname(File.expand_path(__FILE__)) # i.e. the directory this file is in
49
-
50
- # ["05/07/2010",
51
- # "DEB",
52
- # "308760",
53
- # "25387560",
54
- # "ANGELSCD 0655",
55
- # "",
56
- # "11.50",
57
- # "4506.80"]
58
- #
59
- @component_results = [:date, :type, :sc, :ac, :description, :deposit, :withdrawal, :balance]
60
- @results = [:date_i, :data, :data_line] + @component_results
61
- def generate_input_file
62
- FileUtils.cp @data_file.sub(/~/, ENV['HOME']), @directory + '/data.cvs'
63
- end
64
- def debit
65
- case @account_type
66
- when :Asset, :Expense
67
- deposit
68
- else
69
- withdrawal
70
- end
71
- end
72
- def credit
73
- case @account_type
74
- when :Asset, :Expense
75
- withdrawal
76
- else
77
- deposit
78
- end
79
- end
80
- DOUBLE_STRING=/"(?:\\\\|\\"|[^"\\]|\\[^"\\])*"/
81
- def process_directory_code_specific
82
- @status=:Complete
83
- data = File.read('data.cvs')
30
+ class Budget < Run
31
+ @code_long = "Budget Calculator"
32
+ @uses_mpi = false
33
+ @naming_pars = []
34
+ @run_info = []
35
+ @variables = [:data_file, :account]
36
+ @excluded_sub_folders = []
37
+ @modlet_required = false
38
+ @defaults_file_name = "budget_defaults.rb"
39
+
40
+ @code_module_folder = File.dirname(File.expand_path(__FILE__)) # i.e. the directory this file is in
41
+
42
+ # ["05/07/2010",
43
+ # "DEB",
44
+ # "308760",
45
+ # "25387560",
46
+ # "ANGELSCD 0655",
47
+ # "",
48
+ # "11.50",
49
+ # "4506.80"]
50
+ #
51
+ @component_results = [:date, :type, :sc, :ac, :description, :deposit, :withdrawal, :balance]
52
+ @results = [:date_i, :data, :data_line, :dataset] + @component_results
53
+ def generate_input_file
54
+ FileUtils.cp @data_file.sub(/~/, ENV['HOME']), @directory + '/data.cvs'
55
+ end
56
+ def debit
57
+ case @account_type
58
+ when :Asset, :Expense
59
+ deposit
60
+ else
61
+ withdrawal
62
+ end
63
+ end
64
+ def credit
65
+ case @account_type
66
+ when :Asset, :Expense
67
+ withdrawal
68
+ else
69
+ deposit
70
+ end
71
+ end
72
+ DOUBLE_STRING=/"(?:\\\\|\\"|[^"\\]|\\[^"\\])*"/
73
+ def process_directory_code_specific
74
+ @status=:Complete
75
+ data = File.read('data.cvs')
84
76
  #p ['encoding', data.encoding]
85
77
  #data.encode(Encoding::UTF_8)
86
78
  tries = 1
@@ -98,128 +90,132 @@ class CodeRunner
98
90
  retry
99
91
  end
100
92
  end
101
- if data[0] =~ /^\d{2} \w{3} \d\d,/ # BarclayCard format
102
- data.unshift 'date,description,type,user,expensetype,withdrawal,withdrawal'
103
- end
93
+ if data[0] =~ /^\d{2} \w{3} \d\d,/ # BarclayCard format
94
+ data.unshift 'date,description,type,user,expensetype,withdrawal,withdrawal'
95
+ end
104
96
 
105
- @first_line_string = data[0].dup
106
- data = data.map do |line|
107
- matches = line.scan(Regexp.new("((?:#{DOUBLE_STRING}|[^,])*)(?:,|$)"))
97
+ @first_line_string = data[0].dup
98
+ data = data.map do |line|
99
+ matches = line.scan(Regexp.new("((?:#{DOUBLE_STRING}|[^,])*)(?:,|$)"))
108
100
  pp matches
109
- matches.flatten
110
- end
111
- #pp data
112
- @data = data
113
- @first_line = @data.shift.join(',')
101
+ matches.flatten
102
+ end
103
+ #pp data
104
+ @data = data
105
+ @first_line = @data.shift.join(',')
114
106
  generate_component_runs
115
- end
116
- #def reversed?
117
- #case account_type(@account)
118
- #when :Asset
119
- #@first_line =~ /Debit.*Credit/
120
- #end
121
- #end
122
- def print_out_line
123
- if @is_component
124
- sprintf("%4d. %10s %10s %3s %-40s %8s %8s %8s %8s %8s", id, account, *rcp.component_results.find_all{|r| r!=:ac and r!=:sc}.map{|res| send(res).to_s.gsub(/\s+/, ' ')}, external_account, sub_account)
125
- else
126
- #pr = component_runs.sort_by{|r| r.id}
127
- "#{sprintf("%3d", @id)}. #{sprintf("%-20s", @account)} Start: #{start_date} End: #{end_date} Final Balance: #{final_balance} "
128
- end
129
- end
130
- def date_sorted_component
131
- @date_sorted_component ||= component_runs.sort_by{|r| r.id}
132
- end
133
- def end_date
134
- date_sorted_component[-1].date rescue nil
135
- end
136
- def start_date
137
- date_sorted_component[0].date rescue nil
138
- end
139
- def final_balance
140
- date_sorted_component[-1].balance rescue nil
141
- end
142
- def parameter_transition(run)
143
- end
144
- def parameter_string
145
- ""
146
- end
107
+ end
108
+ #def reversed?
109
+ #case account_type(@account)
110
+ #when :Asset
111
+ #@first_line =~ /Debit.*Credit/
112
+ #end
113
+ #end
114
+ def print_out_line
115
+ if @is_component
116
+ sprintf("%4d. %10s %10s %3s %-40s %8s %8s %8s %8s %8s", id, account, *rcp.component_results.find_all{|r| r!=:ac and r!=:sc}.map{|res| send(res).to_s.gsub(/\s+/, ' ')}, external_account, sub_account)
117
+ else
118
+ #pr = component_runs.sort_by{|r| r.id}
119
+ "#{sprintf("%3d", @id)}. #{sprintf("%-20s", @account)} Start: #{start_date} End: #{end_date} Final Balance: #{final_balance} "
120
+ end
121
+ end
122
+ def date_sorted_component
123
+ @date_sorted_component ||= component_runs.sort_by{|r| r.id}
124
+ end
125
+ def end_date
126
+ date_sorted_component[-1].date rescue nil
127
+ end
128
+ def start_date
129
+ date_sorted_component[0].date rescue nil
130
+ end
131
+ def final_balance
132
+ date_sorted_component[-1].balance rescue nil
133
+ end
134
+ def parameter_transition(run)
135
+ end
136
+ def parameter_string
137
+ ""
138
+ end
147
139
  #def external_account
148
- #name = super
149
- #if ACCOUNT_INFO[name] and ACCOUNT_INFO[name][:currencies].size > 2
140
+ #name = super
141
+ #if ACCOUNT_INFO[name] and ACCOUNT_INFO[name][:currencies].size > 2
150
142
  #end
151
143
  #def sub_account
152
144
  #end
153
145
 
154
- def sub_account
155
- cache[:sub_account] ||= super
156
- end
157
- def external_account
158
- cache[:external_account] ||= super
159
- end
160
-
161
- #def external_account
162
- #(budget.to_s + '_' + sub_account.to_s).to_sym
163
- #end
164
-
165
- def csv_data_fields
166
- case @first_line_string
167
- when /Date,Type,Sort Code,Account Number,Description,In,Out,Balance/ # Old Lloyds Bank Format
168
- [:date, :type, :sc, :ac, :description, :deposit, :withdrawal, :balance]
169
- when /Transaction Date,Transaction Type,Sort Code,Account Number,Transaction Description,Debit Amount,Credit Amount,Balance/ # 2013 Lloyds Bank Format, NB they are using debit and credit as if the account is an equity account (when of course a bank account is really an asset)
170
- [:date, :type, :sc, :ac, :description, :withdrawal, :deposit, :balance]
171
- when /Date,Date entered,Reference,Description,Amount/ # Lloyds Credit Card statement
172
- [:date, :dummy, :dummy, :description, :withdrawal]
173
- when /date,description,type,user,expensetype,withdrawal,withdrawal/
174
- [:date,:description,:type,:dummy,:dummy, :withdrawal, :withdrawal]
146
+ def sub_account
147
+ cache[:sub_account] ||= super
148
+ end
149
+ def external_account
150
+ cache[:external_account] ||= super
151
+ end
152
+
153
+ #def external_account
154
+ #(budget.to_s + '_' + sub_account.to_s).to_sym
155
+ #end
156
+
157
+ def csv_data_fields
158
+ case @first_line_string
159
+ when /Date,Type,Sort Code,Account Number,Description,In,Out,Balance/ # Old Lloyds Bank Format
160
+ [:date, :type, :sc, :ac, :description, :deposit, :withdrawal, :balance]
161
+ when /Transaction Date,Transaction Type,Sort Code,Account Number,Transaction Description,Debit Amount,Credit Amount,Balance/ # 2013 Lloyds Bank Format, NB they are using debit and credit as if the account is an equity account (when of course a bank account is really an asset)
162
+ [:date, :type, :sc, :ac, :description, :withdrawal, :deposit, :balance]
163
+ when /Date,Date entered,Reference,Description,Amount/ # Lloyds Credit Card statement
164
+ [:date, :dummy, :dummy, :description, :withdrawal]
165
+ when /date,description,type,user,expensetype,withdrawal,withdrawal/
166
+ [:date,:description,:type,:dummy,:dummy, :withdrawal, :withdrawal]
175
167
  when /Datum,Transaktion,Kategori,Belopp,Saldo/ # Nordea.se privat, Belopp is positive when the asset increases
176
168
  [:date,:description,:dummy,:deposit,:balance]
177
169
  when /Bokföringsdatum,Transaktionsreferens,Mottagare,Belopp,Valuta/ # Forex.se privat, Belopp is positive when the asset increases
178
170
  [:date,:description,:dummy,:deposit,:dummy]
179
171
  when /Datum,Text,Belopp/ #Ecster Credit Card
180
- [:date,:description,:withdrawal]
172
+ [:date,:description,:deposit]
181
173
  when /Effective Date,Entered Date,Transaction Description,Amount/ #QudosBank, the first field is blank
182
174
  [:dummy,:date,:description,:deposit]
183
- end
184
- end
175
+ when /Date,Amount,Currency,Description,"Payment Reference","Running Balance","Exchange Rate","Payer Name","Payee Name","Payee Account Number",Merchant/ #TransferWise
176
+ [:date,:deposit,:dummy,:description,:dummy,:balance,:dummy,:dummy,:dummy,:dummy,:dummy]
177
+ end
178
+ end
185
179
 
186
- #def withdrawn
187
- #@withdrawn||0.0
188
- #end
180
+ #def withdrawn
181
+ #@withdrawn||0.0
182
+ #end
189
183
 
190
- def has_balance?
191
- @has_balance ||= csv_data_fields.include? :balance
192
- end
184
+ def has_balance?
185
+ @has_balance ||= csv_data_fields.include? :balance
186
+ end
193
187
 
194
- attr_accessor :dummy
188
+ attr_accessor :dummy
195
189
 
196
190
 
197
- def set_zeroes
198
- @withdrawal||=0.0
199
- @deposit||=0.0
200
- end
201
- def generate_component_runs
191
+ def set_zeroes
192
+ @withdrawal||=0.0
193
+ @deposit||=0.0
194
+ end
195
+ def generate_component_runs
202
196
  #puts Kernel.caller
203
197
  #p ['generate_component_runs', @component_runs.class, (@component_runs.size rescue nil), @runner.component_run_list.size, @directory]
204
198
  return if @component_runs and @component_runs.size > 0
205
- @runner.cache[:data] ||= []
206
- #reslts = rcp.component_results
207
- #if reversed?
208
- #reslts[5] = :withdrawal
209
- #reslts[6] = :deposit
210
- #end
211
- @data.each do |dataset|
212
- #next if @runner.cache[:data].include? dataset and Date.parse(dataset[0]) > Date.parse("1/1/2013")
213
- next if @runner.component_run_list.map{|k,v| v.instance_variable_get(:@dataset)}.include? dataset # and Date.parse(dataset[0]) > Date.parse("1/1/2013")
199
+ @runner.cache[:data] ||= []
200
+ #reslts = rcp.component_results
201
+ #if reversed?
202
+ #reslts[5] = :withdrawal
203
+ #reslts[6] = :deposit
204
+ #end
205
+ @data.each do |dataset|
206
+ #next if @runner.cache[:data].include? dataset and Date.parse(dataset[0]) > Date.parse("1/1/2013")
207
+ #next if @runner.component_run_list.map{|k,v| v.instance_variable_get(:@dataset)}.include? dataset # and Date.parse(dataset[0]) > Date.parse("1/1/2013")
208
+ next if @runner.component_run_list.find{|k,v| v.dataset == dataset} # and Date.parse(dataset[0]) > Date.parse("1/1/2013")
214
209
  next if @first_line_string =~ /^Datum/ and dataset[1] =~ /Reservation/
215
- component = create_component
210
+ component = create_component
211
+ component.set_zeroes
216
212
  ep 'Generating Component', @component_runs.size
217
- reslts = csv_data_fields
218
- reslts.each_with_index do |res,index|
219
- value = dataset[index]
220
- #ep value
221
- value = Date.parse value if res == :date
222
- if [:deposit, :withdrawal, :balance].include? res
213
+ reslts = csv_data_fields
214
+ reslts.each_with_index do |res,index|
215
+ value = dataset[index]
216
+ #ep value
217
+ value = Date.parse value if res == :date
218
+ if [:deposit, :withdrawal, :balance].include? res
223
219
  case @first_line_string
224
220
  when /^Datum/i # we are dealing with European numbers
225
221
  value = value.gsub(/[." ]/, '')
@@ -227,494 +223,493 @@ class CodeRunner
227
223
  else
228
224
  value = value.gsub(/[",]/, '')
229
225
  end
230
- next unless value =~ /\d/
231
- value = value.to_f
232
- end
233
- component.instance_variable_set(:@dataset, dataset)
234
- component.set(res, value)
235
- component.set_zeroes
236
- component.set(:data_line, reslts.map{|r| component.send(r).to_s}.join(','))
237
- end
226
+ next unless value =~ /\d/
227
+ value = value.to_f
228
+ end
229
+ component.set(res, value)
230
+ end
231
+ component.set(:data_line, reslts.map{|r| component.send(r).to_s}.join(','))
232
+ component.set(:dataset, dataset)
238
233
  component.date_i = component.date.to_datetime.to_time.to_i
239
234
  if component.deposit < 0.0 and component.withdrawal == 0.0
240
235
  component.withdrawal = -component.deposit
241
236
  component.deposit = 0.0
242
237
  end
243
- @runner.cache[:data].push dataset
238
+ @runner.cache[:data].push dataset
244
239
  component.external_account; component.sub_account # Triggers interactive account choices
245
- #component.account = @account
246
- end
247
- end
248
- def days_ago(today = Date.today)
249
- #ep ['today', today, date]
250
- # sprintf("%04d%02d%02d", date.year, date.month, date.day).to_i
251
- #cache[:days_ago] ||= {}
252
- #cache[:days_ago][today.to_s] ||=
253
- - ((date.to_datetime.to_time.to_i - today.to_datetime.to_time.to_i) / 24 / 3600).to_i
254
- end
255
- def idate
256
- date.to_datetime.to_time.to_i
257
- end
258
- def ds
259
- description
260
- end
261
-
262
-
263
- #def self.sum_future(future_items, end_date, options={})
264
- #sum = future_items.inject(0) do |sum, (name, item)|
265
- #item = [item] unless item.kind_of? Array
266
- #value = item.inject(0) do |value,info|
267
- #value += info[:size] unless (options[:today]||Date.today > info[:date]) or (info[:date] > end_date) # add unless we have already passed that date
268
- #value
269
- #end
270
- #rcp.excluding.include?(name) ? sum : sum + value
271
- #end
272
- #sum
273
- #end
274
-
275
- #def self.budget_expenditure(runner, budget, budget_info, start_date, options={})
276
- #dates = []
277
- #expenditures = []
278
- #budget_items = []
279
- #date = budget_info[:end]||options[:today]||Date.today
280
- #start_date = [(budget_info[:start]||start_date), start_date].max
281
- #expenditure = 0
282
- #items_temp = []
283
- #items = runner.component_run_list.values.find_all{|r| r.budget == budget and r.in_date(budget_info)}
284
- ##ep ['items', items]
285
- ##ep ['budget', budget]
286
- #counter = 0
287
- #if not budget_info[:period]
288
- #dates.push date
289
- #budget_items.push items
290
- #expenditures.push (items.map{|r| r.debit - r.credit}+[0]).sum
291
- #else
292
-
293
- #case budget_info[:period][1]
294
- #when :month
295
- #while date > start_date
296
- #items_temp += items.find_all{|r| r.date == date}
297
- #if date.mday == (budget_info[:monthday] or 1)
298
- #counter +=1
299
- #if counter % budget_info[:period][0] == 0
300
- #expenditure = (items_temp.map{|r| r.debit - r.credit}+[0]).sum
301
- #dates.push date
302
- #expenditures.push expenditure
303
- #budget_items.push items_temp
304
- #items_temp = []
305
- #expenditure = 0
306
- #end
307
- #end
308
- #date-=1
309
- #end
310
- #when :day
311
- #while date > start_date
312
- #items_temp += items.find_all{|r| r.date == date}
313
- ##expenditure += (budget_items[-1].map{|r| r.debit}+[0]).sum
314
- #counter +=1
315
- #if counter % budget_info[:period][0] == 0
316
- #expenditure = (items_temp.map{|r| r.debit - r.credit}+[0]).sum
317
- #dates.push date
318
- #expenditures.push expenditure
319
- #budget_items.push items_temp
320
- #items_temp = []
321
- #expenditure = 0
322
- #end
323
- #date-=1
324
- #end
325
- #end
326
- #end
327
-
328
- #[dates, expenditures, budget_items]
329
-
330
- #end
331
-
332
- #def self.sum_regular(regular_items, end_date, options={})
333
- #today = options[:today]||Date.today
334
- #sum = regular_items.inject(0) do |sum, (name, item)|
335
- #item = [item] unless item.kind_of? Array
336
- ## ep item
337
- #value = item.inject(0) do |value,info|
338
- #finish = (info[:end] and info[:end] < end_date) ? info[:end] : end_date
339
- ##today = (Time.now.to_i / (24.0*3600.0)).round
340
-
341
- #nunits = 0
342
- #counter = info[:period][0] == 1 ? 0 : nil
343
- #####################unless counter
344
- #####################date = today
345
- #####################counter = 0
346
- #####################case info[:period][1]
347
- #####################when :month
348
- #####################while date >= (info[:start] or Date.today)
349
- #####################counter +=1 if date.mday == (info[:monthday] or 1)
350
- #####################date -= 1
351
- #####################end
352
- #####################when :year
353
- #####################while date >= (info[:start] or Date.today)
354
- #####################counter +=1 if date.yday == (info[:yearday] or 1)
355
- #####################date -= 1
356
- #####################end
357
- #####################when :day
358
- #####################while date > (info[:start] or Date.today)
359
- #####################counter +=1
360
- #####################date -= 1
361
- #####################end
362
- #####################end
363
- #####################end
364
- #date = today
365
- #########################case info[:period][1]
366
- #########################when :month
367
- ##########################p date, info
368
- #########################while date <= finish
369
- #########################if date.mday == (info[:monthday] or 1)
370
- #########################nunits += 1 if counter % info[:period][0] == 0
371
- #########################counter +=1
372
- #########################end
373
- #########################date += 1
374
- #########################end
375
- #########################when :year
376
- #########################while date <= finish
377
- #########################if date.yday == (info[:yearday] or 1)
378
- #########################nunits += 1 if counter % info[:period][0] == 0
379
- #########################counter +=1
380
- #########################end
381
- #########################date += 1
382
- #########################end
383
- #########################when :day
384
- #########################while date <= finish
385
- #########################nunits += 1 if counter % info[:period][0] == 0
386
- #########################counter +=1
387
- #########################date += 1
388
- #########################end
389
- #########################end
390
-
391
-
392
-
393
-
394
-
395
- ##nyears = (finish.year - today.year)
396
- ##nmonths = nyears * 12 + (finish.month - today.month)
397
- ##(puts "Number of Months: #{nmonths}"; @pnmonths=true) unless @pnmonths
398
- ##ndays = nyears * 12 + (finish.yday - today.yday)
399
- ##number = case info[:period][1]
400
- ##when :month
401
- ##(nmonths / info[:period][0]).ceil
402
- ##when :day
403
- ##(ndays / info[:period][0]).ceil
404
- ##end
405
- ##value + number * info[:size]
406
- ##eputs "Regular Expenditure Item: #{sprintf("%10s", name)} -- #{nunits} payments, total #{nunits * info[:size]}"
407
- #value + nunits * info[:size]
408
-
409
- #end
410
- #(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value
411
- #end
412
- #sum
413
- #end
414
- def self.predictable_component_ids(runner)
415
- #runner.instance_variable_set(:@component_run_list, {})
416
- #runner.instance_variable_set(:@component_ids, [])
417
- #runner.instance_variable_set(:@component_id, -1)
418
- #runner.run_list.each{|r| r.instance_variable_set(:@component_runs, [])}
419
- #runner.run_list.values.sort_by{|r| r.id}.each{|r| r.generate_component_runs}
420
- #runner.save_large_cache
421
- end
422
- def self.kit_time_format_x(kit)
423
- kit.gp.timefmt = %["%s"]
424
- kit.data.each{|dk| dk.gp.using = "1:2"}
425
- kit.gp.xdata = "time"
426
- kit.gp.format = %[x "%d %B %Y"]
427
- kit.gp.format = %[x "%b %Y"]
428
- kit.gp.mxtics = "30"
429
- kit.gp.xtics = "rotate by 340 offset 0,-0.5 #{24*3600*14}"
430
- kit.gp.xtics = "rotate by 340 offset 0,-0.5 2629746"
431
- end
432
-
433
- def self.print_budget(options={})
434
- @excluding = (options[:excluding] or [])
435
- runner = CodeRunner.fetch_runner(Y: Dir.pwd)
436
- puts "------------------------------"
437
- puts " Budget Report"
438
- puts "------------------------------"
439
- balance = runner.component_run_list.values.sort_by{|r| [r.date, r.id]}.map{|r| r.balance}[-1]
440
- puts "Balance: #{balance}"
441
- end_date = Date.parse("01/10/2011")
442
- puts "Regular Expenditure: #{total_regular = sum_regular(REGULAR_EXPENDITURE, end_date)}"
443
- puts "Future Expenditure: #{total_future = sum_future(FUTURE_EXPENDITURE, end_date)}"
444
- puts "Total Expenditure: #{total_expenditure = total_future + total_regular}"
445
- puts "Total Income: #{total_incoming = sum_future(FUTURE_INCOME, end_date)}"
446
- total = balance + total_incoming - total_expenditure
447
- puts "Weekly Budget: #{total / ((end_date.to_datetime.to_time.to_i - Time.now.to_i) / 3600 / 24 /7)}"
448
- end
449
-
450
- #def self.budgets_with_averages(runner, budgets, start_date, options={})
451
- #projected_budgets = budgets.dup
452
- #projected_budgets.each{|key,v| projected_budgets[key]=projected_budgets[key].dup}
453
- #projected_budgets.each do |budget, budget_info|
454
- ##budget_info = budgets[budget]
455
- #dates, expenditures, items = budget_expenditure(runner, budget, budget_info, start_date, today: options[:today])
456
- #budget_info[:size] = expenditures.mean rescue 0.0
457
- #end
458
- #projected_budgets
459
- #end
460
-
461
- #def self.latex_budget_transfers(runner, budgets, options)
462
- #numdays = options[:days]
463
- #today = options[:today]||Date.today
464
- #"#{budgets.map{|budget, budget_info|
465
- #dates, expenditures, items = budget_expenditure(runner, budget, budget_info, today - numdays, today: options[:today])
466
- ##ep ['budget', budget, dates, expenditures]
467
- #kit = GraphKit.quick_create([dates.map{|d| d.to_time.to_i}, expenditures])
468
- #kit.data.each{|dk| dk.gp.with="boxes"}
469
- #kit.gp.style = "fill solid"
470
- #kit.xlabel = nil
471
- #kit.ylabel = "Expenditure"
472
- #unless options[:transfers]
473
- #kits = budgets_with_averages(runner, {budget => budget_info}, today - numdays, today: today).map{|budget, budget_info|
474
- ##ep 'Budget is ', budget
475
- #kit2 = GraphKit.quick_create([
476
- #[dates[0], dates[-1]].map{|d| d.to_time.to_i},
477
- #[budget_info[:size], budget_info[:size]]
478
- #])
479
- #kit2.data[0].gp.with = 'lp lw 4'
480
- #kit2
481
- #}
482
- ##$debug_gnuplot = true
483
- ##kits.sum.gnuplot
484
- #kit += kits.sum
485
-
486
- #else
487
- #kit.data[0].y.data.map!{|expen| expen*-1.0}
488
- #end
489
- #kit.title = "#{budget} Expenditure with average (Total = #{kit.data[0].y.data.sum})"
490
- #kit_time_format_x(kit)
491
- ##kit.gnuplot
492
- #kit.gnuplot_write("#{budget}.eps")
493
- #"\\begin{center}\\includegraphics[width=4.0in]{#{budget}.eps}\\vspace{1em}\\end{center}"
494
- #}.join("\n\n")
495
- #}"
496
- #end
497
-
498
- #def self.latex_report(options={})
499
- #runner = CodeRunner.fetch_runner(Y: Dir.pwd, h: :component)
500
- #numdays = options[:days]
501
- #today = options[:today] || Date.today
502
- ## Delete budgets that contain no items
503
- #actual_budgets = BUDGETS.dup
504
- #BUDGETS.keys.each do |budget|
505
- #actual_budgets.delete(budget) if budget_expenditure(runner, budget, BUDGETS[budget], today - numdays, today: today)[0].size == 0
506
- #end
507
- ##predictable_component_ids(runner)
508
- #days_ahead = options[:days_ahead]
509
- #runs = runner.component_run_list.values
510
- #indateruns = runs.find_all{|r| r.days_ago < numdays}
511
- #accounts = runs.map{|r| r.account}.uniq
512
- #ep 'Accounts', accounts
513
- #projected_budgets = Hash[actual_budgets.dup.find_all{|k,v| v[:discretionary]}]
514
- #projected_budgets = budgets_with_averages(runner,projected_budgets, today - numdays, today: today)
515
- ##projected_budgets.each{|key,v| projected_budgets[key]=projected_budgets[key].dup}
516
- ##projected_budgets.each do |budget, budget_info|
517
- ###budget_info = budgets[budget]
518
- ##dates, expenditures, items = budget_expenditure(runner, budget, budget_info, today - numdays)
519
- ##budget_info[:size] = expenditures.mean
520
- ##end
521
- #ep 'projected_budgets', projected_budgets
522
- #File.open('report.tex', 'w') do |file|
523
- #file.puts <<EOF
524
- #\\documentclass{article}
525
- #\\usepackage[cm]{fullpage}
526
- #\\usepackage{tabulary}
527
- #\\usepackage{graphicx}
528
- #%\\usepackage{hyperlink}
529
- #\\newcommand\\Tstrut{\\rule{0pt}{2.8ex}}
530
- #\\begin{document}
531
- #\\title{#{numdays}-day Budget Report}
532
- #\\maketitle
533
- #\\tableofcontents
534
-
535
- #\\section{Summary of Accounts}
536
- ##{accounts.map{|acc|
537
- #"\\subsection{#{acc}}
538
- #\\begin{tabulary}{0.8\\textwidth}{ r l}
539
- ###Balance & #{runs.find_all{|r| r.account==acc}.sort_by{|r|
540
- ###r.date
541
- ###}[-1].balance} \\\\
542
- #####Expenditure & #{runs.find_all{|r| r.account==acc &&
543
- #####r.days_ago < numdays
544
- #####}.map{|r|
545
- #####r.debit
546
- #####}.sum} \\\\
547
- ###Income & #{runs.find_all{|r| r.account==acc &&
548
- ###r.days_ago < numdays
549
- ###}.map{|r| r.credit}.sum} \\\\
550
- #\\end{tabulary}"}.join("\n\n")
551
- #}
552
-
553
- #\\section{Graphs of Recent Balances}
554
- ##{accounts.map{|acc|
555
- #balance = runs.find_all{|r| r.account==acc}.sort_by{|r| r.date }[-1].balance
556
- #accshort = acc.gsub(/\s/, '')
557
- #kit = runner.graphkit(['date.to_time.to_i', 'balance'], {conditions: "account == #{acc.inspect} and days_ago < #{numdays}", sort: 'date'})
558
- #futuredates = (today..today+days_ahead).to_a
559
- ##p ["Regtrans", REGULAR_TRANSFERS.values_at(*REGULAR_TRANSFERS.keys.find_all{|from,to| to == acc})]
560
-
561
- #budgets = Hash[projected_budgets.find_all{|k,v| v[:account] == acc}]
562
- #ep ['budgets', budgets]
563
- #projection = futuredates.map{|date| balance -
564
- #sum_regular(REGULAR_EXPENDITURE[acc], date, today: today) +
565
- #sum_regular(REGULAR_INCOME[acc], date, today: today) -
566
- #sum_regular(budgets, date, today: today) -
567
- #sum_future(FUTURE_EXPENDITURE[acc], date, today: today) +
568
- #sum_future(FUTURE_INCOME[acc], date, today: today) +
569
- #(REGULAR_TRANSFERS.keys.find_all{|from,to| to == acc}.map{|key|
570
- ##p [acc, 'to', "key", key]
571
- #sum_regular( REGULAR_TRANSFERS[key], date, today: today)
572
- #}.sum||0) -
573
- #(REGULAR_TRANSFERS.keys.find_all{|from,to| from == acc}.map{|key|
574
- ##p [acc, 'from',"key", key]
575
- #sum_regular( REGULAR_TRANSFERS[key], date, today: today)
576
- #}.sum||0)
577
- #}
578
- #kit2 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, projection])
579
- #kit += kit2
580
- #kit.title = "Balance for #{acc}"
581
- #kit.xlabel = %['Date' offset 0,-2]
582
- #kit.xlabel = nil
583
- #kit.ylabel = "Balance"
584
-
585
- #kit.data[0].gp.title = 'Previous'
586
- #kit.data[1].gp.title = '0 GBP Discretionary'
587
- #kit.data[1].gp.title = 'Projection'
588
- #kit.data.each{|dk| dk.gp.with = "lp"}
589
-
590
- #kit_time_format_x(kit)
591
-
592
- #(kit).gnuplot_write("#{accshort}_balance.eps", size: "4.0in,3.0in")
593
- #"\\begin{center}\\includegraphics[width=4.0in]{#{accshort}_balance.eps}\\end{center}"
594
- #}.join("\n\n")
595
- #}
596
-
597
-
598
- #\\section{Budget Expenditure}
599
- ##{latex_budget_transfers(runner,actual_budgets, options)}
600
-
601
- #\\section{Transfers}
602
- ##{latex_budget_transfers(runner, TRANSFERS, options.dup.absorb({transfers: true}))}
603
-
604
-
605
-
606
- #\\section{Budget Resolutions}
607
-
608
- #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.
609
-
610
- ##{actual_budgets.map{|budget, budget_info|
611
-
612
- ########################################"\\subsection{#{budget} }
613
- ########################################\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{r l}
614
- ########################################%\\hline
615
- ########################################Account Owed & Amount \\\\
616
- ########################################\\hline
617
- ########################################\\Tstrut
618
- #########################################{budget_items = indateruns.find_all{|r| r.budget == budget}
240
+ #component.account = @account
241
+ end
242
+ end
243
+ 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
+ - ((date.to_datetime.to_time.to_i - today.to_datetime.to_time.to_i) / 24 / 3600).to_i
249
+ end
250
+ def idate
251
+ date.to_datetime.to_time.to_i
252
+ end
253
+ def ds
254
+ description
255
+ end
256
+
257
+
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
+ 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
+ end
417
+ def self.kit_time_format_x(kit)
418
+ kit.gp.timefmt = %["%s"]
419
+ kit.data.each{|dk| dk.gp.using = "1:2"}
420
+ kit.gp.xdata = "time"
421
+ kit.gp.format = %[x "%d %B %Y"]
422
+ kit.gp.format = [%[x "%b %Y"]]
423
+ kit.gp.mxtics = "30"
424
+ kit.gp.xtics = "rotate by 340 offset 0,-0.5 #{24*3600*14}"
425
+ kit.gp.xtics = "rotate by 340 offset 0,-0.5 2629746"
426
+ end
427
+
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}
602
+
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}
619
614
  ########################################alternate_accounts = budget_items.map{|r| r.account}.uniq - [budget_info[:account]]
620
- ########################################alternate_accounts.map{|acc|
621
- ########################################alternate_items = budget_items.find_all{|r| r.account == acc}
622
- ########################################total = alternate_items.map{|r| r.debit - r.credit}.sum
623
- ########################################"#{acc} & #{total} \\\\"
624
- ########################################}.join("\n\n")
625
- ########################################}
626
-
627
- ########################################\\\\
628
- ########################################\\hline
629
- ########################################\\end{tabulary}
630
- ########################################\\normalsize
631
- ########################################\\vspace{1em}\n\n
632
-
633
- #########################################{ alternate_accounts.map{|acc|
634
- ########################################alternate_items = budget_items.find_all{|r| r.account == acc}
635
- ########################################alternate_items.pieces((alternate_items.size.to_f/50.to_f).ceil).map{|piece|
636
- ########################################"\\footnotesize\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 3 }}
637
- #########################################{budget}: & #{budget_info[:account]} & owes & #{acc} &&&&\\\\
638
- ########################################\\hline
639
-
640
- ########################################\\Tstrut
641
-
642
- #########################################{piece.map{|r|
643
- ########################################([:id] + rcp.component_results - [:sc]).map{|res|
644
- ########################################r.send(res).to_s.latex_escape
645
- #########################################rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
646
- ########################################}.join(" & ")
647
- ########################################}.join("\\\\\n")
648
- ########################################}
649
- ########################################\\end{tabulary}\\normalsize"}.join("\n\n")
650
- ########################################}.join("\n\n")}
651
- ########################################"
652
- #}.join("\n\n")
653
- #}
654
-
655
-
656
-
657
- #\\section{Budget and Transfer Breakdown}
658
- ##{(TRANSFERS + actual_budgets).map{|budget, budget_info|
659
- #dates, expenditures, budget_items = budget_expenditure(runner, budget, budget_info, today - numdays, today: today)
660
- #pp budget, budget_items.map{|items| items.map{|i| i.date.to_s}}
661
- #"\\subsection{#{budget}}" +
662
- ########################budget_items.zip(dates, expenditures).map{|items, date, expenditure|
663
- ########################if items.size > 0
664
- ########################"
665
- ########################\\footnotesize
666
- ########################\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 2 }}
667
- ########################%\\hline
668
- ########################& #{date.to_s.latex_escape} & & & Total & #{expenditure} & \\\\
669
- ########################\\hline
670
- ########################\\Tstrut
671
- #########################{items.map{|r|
672
- ########################([:id] + rcp.component_results - [:sc, :balance]).map{|res|
673
- ########################r.send(res).to_s.latex_escape
674
- ########################}.join(" & ")
675
- ########################}.join("\\\\\n")
676
- ########################}
677
- ########################\\\\
678
- ########################\\hline
679
- ########################\\end{tabulary}
680
- ########################\\normalsize
681
- ########################\\vspace{1em}\n\n"
682
- ########################else
683
- ########################""
684
- ########################end
685
- ########################}.join("\n\n")
686
- #}.join("\n\n")
687
- #}
688
-
689
-
690
-
691
- #\\section{Recent Transactions}
692
- ##{accounts.map{|acc|
693
- #"\\subsection{#{acc}}
694
- #\\footnotesize
695
- ##{all = runs.find_all{|r| r.account == acc and r.days_ago < numdays}.sort_by{|r| [r.date, r.id]}.reverse
696
- #ep ['acc', acc, 'ids', all.map{|r| r.id}, 'size', all.size]
697
- ########all.pieces((all.size.to_f/50.to_f).ceil).map{|piece|
698
- ########"\\setlength{\\parindent}{0cm}\n\n\\begin{tabulary}{0.99\\textwidth}{ #{"c " * 4 + " L " + " r " * 3 + "l"}}
699
- #########{piece.map{|r|
700
- ########([:id] + rcp.component_results - [:sc] + [:budget]).map{|res| r.send(res).to_s.latex_escape
701
- #########rcp.component_results.map{|res| r.send(res).to_s.gsub(/(.{20})/, '\1\\\\\\\\').latex_escape
702
- ########}.join(" & ")
703
- ########}.join("\\\\\n")}
704
- ########\\end{tabulary}"}.join("\n\n")}"
705
- #}.join("\n\n")}
706
- #\\end{document}
707
- #EOF
708
-
709
-
710
- #end
711
- #system "latex report.tex && latex report.tex"
712
- #end
713
- #require 'treasurer'
714
- #require 'local_customisations.rb'
715
- #include Treasurer::LocalCustomisations
716
-
717
- end # class Budget
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
+
712
+ end # class Budget
718
713
  end #class CodeRunner
719
714
 
720
715
  p Dir.pwd