Module: Treasurer::Reporter::Analysis

Included in:
Treasurer::Reporter
Defined in:
lib/treasurer/analysis.rb

Instance Method Summary collapse

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 (, options={})
   start_dates = []
	end_dates = []
	expenditures = []
	 = []
	date = .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 = .runs.find_all{|r| r.in_date(.info)}
   #ep ['items', items.map{|i| i.date}]
   #ep ['account', account.name_c]
	counter = 0
	if not .info[:period]
     start_dates.push (.info[:start]||@start_date)
		end_dates.push date
		.push items
		expenditures.push (items.map{|r| (r.deposit - r.withdrawal) * (.info[:external] ? -1 : 1)}+[0]).sum
	else
     end_date = nil
		case .info[:period][1]
		when :month
       crossed_boundary = false
			while date > @start_date
				if (date+1).mday == (.info[:monthday] or 1)
					counter +=1
					if counter % .info[:period][0] == 0
             if crossed_boundary # We only calcate expenditures for whole periods.
               expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (.info[:external] ? -1 : 1)}+[0]).sum
               end_dates.push end_date
               start_dates.push date+1
               expenditures.push expenditure
               .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 % .info[:period][0] == 0
					expenditure = (items_temp.map{|r| (r.deposit - r.withdrawal) * (.info[:external] ? -1 : 1)}+[0]).sum
					end_dates.push date
					expenditures.push expenditure
					.push items_temp
					items_temp = []
					expenditure = 0
				end
				date-=1
			end
		end
	end

	[start_dates, end_dates, expenditures, ]

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, options={})
 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_info = accounts[account]
	 #_dates, expenditures, _items = account_expenditure(account, account_info)
	 _start_dates, _dates, expenditures, _items = ()
    .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, options={})
 #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_info = accounts[account]
	 _start_dates, _dates, expenditures, _items = ()
	 .projection = expenditures.mean rescue 0.0
 end
  projected_accounts.map{|acc| [acc, acc.info]}.to_h
end

#get_projected_accountsObject

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, options={})
  #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, options={})
  #end_date = @today + @days_ahead
	sum_out = regular_items.inject(0) do |sum, (, 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 = .kind_of?(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]||.projection*(@projected_account_factor||1.0))

		end
		sum + value_out
		#(rcp.excluding? and rcp.excluding.include?(name)) ? sum : sum + value
	end
	sum_out
end