added from extra-addons
[odoo/odoo.git] / addons / idea / idea.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 # Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 #                   Fabien Pinckaers <fp@tiny.Be>
6 #
7 # WARNING: This program as such is intended to be used by professional
8 # programmers who take the whole responsability of assessing all potential
9 # consequences resulting from its eventual inadequacies and bugs
10 # End users who are looking for a ready-to-use solution with commercial
11 # garantees and support are strongly adviced to contract a Free Software
12 # Service Company
13 #
14 # This program is Free Software; you can redistribute it and/or
15 # modify it under the terms of the GNU General Public License
16 # as published by the Free Software Foundation; either version 2
17 # of the License, or (at your option) any later version.
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 # GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 #
28 ##############################################################################
29
30 from osv import osv, fields
31
32 VoteValues = [('-1','Not Voted'),('0','Very Bad'),('25', 'Bad'),('50','Normal'),('75','Good'),('100','Very Good') ]
33 DefaultVoteValue = '50'
34
35 class idea_category(osv.osv):
36     _name = "idea.category"
37     _description = "Category for an idea"
38     _columns = {
39         'name': fields.char('Category', size=64, required=True),
40         'summary': fields.text('Summary'),
41         'parent_id': fields.many2one('idea.category','Parent Categories', ondelete='set null'),
42         'child_ids': fields.one2many('idea.category','parent_id','Child Categories')
43     }
44     _sql_constraints = [
45         ('name', 'unique(parent_id,name)', 'The name of the category must be unique' )
46     ]
47     _order = 'parent_id,name asc'
48 idea_category()
49
50 class idea_idea(osv.osv):
51     _name = 'idea.idea'
52     _rec_name = 'title'
53
54     def _vote_avg_compute(self, cr, uid, ids, name, arg, context = None):
55         if not len(ids):
56             return {}
57
58         sql = """select i.id, avg(v.score::integer) 
59                    from idea_idea i left outer join idea_vote v on i.id = v.idea_id
60                     where i.id in (%s)
61                     group by i.id
62                 """ % ','.join(['%d']*len(ids))
63
64         cr.execute(sql, ids)
65         return dict(cr.fetchall())
66
67     def _vote_count(self,cr,uid,ids,name,arg,context=None):
68         if not len(ids):
69             return {}
70
71         sql = """select i.id, count(1) 
72                    from idea_idea i left outer join idea_vote v on i.id = v.idea_id
73                     where i.id in (%s)
74                     group by i.id
75                 """ % ','.join(['%d']*len(ids))
76
77         cr.execute(sql, ids)
78         return dict(cr.fetchall())
79
80     def _comment_count(self,cr,uid,ids,name,arg,context=None):
81         if not len(ids):
82             return {}
83
84         sql = """select i.id, count(1) 
85                    from idea_idea i left outer join idea_comment c on i.id = c.idea_id
86                     where i.id in (%s)
87                     group by i.id
88                 """ % ','.join(['%d']*len(ids))
89
90
91         cr.execute(sql,ids)
92         return dict(cr.fetchall())
93
94     def _vote_read(self, cr, uid, ids, name, arg, context = None):
95         res = {}
96         for id in ids:
97             res[id] = '-1'
98         vote_obj = self.pool.get('idea.vote')
99         votes_ids = vote_obj.search(cr, uid, [('idea_id', 'in', ids), ('user_id', '=', uid)])
100         for vote in vote_obj.browse(cr, uid, votes_ids, context):
101             res[vote.idea_id.id] = vote.score
102         return res
103
104     def _vote_save(self, cr, uid, id, field_name, field_value, arg, context = None):
105         vote_obj = self.pool.get('idea.vote')
106         vote = vote_obj.search(cr,uid,[('idea_id', '=', id),('user_id', '=', uid)])
107         textual_value = str(field_value)
108         if vote:
109             if int(field_value)>=0:
110                 vote_obj.write(cr,uid, vote, { 'score' : textual_value })
111             else:
112                 vote_obj.unlink(cr,uid, vote)
113         else:
114             if int(field_value)>=0:
115                 vote_obj.create(cr,uid, { 'idea_id' : id, 'user_id' : uid, 'score' : textual_value })
116
117
118     _columns = {
119         'user_id': fields.many2one('res.users', 'Creator', required=True, readonly=True),
120         'title': fields.char('Idea Summary', size=64, required=True),
121         'description': fields.text('Description', required=True, help='Content of the idea'),
122         'comment_ids': fields.one2many('idea.comment', 'idea_id', 'Comments'),
123         'create_date' : fields.datetime( 'Creation date', readonly=True),
124         'vote_ids' : fields.one2many('idea.vote', 'idea_id', 'Vote'),
125         'my_vote' : fields.function(_vote_read, fnct_inv = _vote_save, string="My Vote", method=True, type="selection", selection=VoteValues),
126         'vote_avg' : fields.function(_vote_avg_compute, method=True, string="Average Score", type="float"),
127         'count_votes' : fields.function(_vote_count, method=True, string="Count of votes", type="integer"),
128         'count_comments': fields.function(_comment_count, method=True, string="Count of comments", type="integer"),
129         'category_id': fields.many2one('idea.category', 'Category', required=True ),
130         'state': fields.selection([('draft','Draft'),('open','Opened'),('close','Accepted'),('cancel','Canceled')], 'State', readonly=True),
131         'stat_vote_ids': fields.one2many('idea.vote.stat', 'idea_id', 'Statistics', readonly=True),
132     }
133
134     _defaults = {
135         'user_id': lambda self,cr,uid,context: uid,
136         'my_vote': lambda *a: '-1', 
137         'state': lambda *a: 'draft'
138     }
139     _order = 'id desc'
140
141     def idea_cancel(self, cr, uid, ids):
142         self.write(cr, uid, ids, { 'state' : 'cancel' })
143         return True
144
145     def idea_open(self, cr, uid, ids):
146         self.write(cr, uid, ids, { 'state' : 'open' })
147         return True
148
149     def idea_close(self, cr, uid, ids):
150         self.write(cr, uid, ids, { 'state' : 'close' })
151         return True
152
153     def idea_draft(self, cr, uid, ids):
154         self.write(cr, uid, ids, { 'state' : 'draft' })
155         return True
156 idea_idea()
157
158 class idea_comment(osv.osv):
159     _name = 'idea.comment'
160     _description = 'Comments'
161     _rec_name = 'content'
162     _columns = {
163         'idea_id': fields.many2one('idea.idea', 'Idea', required=True, ondelete='cascade' ),
164         'user_id': fields.many2one('res.users', 'User', required=True ),
165         'content': fields.text( 'Comment', required=True ),
166         'create_date' : fields.datetime( 'Creation date', readonly=True),
167     }
168     _defaults = {
169         'user_id': lambda self, cr, uid, context: uid
170     }
171     _order = 'id desc'
172 idea_comment()
173
174 class idea_vote(osv.osv):
175     _name = 'idea.vote'
176     _rec_name = 'score'
177     _columns = {
178         'user_id': fields.many2one( 'res.users', 'User'),
179         'idea_id': fields.many2one('idea.idea', 'Idea', required=True, ondelete='cascade'),
180         'score': fields.selection( VoteValues, 'Score', required=True)
181     }
182     _defaults = {
183         'score': lambda *a: DefaultVoteValue,
184     }
185 idea_vote()
186
187 class idea_vote_stat(osv.osv):
188     _name = 'idea.vote.stat'
189     _description = 'Idea Votes Statistics'
190     _auto = False
191     _rec_name = 'idea_id'
192     _columns = {
193         'idea_id': fields.many2one('idea.idea', 'Idea', readonly=True),
194         'score': fields.selection( VoteValues, 'Score', readonly=True),
195         'nbr': fields.integer('Number of Votes', readonly=True),
196     }
197     def init(self, cr):
198         """
199         initialize the sql view for the stats
200         
201         cr -- the cursor
202         """
203         cr.execute("""
204             create or replace view idea_vote_stat as (
205                 select
206                     min(v.id) as id,
207                     i.id as idea_id,
208                     v.score,
209                     count(1) as nbr
210                 from
211                     idea_vote v
212                     left join 
213                     idea_idea i on (v.idea_id=i.id)
214                 group by
215                     i.id, v.score, i.id
216         )""")
217 idea_vote_stat()
218
219 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
220