treasurer 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65f2e9677098bdac4956e3562dd33f66317c52df
4
- data.tar.gz: 34118648a3281e1274a00f953887283937af5d76
3
+ metadata.gz: 931217424d6cdc37f7c8dcc760fd08bc9d5d2a3d
4
+ data.tar.gz: a48e8e11f67f770600ff93f6506a4eed78eb2c8d
5
5
  SHA512:
6
- metadata.gz: 728db7d25466eb3f09bb2e47f0336dee0ea762624b899f7cc521584c17629de66818f584afbbefbdbeb4d351110381984b8075581c4df2da725a903bae864287
7
- data.tar.gz: c1837491048206c26c5dc37104201ce2b5d232bbdb85135b0e2e3e482495d1ad52dcfbe17d2662fe860c4c0b06ac32be32c08fe9f3d8e16c90289339ff614f54
6
+ metadata.gz: abb2e38f758b4737b9084479661e274a2dcc5fb536b01327d032374991ab02da419fb33d412fdd26799da0ebe53b018bf73fe77cff90a361dfe3668384e232c1
7
+ data.tar.gz: 9abf97d6b4166d1e71b636d0486ab69369f7645644882b0d212541d19f37ae90e35cc4f8a823cdb3f39221ab9d99dd76ba9763c39b6cfa909d71082525f7edbe
data/Gemfile CHANGED
@@ -1,9 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
- # gem "activesupport", ">= 2.3.5"
4
+ gem "activesupport", ">= 5.0.0"
5
5
  gem "coderunner", ">= 0.14.16"
6
- gem "budgetcrmod", ">= 0.2.0"
6
+ gem "budgetcrmod", ">= 0.2.1"
7
7
  gem "command-line-flunky", ">= 1.0.0"
8
8
 
9
9
  # Add dependencies to develop your gem here.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.5.0
