Class: Treasurer::Reporter::Account
- Inherits:
-
Object
- Object
- Treasurer::Reporter::Account
- Defined in:
- lib/treasurer/accounts.rb,
lib/treasurer/accounts.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#average ⇒ Object
Returns the value of attribute average.
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
-
#external ⇒ Object
readonly
Returns the value of attribute external.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#original_currency ⇒ Object
Returns the value of attribute original_currency.
-
#projection ⇒ Object
Returns the value of attribute projection.
-
#runs ⇒ Object
readonly
Returns the value of attribute runs.
Instance Method Summary collapse
- #available(date = @reporter.today) ⇒ Object
- #balance(date = @reporter.today, options = {}) ⇒ Object
-
#balance_graph_string ⇒ Object
A string to include the balance graph in the document.
- #cache ⇒ Object
- #currency_label ⇒ Object
- #deposited(today, days_before, &block) ⇒ Object
- #discretionary ⇒ Object
-
#generate_report_account ⇒ Object
Make the account object that does the reporting.
- #has_balance? ⇒ Boolean
- #info ⇒ Object
-
#initialize(name, reporter, runner, runs, external, options = {}) ⇒ Account
constructor
A new instance of Account.
-
#linked_projected_account_info ⇒ Object
(discretionary ? @reporter.sum_regular(=> info, date) : 0.0).
- #money_in_sign ⇒ Object
- #name_c ⇒ Object
- #name_c_file ⇒ Object
- #non_discretionary_projected_balance(date) ⇒ Object
- #opening_balance ⇒ Object
- #opening_date ⇒ Object
- #projected_balance(date) ⇒ Object
- #red_line(date = @reporter.today) ⇒ Object
-
#report_account ⇒ Object
The object that actually does the reporting.
- #report_start ⇒ Object
-
#should_report? ⇒ Boolean
Should I report? If there is no currency conversion all accounts report.
- #sub_accounts ⇒ Object
- #summary_line(today, days_before) ⇒ Object
- #summary_table(today, days_before) ⇒ Object
- #type ⇒ Object
- #withdrawn(today, days_before) ⇒ Object
-
#write_balance_graph(today, days_before, days_ahead) ⇒ Object
Write an eps graph to disk of past and projected balance of the account.
Constructor Details
#initialize(name, reporter, runner, runs, external, options = {}) ⇒ Account
Returns a new instance of Account.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/treasurer/accounts.rb', line 21 def initialize(name, reporter, runner, runs, external, ={}) @name = name @reporter = reporter @runner = runner @currency = [:currency] #@projected_accounts_info =Hash[projected_accounts_info.find_all{|k,v| v[:account] == name}] @external = external unless @runs = [:input_runs] @runs = runs.find_all do |r| #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency and @external #@external ? r.external_account : r.account) == name} if not @external r.account == name elsif @currency and info and cur = info[:currencies] and cur.size > 1 #p ['checking11', name, @currency, ACCOUNT_INFO[r.account]] if name == r.external_account and @currency r.external_account == name and acinfo = ACCOUNT_INFO[r.account] and acinfo[:currencies] == [@currency] else r.external_account == name end end if should_report? if @external @report_runs = runs.find_all do |r| r.external_account == name end else @report_runs = @runs end end else @report_runs = [] end #p ['Accountinf', name, @currency, @runs.size, runs.size] info[:external] = external if info end |
Instance Attribute Details
#average ⇒ Object
Returns the value of attribute average.
20 21 22 |
# File 'lib/treasurer/accounts.rb', line 20 def average @average end |
#currency ⇒ Object (readonly)
Returns the value of attribute currency.
19 20 21 |
# File 'lib/treasurer/accounts.rb', line 19 def currency @currency end |
#external ⇒ Object (readonly)
Returns the value of attribute external.
19 20 21 |
# File 'lib/treasurer/accounts.rb', line 19 def external @external end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/treasurer/accounts.rb', line 19 def name @name end |
#original_currency ⇒ Object
Returns the value of attribute original_currency.
20 21 22 |
# File 'lib/treasurer/accounts.rb', line 20 def original_currency @original_currency end |
#projection ⇒ Object
Returns the value of attribute projection.
20 21 22 |
# File 'lib/treasurer/accounts.rb', line 20 def projection @projection end |
#runs ⇒ Object (readonly)
Returns the value of attribute runs.
19 20 21 |
# File 'lib/treasurer/accounts.rb', line 19 def runs @runs end |
Instance Method Details
#available(date = @reporter.today) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/treasurer/accounts.rb', line 124 def available(date = @reporter.today) case type when :Asset, :Equity b = balance b - red_line when :Liability b = balance red_line - b else nil end end |
#balance(date = @reporter.today, options = {}) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/treasurer/accounts.rb', line 136 def balance(date = @reporter.today, ={}) @balance_cache ||= {} if b = @balance_cache[[date,]] return b end date_i = date.to_datetime.to_time.to_i #if !date #@runs.sort_by{|r| r.date}[-1].balance balance = nil if @external or not has_balance? #p ['name is ', name, type] # if type == :Expense balance = (@runs.find_all{|r| r.date <= date and r.date >= @reporter.start_date }.map{|r| money_in_sign * (r.deposit - r.withdrawal) * (@external ? -1 : 1)}.sum || 0.0) else 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) balance += info[:opening_balance] if info[:opening_balance] balance end #Temporary.... #0.0 else #p ['name33 is ', name, type, @runs.size, @currency] nearest_time = @runs.map{|r| (r.date_i - date_i).to_f.abs}.sort[0] balance = @runs.find_all{|r| (r.date_i - date_i).to_f.abs == nearest_time}.sort_by{|r| r.id}[-1].balance end if [:original_currency] and @original_currency and @original_currency!=currency balance = balance*EXCHANGE_RATES[[currency, @original_currency]] end @balance_cache[[date,]]=balance balance end |
#balance_graph_string ⇒ Object
A string to include the balance graph in the document
365 366 367 368 369 370 |
# File 'lib/treasurer/accounts.rb', line 365 def balance_graph_string #accshort = name.gsub(/\s/, '') #"\\begin{center}\\includegraphics[width=3.0in]{#{name}_balance.eps}\\end{center}" #"\\begin{center}\\includegraphics[width=0.9\\textwidth]{#{name}_balance.eps}\\end{center}" "\\myfigure{#{name_c_file}_balance.pdf}" end |
#cache ⇒ Object
246 247 248 |
# File 'lib/treasurer/accounts.rb', line 246 def cache @cache ||={} end |
#currency_label ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/treasurer/accounts.rb', line 181 def currency_label if currency " (#{currency}#{@original_currency ? "<-#@original_currency" : ""})" else '' end end |
#deposited(today, days_before, &block) ⇒ Object
169 170 171 172 173 |
# File 'lib/treasurer/accounts.rb', line 169 def deposited(today, days_before, &block) #p ['name223344 is ', name_c, today, days_before] #@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 @runs.find_all{|r| r.days_ago(today) < days_before and r.date <= today and (!block or yield(r)) }.map{|r| (@external) ? r.withdrawal : r.deposit }.sum || 0 end |
#discretionary ⇒ Object
221 222 223 |
# File 'lib/treasurer/accounts.rb', line 221 def discretionary info and info[:discretionary] end |
#generate_report_account ⇒ Object
Make the account object that does the reporting. This only gets called if we are doing a currency conversion and this account is in the reeport currency.
61 62 63 64 65 66 |
# File 'lib/treasurer/accounts.rb', line 61 def generate_report_account p [name_c, @report_runs.class, @runs.class] @report_account = ReportAccount.new(@name, @reporter, @runner, nil, @external, {currency: @currency, input_runs: @report_runs}) @report_account.instance_variable_set(:@currency, @reporter.report_currency||currency) @report_account.instance_variable_set(:@original_currency, currency) end |
#has_balance? ⇒ Boolean
121 122 123 |
# File 'lib/treasurer/accounts.rb', line 121 def has_balance? not @runs.find{|r| not r.has_balance?} end |
#info ⇒ Object
224 225 226 |
# File 'lib/treasurer/accounts.rb', line 224 def info ACCOUNT_INFO[name] ||= {} end |
#linked_projected_account_info ⇒ Object
(discretionary ? @reporter.sum_regular(=> info, date) : 0.0)
236 237 238 239 240 241 242 243 244 245 |
# File 'lib/treasurer/accounts.rb', line 236 def linked_projected_account_info #Hash[@reporter.projected_accounts_info.find_all{|ext_ac,inf| inf[:linked_account] == name and ext_ac.currency == currency}] Hash[@reporter.projected_accounts_info.find_all{|ext_ac,inf| la = inf[:linked_account] and ( la == name or (la.kind_of? Hash and la[original_currency] and la[original_currency] == name and ext_ac.original_currency == original_currency) ) }] end |
#money_in_sign ⇒ Object
213 214 215 216 217 218 219 220 |
# File 'lib/treasurer/accounts.rb', line 213 def money_in_sign case type when :Liability, :Income -1.0 else 1.0 end end |
#name_c ⇒ Object
189 190 191 |
# File 'lib/treasurer/accounts.rb', line 189 def name_c name + currency_label end |
#name_c_file ⇒ Object
192 193 194 |
# File 'lib/treasurer/accounts.rb', line 192 def name_c_file name_c.to_s.gsub(/[: ()<-]/, '_') end |
#non_discretionary_projected_balance(date) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/treasurer/accounts.rb', line 249 def non_discretionary_projected_balance(date) #ep ['FUTURE_INCOME', FUTURE_INCOME, name] if FUTURE_INCOME.size > 0 if not (@futures and @regulars) @futures = Marshal.load(Marshal.dump(FUTURE_TRANSFERS)) @regulars = Marshal.load(Marshal.dump(REGULAR_TRANSFERS)) [@regulars, @futures].each do |transfers| @accounts_hash = @reporter.accounts_hash transfers.each do |accs, trans| next unless accs.include? name trans.each do |item, details| if details[:currency] and details[:currency] != currency #p ['LAGT(O', details[:currency], currency, details, name_c, item] details[:size] *= EXCHANGE_RATES[[details[:currency], currency]] end end end end end cache[[:non_discretionary_projected_balance, date]] ||= balance + #@reporter.sum_regular(REGULAR_EXPENDITURE[name], date) + #@reporter.sum_regular(REGULAR_INCOME[name], date) - #@reporter.sum_future(FUTURE_EXPENDITURE[name], date) + #@reporter.sum_future(FUTURE_INCOME[name], date) + (@futures.keys.find_all{|from,to| to == name}.map{|key| @reporter.sum_future(@futures[key], date) * money_in_sign }.sum||0) - (@futures.keys.find_all{|from,to| from == name}.map{|key| @reporter.sum_future( @futures[key], date) * money_in_sign }.sum||0) + (@regulars.keys.find_all{|from,to| to == name}.map{|key| @reporter.sum_regular(@regulars[key], date) * money_in_sign }.sum||0) - (@regulars.keys.find_all{|from,to| from == name}.map{|key| @reporter.sum_regular( @regulars[key], date) * money_in_sign }.sum||0) end |
#opening_balance ⇒ Object
118 119 120 |
# File 'lib/treasurer/accounts.rb', line 118 def opening_balance (info && info[:opening_balance]) || 0.0 end |
#opening_date ⇒ Object
115 116 117 |
# File 'lib/treasurer/accounts.rb', line 115 def opening_date (info && info[:start]) || @runs.map{|r| r.date}.min end |
#projected_balance(date) ⇒ Object
227 228 229 230 231 232 233 234 235 |
# File 'lib/treasurer/accounts.rb', line 227 def projected_balance(date) #return 0.0 if @external # Temporary Hack #ep ['projected', @reporter.projected_accounts_info] raise "Only should be called for Asset and Liability accounts" unless [:Asset, :Liability].include? type non_discretionary_projected_balance(date) - @reporter.sum_regular(linked_projected_account_info, date) #(discretionary ? @reporter.sum_regular({name => info}, date) : 0.0) end |
#red_line(date = @reporter.today) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/treasurer/accounts.rb', line 99 def red_line(date=@reporter.today) if Treasurer::LocalCustomisations.instance_methods.include? :red_line val = super(name, date) if rc = @reporter.report_currency and rc != @original_currency er = EXCHANGE_RATES[[@original_currency,rc]] #p ['AAAAAAA', name, @original_currency, er, val, rc] val *= er end val else 0.0 end end |
#report_account ⇒ Object
The object that actually does the reporting. If there is no currency conversion this is just self. A separate report object is needed as just lumping all the different currencies together across the board results in double counting.
The report account is used for reporting information regarding a particular account. The main accoun is used for calculations e.g. Equity
77 78 79 |
# File 'lib/treasurer/accounts.rb', line 77 def report_account @report_account || self end |
#report_start ⇒ Object
112 113 114 |
# File 'lib/treasurer/accounts.rb', line 112 def report_start @reporter.today - @reporter.days_before end |
#should_report? ⇒ Boolean
Should I report? If there is no currency conversion all accounts report. If there is currency conversion only non-external accounts and accounts in the right currency report.
85 86 87 |
# File 'lib/treasurer/accounts.rb', line 85 def should_report? !@reporter.report_currency or !@external or (@original_currency||currency) == @reporter.report_currency end |
#sub_accounts ⇒ Object
88 89 90 |
# File 'lib/treasurer/accounts.rb', line 88 def sub_accounts @sub_accounts ||= @runs.map{|r| r.sub_account}.uniq.compact.map{|acc| SubAccount.new(acc, @reporter, @runner, @runs, @external, currency: @currency)} end |
#summary_line(today, days_before) ⇒ Object
207 208 209 210 211 212 |
# File 'lib/treasurer/accounts.rb', line 207 def summary_line(today, days_before) <<EOF #{name_c} & #{balance.to_tex} & #{deposited(today, days_before).to_tex} & #{withdrawn(today, days_before).to_tex} EOF end |
#summary_table(today, days_before) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/treasurer/accounts.rb', line 196 def summary_table(today, days_before) <<EOF \\subsubsection{#{name_c}} \\begin{tabulary}{0.8\\textwidth}{ r | l} Balance & #{balance} \\\\ Deposited & #{deposited(today, days_before)} \\\\ Withdrawn & #{withdrawn(today, days_before)} \\\\ \\end{tabulary} EOF end |
#type ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/treasurer/accounts.rb', line 91 def type #account_type(name) if ACCOUNT_INFO[name] and type = ACCOUNT_INFO[name][:type] type else :Expense end end |
#withdrawn(today, days_before) ⇒ Object
174 175 176 177 |
# File 'lib/treasurer/accounts.rb', line 174 def withdrawn(today, days_before) #@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 @runs.find_all{|r| r.days_ago(today) < days_before and r.date <= today }.map{|r| (@external) ? r.deposit : r.withdrawal }.sum || 0 end |
#write_balance_graph(today, days_before, days_ahead) ⇒ Object
Write an eps graph to disk of past and projected balance of the account
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/treasurer/accounts.rb', line 290 def write_balance_graph(today, days_before, days_ahead) #accshort = name.gsub(/\s/, '') if not (@external or type == :Equity or not has_balance?) 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]'}) else pastdates = (today-days_before..today).to_a balances = pastdates.map{|date| balance(date)} kit = GraphKit.quick_create([pastdates.map{|d| d.to_time.to_i}, balances]) end futuredates = (today..today+days_ahead).to_a projection = futuredates.map{|date| projected_balance(date) } kit2 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, projection]) red = futuredates.map{|date| red_line(date)} kit3 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, red]) @reporter.projected_account_factor = @reporter.in_limit_discretionary_account_factors[currency] limit = futuredates.map{|date| projected_balance(date)} kit4 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, limit]) @reporter.projected_account_factor = @reporter.stable_discretionary_account_factors[currency] #ep ['projected_account_factor!!!!', @reporter.projected_account_factor] stable = futuredates.map{|date| projected_balance(date)} kit5 = GraphKit.quick_create([futuredates.map{|d| d.to_time.to_i}, stable]) [kit2,kit4,kit5].each{|k| k.data[0].y.data[0] = balance(today)} #exit @reporter.projected_account_factor = nil kit += ( kit4 + kit5 + kit2) #kit.yrange = [(m = kit.data.map{|dk| dk.y.data.min}.min; m-m.abs*0.1), (m=kit.data.map{|dk| dk.y.data.max}.max; m+m.abs*0.1)] #kit += (kit2) kit = kit3 + kit kit.title = "Balance for #{name_c}" kit.xlabel = %['Date' offset 0,-2] kit.xlabel = nil kit.ylabel = "Balance" kit.gp.mytics= "5" kit.gp.grid = "ytics mytics lw 2,lw 1" kit.data[0].gp.title = 'Limit' kit.data[1].gp.title = 'Previous' #kit.data[2].gp.title = '0 GBP Discretionary' kit.data[2].gp.title = 'Avoid Limit' kit.data[3].gp.title = 'Stable' kit.data[4].gp.title = 'Projection' kit.data.each{|dk| dk.gp.with = "l lw 5"} kit.data[4].gp.with = "l lw 5 dt 2 lc rgb 'black' " kit.gp.key = ' bottom left ' kit.gp.key = ' rmargin samplen 2' kit.gp.decimalsign = 'locale "en_GB.UTF-8"' #bal, avail = balance, available if avail = available kit.gp.label = [ %[ "Balance \\n#{balance}\\n\\nAvailable\\n#{avail}" at screen 0.95, screen 0.5 right], ] end #(p kit; STDIN.gets) if name == :LloydsCreditCard CodeRunner::Budget.kit_time_format_x(kit) kit.gp.format.push %[y "%'.2f"] size = case type when :Equity "4.0in,4.0in" else "4.0in,2.5in" end fork do (kit).gnuplot_write("#{name_c_file}_balance2.eps", size: size) #, latex: true) system %[ps2epsi #{name_c_file}_balance2.eps #{name_c_file}_balance.eps] system %[epstopdf #{name_c_file}_balance.eps] end #%x[epstopdf #{name}_balance.eps] end |