manage bookmarks, bugfixes
[smr.git] / gui / lib / smr / cashflowitem.rb
blobf9ca103c33b03d41bd8c36e9b7d199cf279b76c7
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/>.
18 # Represents a single item of cashflow. Useful for viewing.
19 class Smr::CashflowItem
20     include Comparable
22     ##
23     # Reader for given attribute, see #new
24     attr_reader :date
25     attr_reader :what
26     attr_reader :amount_per_share
27     attr_reader :poolfactor
28     attr_reader :comment
29     attr_reader :type
31     # number of shares (or face value) that produced this cashflow item
32     attr_writer :shares
34     # Smr::Link to whatever has created this item, may be false
35     attr_accessor :link
37     ##
38     # A piece of cashflow at a specific time.
39     #
40     # By default its for a single share. But can be scaled by using
41     # #shares=X.Y or specifying options[:shares].
42     #
43     # Note options[:poolfactor]. This is also applied. Make sure to set it
44     # correctly if one existed at :date.
45     #
46     # Pass a Smr::Link in via :link option to make use of the #link method.
47     def initialize(date, what, amount_per_share, options={})
48       raise ':date must be Time' unless date.is_a? Time
49       raise ':amount_per_share must be Integer, Float or Percentage' unless [Integer, Float, Percentage].include? amount_per_share.class
51       options.reverse_update({
52           :comment=>nil, :type=>false, :poolfactor=>1.0, :shares=>1.0,
53           :link=>false,
54       })
56       @date=date
57       @what=what
58       @amount_per_share=amount_per_share
59       @options = options
60       @comment = options[:comment]
61       @shares = options[:shares]
62       @type = options[:type]
63       @link = options[:link]
65       @poolfactor = options[:poolfactor]
66       @lock_poolfactor = false
67     end
69     ##
70     # Human readable description of #type.
71     def describe_type
72       PositionRevision.describe_type(@options[:type]) if PositionRevision.types.include?(@options[:type])
73     end
75     ##
76     # Human readable representation of this item.
77     def to_s
78       '%s: %-25.24s %10.4f (pf=%4.2f)' % [date, describe_type, total, @poolfactor]
79     end
81     ##
82     # Absolute amount of cashflow.
83     #
84     # It is scaled to #shares and the :poolfactor is applied unless its a
85     # redemption payment which causes the poolfactor to shrink in most cases.
86     def total
87       @lock_poolfactor = true
88       if @type == :redemption_booking
89           @shares * @amount_per_share
90       else @shares * @amount_per_share * poolfactor end
91     end
93     ##
94     # Compares items by :date, then by :total amount
95     def <=>(other)
96       comp = (date <=> other.date)
97       if comp.zero? then (total <=> other.total) else comp end
98     end
100     ##
101     # Adjust :poolfactor to some other value.
102     # Works only once and not at all after #total has been called!
103     def adjust_poolfactor(value)
104       raise '#adjust_poolfactor should never be called twice, check algorithm.' if @lock_poolfactor
105       @lock_poolfactor = true
106       @poolfactor = value
107     end