reworked dividend
[smr.git] / gui / lib / smr / asset.rb
blob7bfb487188ecc972d99664439d50760d4b216534
2 # This file is part of SMR.
4 # SMR is free software: you can redistribute it and/or modify it under the
5 # terms of the GNU General Public License as published by the Free Software
6 # Foundation, either version 3 of the License, or (at your option) any later
7 # version.
9 # SMR is distributed in the hope that it will be useful, but WITHOUT ANY
10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along with
14 # SMR.  If not, see <http://www.gnu.org/licenses/>.
16 require 'asset_position'
18 module Smr  #:nodoc:
19   ##
20   # Total assets of current user at some point in time.
21   #
22   # Use #open_positions to access Smr::AssetPosition objects of all positions
23   # held. Then each knows more details about itself.
24   class Asset
25       # collection of Smr::AssetPosition objects of currently open positions
26       attr_reader :open_positions
28       # currently invested amount of money
29       attr_reader :invested
31       # current market value of all assets
32       attr_reader :market_value
34       # current profit/loss on all assets
35       attr_reader :profit_loss
37       ##
38       # age of +Quote+ data before its considered old
39       QUOTE_OUTDATED_DAYS = 4
40   
41       ## 
42       # date defines the point of Time this object sits at
43       def initialize(id_user, date, id_portfolio=false)
44           raise 'date must be of Time' unless date.is_a?(Time)
47           @id_user = id_user
48           @date = date
50           limit_portfolio = if id_portfolio then 'AND po.id=%i' % id_portfolio else '' end
51   
52           @invested = 0.0
53           @market_value = 0.0
54           @profit_loss = 0.0
55   
56           @_have_old_quotes = false
57           @_have_missing_quotes = false
58   
59           @open_positions = Array.new
61           # ATTENTION: not portable!
62           # - thats not the preferred way to do a query.
63           # - this one is just too complex for ActiveRecord at the moment
64           open_positions = Smr::AssetPositions.new(@date, '
65           SELECT
66               p.id
67          /*   p.id_stock,
68               p.id_portfolio,   # if those values could be used
69               pr.id_order,      # things would be much faster since
70               pr.id_position,   # subsequent SmrPosition objects query
71               pr.date,          # these again... too many queries...
72               pr.shares,
73               pr.invested */
74           FROM
75               position p,
76               position_revision pr,
77               stock s,
78               portfolio po,
79               (SELECT
80                   MAX(pr1.date) AS LASTDATE,
81                   pr1.id_position AS LASTPOSITION
82                   FROM
83                       position_revision pr1
84                   WHERE
85                       pr1.date<=%i
86                   GROUP BY pr1.id_position
87               ) AS blah
88           WHERE
89               p.id=pr.id_position
90               %s
91               AND p.id_portfolio=po.id
92               AND s.id=p.id_stock
93               AND po.id_user=%i
94               AND (p.closed=0 OR p.closed>%i)
95               AND pr.date=LASTDATE
96               AND pr.id_position=LASTPOSITION
97               AND po.name NOT LIKE "watchlist:%%"   /* HACK for speed on old DBs */
98           GROUP BY p.id
99           ORDER BY s.name, pr.date' % [@date, limit_portfolio, @id_user, @date]).get_all
100   
101           # turn Position objects into SmrPosition
102           # - for the sake of performance we calculate totals right here
103           open_positions.each do |p|
104               sp = Smr::AssetPosition.new(p.id, id_user, @date)
105               @open_positions << sp
106   
107               @invested += sp.invested
108               @market_value += sp.market_value if sp.market_value
109               @profit_loss += sp.profit_loss if sp.profit_loss
110   
111               if not sp.market_value then @_have_missing_quotes = true end
112               if sp.quote_time and  sp.quote_time < QUOTE_OUTDATED_DAYS.days.ago then
113                   @_have_old_quotes = true
114               end 
115           end
116       end
117   
118       public
120       # tell whether this Asset report includes outdated quotes
121       def have_old_quotes?
122           @_have_old_quotes
123       end
124   
125       # tell whether this Asset report is lacking quote data
126       def have_missing_quotes?
127           @_have_missing_quotes
128       end
129   end
131 end # module