@@ -0,0 +1,307 @@
1
+ class Treasurer::Reporter
2
+ class Account
3
+ end
4
+ class SubAccount < Account
5
+ def initialize(name, reporter, runner, runs, external, options={})
6
+ @name = name
7
+ @reporter = reporter
8
+ @runner = runner
9
+ #@projected_accounts_info =Hash[projected_accounts_info.find_all{|k,v| v[:account] == name}]
10
+ @external = external
11
+ @runs = runs.find_all{|r| r.sub_account == name}
12
+ info[:external] = external if info
13
+ #ep ['sub_accounts333', name, @runs.size, runs.size]
14
+ end
15
+ end
16
+ class Account
17
+ attr_reader :name, :external, :runs, :currency
18
+ attr_accessor :projection, :average
19
+ def initialize(name, reporter, runner, runs, external, options={})
20
+ @name = name
21
+ @reporter = reporter
22
+ @runner = runner
23
+ @currency = options[:currency]
24
+ #@projected_accounts_info =Hash[projected_accounts_info.find_all{|k,v| v[:account] == name}]
25
+ @external = external
26
+ @runs = runs.find_all do |r|
27
+ #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency and @external
28
+ #@external ? r.external_account : r.account) == name}
29
+ if not @external
30
+ r.account == name
31
+ elsif info and cur = info[:currencies] and cur.size > 1
32
+ #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency
33
+ r.external_account == name and acinfo = ACCOUNT_INFO[r.account] and acinfo[:currencies] == [@currency]
34
+ else
35
+ r.external_account == name
36
+ end
37
+ end
38
+ #p ['Accountinf', name, @currency, @runs.size, runs.size]
39
+ info[:external] = external if info
40
+ end
41
+ def sub_accounts
42
+ @sub_accounts ||= @runs.map{|r| r.sub_account}.uniq.compact.map{|acc| SubAccount.new(acc, @reporter, @runner, @runs, @external, currency: @currency)}
43
+ end
44
+ def type
45
+ #account_type(name)
46
+ if ACCOUNT_INFO[name] and type = ACCOUNT_INFO[name][:type]
47
+ type
48
+ else
49
+ :Expense
50
+ end
51
+ end
52
+ def red_line(date)
53
+ if Treasurer::LocalCustomisations.instance_methods.include? :red_line
54
+ super(name, date)
55
+ else
56
+ 0.0
57
+ end
58
+ end
59
+ def report_start
60
+ @reporter.today - @reporter.days_before
61
+ end
62
+ def opening_date
63
+ (info && info[:start]) || @runs.map{|r| r.date}.min
64
+ end
65
+ def opening_balance
66
+ (info && info[:opening_balance]) || 0.0
67
+ end
68
+ def has_balance?
69
+ not @runs.find{|r| not r.has_balance?}
70
+ end
71
+ def balance(date = @reporter.today)
72
+ date_i = date.to_datetime.to_time.to_i
73
+ #if !date
74
+ #@runs.sort_by{|r| r.date}[-1].balance
75
+ if @external or not has_balance?
76
+ #p ['name is ', name, type]
77
+ #
78
+ balance = (@runs.find_all{|r| r.date <= date and r.date >= opening_date }.map{|r| money_in_sign * (r.deposit - r.withdrawal) * (@external ? -1 : 1)}.sum || 0.0)
79
+ balance += info[:opening_balance] if info[:opening_balance]
80
+ balance
81
+ #Temporary....
82
+ #0.0
83
+ else
84
+ #p ['name33 is ', name, type, @runs.size, @currency]
85
+ nearest_time = @runs.map{|r| (r.date_i - date_i).to_f.abs}.sort[0]
86
+ @runs.find_all{|r| (r.date_i - date_i).to_f.abs == nearest_time}.sort_by{|r| r.id}[-1].balance
87
+ end
88
+ end
89
+ def deposited(today, days_before, &block)
90
+ #p ['name22 is ', name, type, @runs.size]
91
+ #@runs.find_all{|r| r.days_ago(today) < days_before and (!block or yield(r)) }.map{|r| (@external and not ([:Liability, :Income].include?(type))) ? r.withdrawal : r.deposit }.sum || 0
92
+ @runs.find_all{|r| r.days_ago(today) < days_before and (!block or yield(r)) }.map{|r| (@external) ? r.withdrawal : r.deposit }.sum || 0
93
+ end
94
+ def withdrawn(today, days_before)
95
+ #@runs.find_all{|r| r.days_ago(today) < days_before }.map{|r| (@external and not ([:Liability, :Income].include?(type))) ? r.deposit : r.withdrawal }.sum || 0
96
+ @runs.find_all{|r| r.days_ago(today) < days_before }.map{|r| (@external) ? r.deposit : r.withdrawal }.sum || 0
97
+ end
98
+ def currency
99
+ @currency || (info[:currencies] && info[:currencies][0])
100
+ end
101
+ def currency_label
102
+ if @currency
103
+ " (#@currency)"
104
+ else
105
+ ''
106
+ end
107
+ end
108
+
109
+ def name_c
110
+ name + currency_label
111
+ end
112
+ def name_c_file
113
+ name_c.to_s.gsub(/[: ()]/, '_')
114
+ end
115
+
116
+ def summary_table(today, days_before)
117
+
118
+ <<EOF
119
+ \\subsubsection{#{name_c}}
120
+ \\begin{tabulary}{0.8\\textwidth}{ r | l}
121
+ Balance & #{balance} \\\\
122
+ Deposited & #{deposited(today, days_before)} \\\\
123
+ Withdrawn & #{withdrawn(today, days_before)} \\\\
124
+ \\end{tabulary}
125
+ EOF
126
+ end
127
+ def summary_line(today, days_before)
128
+
129
+ <<EOF
130
+ #{name_c} & #{balance} & #{deposited(today, days_before)} & #{withdrawn(today, days_before)}
131
+ EOF
132
+ end
133
+ def money_in_sign
134
+ case type
135
+ when :Liability, :Income
136
+ -1.0
137
+ else
138
+ 1.0
139
+ end
140
+ end
141
+ def discretionary
142
+ info and info[:discretionary]
143
+ end
144
+ def info
145
+ ACCOUNT_INFO[name] ||= {}
146
+ end
147
+ def projected_balance(date)
148
+ #return 0.0 if @external # Temporary Hack
149
+ #ep ['projected', @reporter.projected_accounts_info]
150
+ raise "Only should be called for Asset and Liability accounts" unless [:Asset, :Liability].include? type
151
+ non_discretionary_projected_balance(date) -
152
+ @reporter.sum_regular(linked_projected_account_info, date)
153
+
154
+ #(discretionary ? @reporter.sum_regular({name => info}, date) : 0.0)
155
+ end
156
+ def linked_projected_account_info
157
+ Hash[@reporter.projected_accounts_info.find_all{|ext_ac,inf| inf[:linked_account] == name and ext_ac.currency == currency}]
158
+ end
159
+ def cache
160
+ @cache ||={}
161
+ end
162
+ def non_discretionary_projected_balance(date)
163
+ #ep ['FUTURE_INCOME', FUTURE_INCOME, name] if FUTURE_INCOME.size > 0
164
+ cache[[:non_discretionary_projected_balance, date]] ||=
165
+ balance +
166
+ #@reporter.sum_regular(REGULAR_EXPENDITURE[name], date) +
167
+ #@reporter.sum_regular(REGULAR_INCOME[name], date) -
168
+ #@reporter.sum_future(FUTURE_EXPENDITURE[name], date) +
169
+ #@reporter.sum_future(FUTURE_INCOME[name], date) +
170
+ (FUTURE_TRANSFERS.keys.find_all{|from,to| to == name}.map{|key|
171
+ @reporter.sum_future(FUTURE_TRANSFERS[key], date) * money_in_sign
172
+ }.sum||0) -
173
+ (FUTURE_TRANSFERS.keys.find_all{|from,to| from == name}.map{|key|
174
+ @reporter.sum_future( FUTURE_TRANSFERS[key], date) * money_in_sign
175
+ }.sum||0) +
176
+ (REGULAR_TRANSFERS.keys.find_all{|from,to| to == name}.map{|key|
177
+ @reporter.sum_regular(REGULAR_TRANSFERS[key], date) * money_in_sign
178
+ }.sum||0) -
179
+ (REGULAR_TRANSFERS.keys.find_all{|from,to| from == name}.map{|key|
180
+ @reporter.sum_regular( REGULAR_TRANSFERS[key], date) * money_in_sign
181
+ }.sum||0)
182
+ end
183
+ # Write an eps graph to disk of past and projected
184
+ # balance of the account
185
+ def write_balance_graph(today, days_before, days_ahead)
186
+ #accshort = name.gsub(/\s/, '')
187
+ if not (@external or type == :Equity or not has_balance?)
188
+ kit = @runner.graphkit(['date.to_time.to_i', 'balance'], {conditions: "account == #{name.inspect} and days_ago(Date.parse(#{today.to_s.inspect})) < #{days_before} and days_ago(Date.parse(#{today.to_s.inspect})) > -1", sort: '[date, id]'})
189
+ else
190
+ pastdates = (today-days_before..today).to_a
191
+ balances = pastdates.map{|date| balance(date)}
192
+ kit = GraphKit.quick_create([pastdates.map{|d| d.to_time.to_i}, balances])
193
+ end
194
+ futuredates = (today..today+days_ahead).to_a
195
+ projection = futuredates.map{|date| projected_balance(date) }
196
+ kit2 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, projection])
197
+ red = futuredates.map{|date| red_line(date)}
198
+ kit3 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, red])
199
+ @reporter.projected_account_factor = @reporter.in_limit_discretionary_account_factors[currency]
200
+ limit = futuredates.map{|date| projected_balance(date)}
201
+ kit4 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, limit])
202
+ @reporter.projected_account_factor = @reporter.stable_discretionary_account_factors[currency]
203
+ #ep ['projected_account_factor!!!!', @reporter.projected_account_factor]
204
+ stable = futuredates.map{|date| projected_balance(date)}
205
+ kit5 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, stable])
206
+ #exit
207
+ @reporter.projected_account_factor = nil
208
+ kit += (kit2 + kit4 + kit5)
209
+ #kit += (kit2)
210
+ kit = kit3 + kit
211
+ kit.title = "Balance for #{name_c}"
212
+ kit.xlabel = %['Date' offset 0,-2]
213
+ kit.xlabel = nil
214
+ kit.ylabel = "Balance"
215
+
216
+
217
+ kit.data[0].gp.title = 'Limit'
218
+ kit.data[1].gp.title = 'Previous'
219
+ kit.data[2].gp.title = '0 GBP Discretionary'
220
+ kit.data[2].gp.title = 'Projection'
221
+ kit.data[3].gp.title = 'Limit'
222
+ kit.data[4].gp.title = 'Stable'
223
+ kit.data.each{|dk| dk.gp.with = "l lw 5"}
224
+ kit.gp.key = ' bottom left '
225
+ kit.gp.key = ' rmargin '
226
+
227
+ #(p kit; STDIN.gets) if name == :LloydsCreditCard
228
+ CodeRunner::Budget.kit_time_format_x(kit)
229
+
230
+ fork do
231
+ (kit).gnuplot_write("#{name_c_file}_balance.eps", size: "4.0in,1.5in") #, latex: true)
232
+ %x[epspdf #{name_c_file}_balance.eps]
233
+ end
234
+ #%x[epspdf #{name}_balance.eps]
235
+ end
236
+ # A string to include the balance graph in the document
237
+ def balance_graph_string
238
+ #accshort = name.gsub(/\s/, '')
239
+ #"\\begin{center}\\includegraphics[width=3.0in]{#{name}_balance.eps}\\end{center}"
240
+ #"\\begin{center}\\includegraphics[width=0.9\\textwidth]{#{name}_balance.eps}\\end{center}"
241
+ "\\myfigure{#{name_c_file}_balance.pdf}"
242
+ end
243
+ end
244
+ class Equity < Account
245
+ def initialize(reporter, runner, accounts, options={})
246
+ @reporter = reporter
247
+ @runner = runner
248
+ @accounts = accounts #.find_all{|acc| not acc.external}
249
+ @currency = options[:currency]
250
+ end
251
+ def type
252
+ :Equity
253
+ end
254
+ def name
255
+ :Equity
256
+ end
257
+ def red_line(date)
258
+ @accounts.map{|acc|
259
+ case acc.type
260
+ when :Asset
261
+ acc.red_line(date)
262
+ when :Liability
263
+ -acc.red_line(date)
264
+ else
265
+ 0.0
266
+ end
267
+ }.sum
268
+ end
269
+ def balance(date=@reporter.today)
270
+ @accounts.map{|acc|
271
+ case acc.type
272
+ when :Asset
273
+ acc.balance(date)
274
+ when :Liability
275
+ -acc.balance(date)
276
+ else
277
+ 0.0
278
+ end
279
+ }.sum
280
+ end
281
+ def projected_balance(date=@reporter.today)
282
+ @accounts.map{|acc|
283
+ case acc.type
284
+ when :Asset
285
+ acc.projected_balance(date)
286
+ when :Liability
287
+ -acc.projected_balance(date)
288
+ else
289
+ 0.0
290
+ end
291
+ }.sum
292
+ end
293
+ def summary_table(today, days_before)
294
+
295
+ <<EOF
296
+ \\subsubsection{#{name}}
297
+ \\begin{tabulary}{0.8\\textwidth}{ r | l}
298
+ Balance & #{balance} \\\\
299
+ \\end{tabulary}
300
+ EOF
301
+ end
302
+ def summary_line(today, days_before)
303
+ "#{name_c} & #{balance(today)} & & "
304
+ end
305
+ end
306
+ end
307
+
@@ -6,32 +6,32 @@ module Analysis
6
6
  # period, along with a list of the expenditures
7
7
  # for each period and a list of the items within
8
8
  # each period
9
- def account_expenditure(account, account_info, options={})
9
+ def account_expenditure(account, options={})
10
10
  dates = []
11
11
  expenditures = []
12
12
  account_items = []
13
- date = account_info[:end]||@today
14
- start_date = [(account_info[:start]||@start_date), @start_date].max
13
+ date = account.info[:end]||@today
14
+ #start_date = [(account.info[:start]||@start_date), @start_date].max
15
15
  expenditure = 0
16
16
  items_temp = []
17
- items = @runner.component_run_list.values.find_all{|r| r.external_account == account and r.in_date(account_info)}
18
- #ep ['items', items]
19
- #ep ['account', account]
17
+ items = @runner.component_run_list.values.find_all{|r| r.external_account == account.name and r.in_date(account.info) and @accounts_hash[r.account].currency == account.currency}
18
+ #ep ['items', items.map{|i| i.date}]
19
+ #ep ['account', account.name_c]
20
20
  counter = 0
21
- if not account_info[:period]
21
+ if not account.info[:period]
22
22
  dates.push date
23
23
  account_items.push items
24
- expenditures.push (items.map{|r| (r.deposit - r.withdrawal) * (account_info[:external] ? -1 : 1)}+[0]).sum
24
+ expenditures.push (items.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum
25
25
  else
26
26
 
27
- case account_info[:period][1]
27
+ case account.info[:period][1]
28
28
  when :month
29
29
  while date > @start_date
30
30
  items_temp += items.find_all{|r| r.date == date}
31
- if date.mday == (account_info[:monthday] or 1)
31
+ if date.mday == (account.info[:monthday] or 1)
32
32
  counter +=1
33
- if counter % account_info[:period][0] == 0
34
- expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account_info[:external] ? -1 : 1)}+[0]).sum
33
+ if counter % account.info[:period][0] == 0
34
+ expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum
35
35
  dates.push date
