Module: Treasurer::Reporter::Analysis
- Included in:
- Treasurer::Reporter
- Defined in:
- lib/treasurer/analysis.rb
Instance Method Summary collapse
-
#account_expenditure(account, options = {}) ⇒ Object
Within the range of the report, return a list of the dates of the beginning of each account period, along with a list of the expenditures for each period and a list of the items within each period.
-
#accounts_with_averages(accounts, options = {}) ⇒ Object
Work out the average spend from the account and include it in the account info.
-
#accounts_with_projections(projected_accounts, options = {}) ⇒ Object
Work out the projected spend from the account and include it in the account info.
-
#get_projected_accounts ⇒ Object
end Find all discretionary accounts and estimate the future expenditure from that account based on past expenditure (currently only a simple average).
-
#sum_future(future_items, end_date, options = {}) ⇒ Object
Calculate the sum of all items within future items that fall before end_date.
-
#sum_regular(regular_items, end_date, options = {}) ⇒ Object
Sum every future occurence of the given regular items that falls within the account period.
Instance Method Details
#account_expenditure(account, options = {}) ⇒ Object
Within the range of the report, return a list of the dates of the beginning of each account period, along with a list of the expenditures for each period and a list of the items within each period
16 17 18 19 20 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/treasurer/analysis.rb', line 16 def account_expenditure(account, ={}) start_dates = [] end_dates = [] expenditures = [] account_items = [] date = account.info[:end]||@today #start_date = [(account.info[:start]||@start_date), @start_date].max expenditure = 0 items_temp = [] #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].original_currency == account.original_currency} items = account.runs.find_all{|r| r.in_date(account.info)} #ep ['items', items.map{|i| i.date}] #ep ['account', account.name_c] counter = 0 if not account.info[:period] start_dates.push (account.info[:start]||@start_date) end_dates.push date account_items.push items expenditures.push (items.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum else end_date = nil case account.info[:period][1] when :month crossed_boundary = false while date > @start_date if (date+1).mday == (account.info[:monthday] or 1) counter +=1 if counter % account.info[:period][0] == 0 if crossed_boundary # We only calcate expenditures for whole periods. expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum end_dates.push end_date start_dates.push date+1 expenditures.push expenditure account_items.push items_temp end end_date = date crossed_boundary = true items_temp = [] expenditure = 0 end end items_temp += items.find_all{|r| r.date == date} date-=1 end when :day raise "Period of days not implemented yet" while date > @start_date items_temp += items.find_all{|r| r.date == date} #expenditure += (account_items[-1].map{|r| r.debit}+[0]).sum counter +=1 if counter % account.info[:period][0] == 0 expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (account.info[:external] ? -1 : 1)}+[0]).sum end_dates.push date expenditures.push expenditure account_items.push items_temp items_temp = [] expenditure = 0 end date-=1 end end end [start_dates, end_dates, expenditures, account_items] end |
#accounts_with_averages(accounts, options = {}) ⇒ Object
Work out the average spend from the account and include it in the account info
83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/treasurer/analysis.rb', line 83 def accounts_with_averages(accounts, ={}) projected_accounts_info = accounts.dup projected_accounts_info.each{|key,v| projected_accounts_info[key]=projected_accounts_info[key].dup} projected_accounts_info.each do |account, account_info| #account_info = accounts[account] #_dates, expenditures, _items = account_expenditure(account, account_info) _start_dates, _dates, expenditures, _items = account_expenditure(account) account.average = expenditures.mean rescue 0.0 end projected_accounts_info end |
#accounts_with_projections(projected_accounts, options = {}) ⇒ Object
Work out the projected spend from the account and include it in the account info
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/treasurer/analysis.rb', line 95 def accounts_with_projections(projected_accounts, ={}) #projected_accounts_info = accounts.dup #projected_accounts_info.each{|key,v| projected_accounts_info[key]=projected_accounts_info[key].dup} projected_accounts.each do |account| #account_info = accounts[account] _start_dates, _dates, expenditures, _items = account_expenditure(account) account.projection = expenditures.mean rescue 0.0 end projected_accounts.map{|acc| [acc, acc.info]}.to_h end |
#get_projected_accounts ⇒ Object
end Find all discretionary accounts and estimate the future expenditure from that account based on past expenditure (currently only a simple average)
116 117 118 119 120 121 122 |
# File 'lib/treasurer/analysis.rb', line 116 def get_projected_accounts #@projected_accounts_info = Hash[ACCOUNT_INFO.dup.find_all{|k,v| v[:discretionary]}] #@projected_accounts_info = accounts_with_projections(@projected_accounts_info) #@projected_accounts_info = @accounts.find_all{|acc| info = ACCOUNT_INFO[acc.name] and info[:discretionary]} projected_accounts = @accounts.find_all{|acc| acc.info and acc.info[:discretionary]} @projected_accounts_info = accounts_with_projections(projected_accounts) end |
#sum_future(future_items, end_date, options = {}) ⇒ Object
Calculate the sum of all items within future items that fall before end_date
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/treasurer/analysis.rb', line 125 def sum_future(future_items, end_date, ={}) #end_date = @today + @days_ahead sum_out = future_items.inject(0.0) do |sum, (_name, item)| item = [item] unless item.kind_of? Array value_out = item.inject(0.0) do |value,info| value += info[:size] unless ((@today||Date.today) > info[:date]) or (info[:date] > end_date) # add unless we have already passed that date value end #ep ['name2223', name, item, value, end_date, @today, (@today||Date.today > item[0][:date]), (item[0][:date] > end_date)] sum + value_out #rcp.excluding.include?(name) ? sum : sum + value end sum_out end |
#sum_regular(regular_items, end_date, options = {}) ⇒ Object
Sum every future occurence of the given regular items that falls within the account period
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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/treasurer/analysis.rb', line 142 def sum_regular(regular_items, end_date, ={}) #end_date = @today + @days_ahead sum_out = regular_items.inject(0) do |sum, (account, item)| item = [item] unless item.kind_of? Array # ep item value_out = item.inject(0) do |value,info| finish = (info[:end] and info[:end] < end_date) ? info[:end] : end_date #today = (Time.now.to_i / (24.0*3600.0)).round nunits = 0.0 counter = info[:period][0] == 1 ? 0 : nil unless counter date = @today counter = 0 case info[:period][1] when :month while date >= (info[:start] or @today) counter +=1 if date.mday == (info[:monthday] or 1) date -= 1 end when :year while date >= (info[:start] or @today) counter +=1 if date.yday == (info[:yearday] or 1) date -= 1 end when :day while date > (info[:start] or @today) counter +=1 date -= 1 end end end delta_units = account.kind_of?(Account) && account.projection date = @today case info[:period][1] when :month #p date, info while date <= finish if delta_units nunits += 1.0/date.days_in_month else if date.mday == (info[:monthday] or 1) nunits += 1 if counter % info[:period][0] == 0 counter +=1 end end date += 1 end when :year while date <= finish if delta_units nunits += 1.0/date.days_in_year else if date.yday == (info[:yearday] or 1) nunits += 1 if counter % info[:period][0] == 0 counter +=1 end end date += 1 end when :day while date <= finish nunits += 1 if counter % info[:period][0] == 0 counter +=1 date += 1 end end #ep ['name2234', name, info, @projected_account_factor] if info[:discretionary] value + nunits * (info[:size]||account.projection*(@projected_account_factor||1.0)) end sum + value_out #(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value end sum_out end |