treasurer 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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)