36
36
  expenditures.push expenditure
37
37
  account_items.push items_temp
@@ -46,8 +46,8 @@ module Analysis
46
46
  items_temp += items.find_all{|r| r.date == date}
47
47
  #expenditure += (account_items[-1].map{|r| r.debit}+[0]).sum
48
48
  counter +=1
49
- if counter % account_info[:period][0] == 0
50
- expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account_info[:external] ? -1 : 1)}+[0]).sum
49
+ if counter % account.info[:period][0] == 0
50
+ expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum
51
51
  dates.push date
52
52
  expenditures.push expenditure
53
53
  account_items.push items_temp
@@ -68,21 +68,21 @@ module Analysis
68
68
  projected_accounts_info.each{|key,v| projected_accounts_info[key]=projected_accounts_info[key].dup}
69
69
  projected_accounts_info.each do |account, account_info|
70
70
  #account_info = accounts[account]
71
- dates, expenditures, items = account_expenditure(account, account_info)
72
- account_info[:average] = expenditures.mean rescue 0.0
71
+ _dates, expenditures, _items = account_expenditure(account, account_info)
72
+ account.average = expenditures.mean rescue 0.0
73
73
  end
74
74
  projected_accounts_info
75
75
  end
76
76
  # Work out the projected spend from the account and include it in the account info
