portrait Security and Organization records
[smr.git] / gui / app / controllers / cashflow_controller.rb
blobcebdd2f9592a7ea8cc5e65cdcf3ed9a92a6c73a7
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 'cashflowlog'
17 require 'cashflowforecast'
20 # see Smr::CashflowLog
21 class CashflowController < ApplicationController
23     ##
24     # shows cashflows in adjustable manner
25     def index
26         smr_menu_addsubitem('cashflow', {'+ dividend'=>:new_cashflow})
28         @filters = Smr::CashflowLog.filters.merge(Smr::CashflowForecast.filters)
29         @log = Array.new
30         @forecast = Array.new
32         # timeframes this report can work with
33         @timeframes = {
34             'This Month'   => :this_month,
35             'This Quarter' => :this_quarter,
36             'This Year'    => :this_year,
37             '3 Years'      => :three_years,
38             '5 Years'      => :five_years,
39             'All Time'     => :all_time,
40         }
42         # handle params
43         case params[:timeframe].to_s.to_sym
44             when :this_month
45                 report_start = smr_browse_date.beginning_of_month
46                 report_end = smr_browse_date.end_of_month
47             when :this_quarter
48                 report_start = smr_browse_date.beginning_of_quarter
49                 report_end = smr_browse_date.end_of_quarter
50             when :this_year
51                 report_start = smr_browse_date.beginning_of_year
52                 report_end = smr_browse_date.end_of_year
53             when :three_years
54                 report_start = (smr_browse_date - 3.years).beginning_of_year
55                 report_end = (smr_browse_date + 3.years).end_of_year
56             when :five_years
57                 report_start = (smr_browse_date - 5.years).beginning_of_year
58                 report_end = (smr_browse_date + 5.years).end_of_year
59             when :all_time
60                 report_start = Time.new(2000,1,1)
61                 report_end = (smr_browse_date + 100.years).end_of_year
62             else
63                 report_start = smr_browse_date.beginning_of_quarter
64                 report_end = smr_browse_date.end_of_quarter
65         end
66         @timeframe = params[:timeframe] || :this_quarter
67         @filter = if params[:filter] then filter_params else :none end
68         @portfolio = params[:portfolio] || 0
69         @portfolios = smr_portfolios_list
71         # make the log
72         if Smr::CashflowLog.filters.has_value? @filter
73             @log = Smr::CashflowLog.new(report_start, smr_browse_date, current_user.id)
74             @log.set_filter(@filter) if @log.filters.has_value? @filter
75             @log.set_portfolio(@portfolio) if @portfolio
76         end
78         # make the forecast
79         # - looking forward what @timeframe looks backwards
80         if Smr::CashflowForecast.filters.has_value? @filter
81             @forecast = Smr::CashflowForecast.new(smr_browse_date, report_end, current_user.id)
82             @forecast.set_filter(@filter)
83             @forecast.set_portfolio(@portfolio) if @portfolio
84         end
85     end
87     ##
88     # add new cashflows (right now Dividend only)
89     def new
90         self.index
91         if params[:id] then
92             @dividend = Dividend.where(:id=>params[:id]).first
93         else @dividend = Dividend.new(:time_exdate=>smr_browse_date) end
94         @positions = Smr::Asset.new(current_user.id, smr_browse_date, :skip_cash_positions=>true).open_positions
96         render :index
97     end
99     ##
100     # handles data creates and updates
101     #
102     # This method redirects differently depending on :params received. Ie its
103     # guessing whats the right thing of the moment. If guessing fails it
104     # redirects to #cashflow_index_path.
105     def create
106         exdate = params[:dividend][:time_exdate].to_time
107         valutadate = params[:valutadate].to_time
108         n = Array.new
110         # book received amount against cash (if we have shares)
111         ap = Smr::AssetPosition.new(params[:dividend][:id_position].to_i, current_user.id, exdate)
113         if  ap.shares == 0
114             n << 'can not book dividend because position holds no shares at ex-date'
115         else
116             apt = Smr::Transaction.new(ap, current_user)
117             cp = Smr::Transaction.new(apt.cash_position, current_user, :type=>:dividend_booking)
118             cp.book(params[:received].to_f * ap.shares, :time=>valutadate, :comment=>'from %s' % ap)
120             # create the dividend payment
121             d = Smr::DividendIncome.new(ap)
122             d.add_payment(
123                 params[:dividend][:paid].to_f,
124                 cp.order.id,
125                 exdate
126             )
127             n << d.error if d.error
129             # handle document
130             if params[:dividend][:document] then
131                 doc = Smr::UploadedFile.store(current_user.id, params[:dividend][:document])
132                 doc.assign(:order=>cp.order.id)
133             end
134         end
136         # handle redirection
137         return_path = case params[:redirect]
138             when 'position' then return_path = position_path(:id=>ap.id)
139         else cashflow_index_path end
140         redirect_to return_path, :flash=>{:notice=>n.join(', ')}
141     end
144  protected
146     ##
147     # internal helper defining parameters acceptable for Dividend create/update
148     def dividend_params
149         params.require(:dividend).permit(:id_position, :exdate, :paid)
150     end
152     ##
153     # internal helper defining parameters acceptable for filter specification
154     def filter_params
155       if @filters.has_value?(params[:filter].parameterize.to_sym) then
156             params[:filter].parameterize.to_sym
157       else
158             raise 'symbol "%s" is not accepted as filter' % params[:filter]
159       end
160     end