budgetcrmod 0.2.2 → 0.2.3

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: 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