77
- def accounts_with_projections(accounts, options={})
78
- projected_accounts_info = accounts.dup
79
- projected_accounts_info.each{|key,v| projected_accounts_info[key]=projected_accounts_info[key].dup}
80
- projected_accounts_info.each do |account, account_info|
77
+ def accounts_with_projections(projected_accounts, options={})
78
+ #projected_accounts_info = accounts.dup
79
+ #projected_accounts_info.each{|key,v| projected_accounts_info[key]=projected_accounts_info[key].dup}
80
+ projected_accounts.each do |account|
81
81
  #account_info = accounts[account]
82
- dates, expenditures, items = account_expenditure(account, account_info)
83
- account_info[:projection] = expenditures.mean rescue 0.0
82
+ _dates, expenditures, _items = account_expenditure(account)
83
+ account.projection = expenditures.mean rescue 0.0
84
84
  end
85
- projected_accounts_info
85
+ projected_accounts.map{|acc| [acc, acc.info]}.to_h
86
86
  end
87
87
  ## Get a list of accounts to be included in the report
88
88
  ## i.e. accounts with non-empty expenditure
@@ -96,9 +96,11 @@ module Analysis
96
96
  # expenditure from that account based on past
97
97
  # expenditure (currently only a simple average)
98
98
  def get_projected_accounts
