reworked dividend
[smr.git] / gui / lib / smr / uploaded_file.rb
blobc544c628f12bf580243e0a027141d8422aba1b8a
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   
17 module Smr  #:nodoc:
18   ##
19   # A UploadedFile with relations to Portfolio, Position, Order and/or Stock.
20   #
21   # == Security
22   # For the sake of security its required to supply id of User that is used to
23   # make sure the requested document does belong to that user. The +id_user+
24   # parameter should <b>not</b> come from user input, but rather result from a
25   # successful authentication process.
26   #
27   
28   # == Attention
29   # - right now this is only for viewing perposes
30   # - to store new data records use the model classes directly. These are
31   #   Document, DocumentData and DocumentAssign.
32   #
33   class UploadedFile
34     ##
35     # initialize with Document id and User id
36     def initialize(id_document, id_user)
37         @id = id_document
38         @id_user = id_user
39   
40         @document = Document.where(:id=>@id, :id_user=>@id_user).limit(1).first
41     end
42   
43     public
44   
45     def id
46         @document.id
47     end
48   
49     ##
50     # returns Document.time_upload
51     def time_upload
52         @document.time_upload
53     end
54   
55     def comment
56         @document.comment
57     end
58   
59     def filename
60         @document.filename
61     end
62   
63     def size
64         @document.size
65     end
66   
67     def mimetype
68         @document.mimetype
69     end
70   
71     def has_relations?
72         if DocumentAssign.where(:id_document=>@id, :is_assigned=>1).count > 0 then return true
73         else return false end
74     end
75   
76     ##
77     # tell whether a Document record was found
78     def empty?
79         not @document.is_a?(Document)
80     end
81   
82     ##
83     # return human readable string of relations of this document
84     #
85     # TODO: make link to each relation
86     def relations_text
87         rel = DocumentAssign.where(:id_document=>@id, :is_assigned=>1).first
88         t = Array.new
89   
90         return nil unless rel
91   
92         t << 'security %s' % rel.Stock.name if rel.id_stock
93         t << 'order #%i' % rel.id_order if rel.id_order
94         t << 'portfolio %s' % rel.Portfolio.name if rel.id_portfolio
95         t << 'position %s held at %s' % [rel.Position.Stock.name, rel.Position.Portfolio.name] if rel.id_position
96         
97         return 'related to ' + t.join(', ')
98     end
99   
100     ##
101     # return Portfolio object(s) if any were assigned
102     # FIXME: not yet implemented
103     def portfolio
104         true
105     end
106   
107     ##
108     # return Position object(s) if any were assigned
109     # FIXME: not yet implemented
110     def position
111         true
112     end
113   
114     ##
115     # return Order object(s) if any were assigned
116     # FIXME: not yet implemented
117     def order
118         true
119     end
120   
121     ##
122     # return Stock object(s) if any were assigned
123     # FIXME: not yet implemented
124     def stock
125         true
126     end
127   
128     ##
129     # return BLOB (binary large object) data of that document
130     def data
131         DocumentData.where(:id_document=>@id).first.content
132     end
133   
134     ##
135     # assigns this document to an Order, a Position, a Stock or a Portfolio.
136     #
137     # Give a symbol and the id that should be assigned. Like
138     # +assign(:order=>5)+ or more than on with +assign(:order=>6,
139     # :position=>3)+.
140     #
141     # Unassign by specifying zero, ie +assign(:order=>0)+.
142     def assign(assignments = {})
143         da = DocumentAssign.find_by_id_document(@id) || DocumentAssign.new(:id_document=>@id, :is_assigned=>1)
144   
145         return false if assignments.empty?
146   
147         da.id_order = assignments[:order] if assignments[:order]; da.id_order=nil if assignments[:order] == 0
148         da.id_position = assignments[:position] if assignments[:position]; da.id_position=nil if assignments[:position] == 0
149         da.id_portfolio = assignments[:portfolio] if assignments[:portfolio]; da.id_portfolio=nil if assignments[:portfolio] == 0
150         da.id_stock = assignments[:stock] if assignments[:stock]; da.id_stock=nil if assignments[:stock] == 0
151   
152         da.save!
153     end
155     ##
156     # Make new Smr::UploadedFile from POSTed data.
157     #
158     # This creates the records which can later be viewed as Smr::UploadedFile. On
159     # success it will return a new Smr::UploadedFile based on the new records.  
160     # - +upload_time+ should be of class Time
161     # - +file+ is expected to be of class ActionDispatch::Http::UploadedFile.
162     #
163     # NOTE: this is a class method, not an instance method!
164     def self.store(id_user, file, comment='', upload_time=Time.now)
165         raise 'file must be of ActionDispatch::Http::UploadedFile' unless file.is_a?(ActionDispatch::Http::UploadedFile)
166         d = Document.new(
167             :id_user=>id_user,
168             :date_upload=>upload_time.to_i,
169             :size=>file.size,
170             :mimetype=>file.content_type,
171             :filename=>file.original_filename,
172             :comment=>comment
173         )
174         d.save!
175         DocumentData.new(:id_document=>d.id, :content=>file.read).save!
176         return UploadedFile.new(d.id, id_user)
177     end
178   end
179   
180   ##
181   # Collection of UploadedFile objects owned by a given user.
182   #
183   # Optionally only those related to :id_position.
184   #
185   # == Security
186   # The +id_user+ parameter should <b>not</b> come from user input, but rather
187   # result from a successful authentication process.
188   class UploadedFiles < Array
189     ##
190     # provide +Time+ date and SQL statement as string.
191     def initialize(id_user, id_position=false)
192         @docids = Document.select(:id).where(:id_user=>id_user).order(date_upload: :desc)
194         if id_position
195             @docids = @docids.joins(:DocumentAssign).where(document_assign: { id_position: id_position })
196         end
198         @docids.each { |id| push(UploadedFile.new(id, id_user)) }
199         compact!
200     end
201   end
202   
203 end # module