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
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/>.
19 # Dividend received on a AssetPosition at some point in time.
22 # initialize with Smr::AssetPosition
23 def initialize (position)
24 raise 'position must be a Smr::AssetPosition' unless position.is_a?(Smr::AssetPosition)
26 @payments = query_payments
33 # Collection of DividendIncomeItem objects received.
36 # returns String describing the error when some methode returned False
42 # Returns total Dividend received, after tax and other costs.
45 @payments.each{|p| received += p.received_total }
54 # Add Dividend payment to this Position.
56 # :id_order should refer to the cash booking which represents the
57 # actually received amount (after tax and other costs).
58 def add_payment(paid, id_order, exdate=Time.now)
60 :exdate=>exdate.to_i, :paid=>paid, :id_order=>id_order,
61 :id_stock=>@position.id_stock, :id_position=>@position.id
68 # Queries eligible Dividend payments to create DividendIncomeItem collection.
73 # - pre 20150403195501_enhance_dividend.rb migration
74 # - slow because revisions must be looped!
75 Dividend.where(:id_stock=>@position.stock.id, :id_order=>0, :id_position=>0)
76 .where('exdate <= %i' % @position.date).each do |d|
77 @position.revisions.each do |pr|
78 payments[d.id] = Smr::DividendIncomeItem.new(d, :position_revision=>pr) if pr.date <= d.exdate
83 # - with received amount being a cash booking
84 Dividend.where(:id_position=>@position.id)
85 .where('exdate <= %i' % @position.date).order(exdate: :asc).each do |d|
86 payments[d.id] = Smr::DividendIncomeItem.new(d)
89 payments.compact! || Array.new
94 # Represents a single Dividend payment.
95 class DividendIncomeItem
97 # Time when the security traded ex-Dividend and when payment was received.
99 attr_reader :valutadate
101 # amount received per share and in total at :valutadate
102 attr_reader :received
103 attr_reader :received_total
105 # amount the company has paid at :exdate
108 # number of shares and invested amount of money at :exdate
110 attr_reader :invested
113 # Provide Dividend and, optionally, PositionRevision record to construct a payment.
114 def initialize(dividend, options={:position_revision=>false})
115 @exdate=dividend.time_exdate
117 @id_order=dividend.id_order
119 if options[:position_revision]
121 # - unaware of exdate vs. valutadate
122 # - unaware of paid bs. actually received
124 @shares=options[:position_revision].shares
125 @invested=options[:position_revision].invested
126 @received=dividend.paid
127 @received_total = @shares * @received
130 # - using cash booking
131 booking_rev = dividend.Order.PositionRevision.first
132 position_rev = PositionRevision
133 .where(:id_position=>dividend.id_position)
134 .where('date <= %i' % dividend.exdate)
137 @valutadate = booking_rev.time
138 @received_total = dividend.Order.volume
139 @shares = position_rev.shares
140 @invested = position_rev.invested
141 @received = @received_total / @shares
146 # tell whether there is a related Order available
152 # wrapper to cash booking order, use #has_order? first
154 Order.find(@id_order) if has_order?