99
- @projected_accounts_info = Hash[ACCOUNT_INFO.dup.find_all{|k,v| v[:discretionary]}]
100
- @projected_accounts_info = accounts_with_projections(@projected_accounts_info)
99
+ #@projected_accounts_info = Hash[ACCOUNT_INFO.dup.find_all{|k,v| v[:discretionary]}]
100
+ #@projected_accounts_info = accounts_with_projections(@projected_accounts_info)
101
101
  #@projected_accounts_info = @accounts.find_all{|acc| info = ACCOUNT_INFO[acc.name] and info[:discretionary]}
102
+ projected_accounts = @accounts.find_all{|acc| acc.info and acc.info[:discretionary]}
103
+ @projected_accounts_info = accounts_with_projections(projected_accounts)
102
104
  end
103
105
  # Calculate the sum of all items within future
104
106
  # items that fall before end_date
@@ -121,7 +123,7 @@ module Analysis
121
123
  # regular items that falls within the account period
122
124
  def sum_regular(regular_items, end_date, options={})
123
125
  #end_date = @today + @days_ahead
124
- sum = regular_items.inject(0) do |sum, (name, item)|
126
+ sum_out = regular_items.inject(0) do |sum, (account, item)|
125
127
  item = [item] unless item.kind_of? Array
126
128
  # ep item
127
129
  value = item.inject(0) do |value,info|
@@ -182,13 +184,13 @@ module Analysis
182
184
 
183
185
  #ep ['name2234', name, info, @projected_account_factor] if info[:discretionary]
184
186
 
185
- value + nunits * (info[:size]||info[:projection]*(@projected_account_factor||1.0))
187
+ value + nunits * (info[:size]||account.projection*(@projected_account_factor||1.0))
186
188
 
187
189
  end
188
190
  sum + value
189
191
  #(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value
190
192
  end
191
- sum
193
+ sum_out
192
194
  end
193
195
  end
194
196
  include Analysis
@@ -2,7 +2,7 @@
2
2
  class Treasurer
3
3
  class << self
4
4
  def add_file(file, account, copts={})
5
- load_treasurer_folder
5
+ load_treasurer_folder(copts)
6
6
  ep 'entries', Dir.entries
7
7
  CodeRunner.submit(p: "{data_file: '#{File.expand_path(file)}', account: :#{account}}")
8
8
  end
@@ -23,9 +23,13 @@ class << self
23
23
  reporter.report()
24
24
  end
25
25
  def fetch_reporter(copts = {})
26
- load_treasurer_folder
27
- reporter = Reporter.new(CodeRunner.fetch_runner(h: :component), days_before: copts[:b]||360, days_ahead: copts[:a]||180, today: copts[:t])
26
+ load_treasurer_folder(copts)
27
+ reporter = Reporter.new(CodeRunner.fetch_runner(h: :component, A: true), days_before: copts[:b]||360, days_ahead: copts[:a]||180, today: copts[:t])
28
28
  end
29
+ def status(copts={})
30
+ load_treasurer_folder(copts)
31
+ CodeRunner.status(eval(copts[:C]||"{}"))
32
+ end
29
33
  def init_root_folder(folder, copts={})
30
34
  raise "Folder already exists" if FileTest.exist? folder
31
35
  FileUtils.makedirs(folder)
@@ -33,15 +37,16 @@ class << self
33
37
  CodeRunner.fetch_runner(Y: folder, C: 'budget', X: '/dev/null')
34
38
  eputs "\n\n Your treasurer folder '#{folder}' has been set up. All further treasurer commands should be run from within this folder.\n"
35
39
  end
36
- def load_treasurer_folder
40
+ def load_treasurer_folder(copts={})
37
41
  check_is_treasurer_folder
38
42
  Treasurer.send(:remove_const, :LocalCustomisations) if defined? Treasurer::LocalCustomisations
39
43
  load 'local_customisations.rb'
40
44
  Treasurer::Reporter.send(:include, Treasurer::LocalCustomisations)
41
45
  Treasurer::Reporter::Account.send(:include, Treasurer::LocalCustomisations)
42
46
  Treasurer::Reporter::Analysis.send(:include, Treasurer::LocalCustomisations)
43
- runner = CodeRunner.fetch_runner
47
+ require 'budgetcrmod'
44
48
  CodeRunner::Budget.send(:include, Treasurer::LocalCustomisations)
49
+ _runner = CodeRunner.fetch_runner(eval(copts[:C]||"{}"))
45
50
  end
46
51
 
47
52
  def method_missing(meth, *args)