[IMP]: idea: Usability Improvement in idea module.

bzr revid: atp@tinyerp.co.in-20100514095428-g7svp99hdr1j6buc
This commit is contained in:
atp (Open ERP) 2010-05-14 15:24:28 +05:30
parent 55d7925b31
commit 8c48b03822
6 changed files with 168 additions and 168 deletions

View File

@ -20,6 +20,7 @@
##############################################################################
from osv import osv, fields
import time
VoteValues = [('-1', 'Not Voted'), ('0', 'Very Bad'), ('25', 'Bad'), \
('50', 'Normal'), ('75', 'Good'), ('100', 'Very Good') ]
@ -90,26 +91,6 @@ class idea_idea(osv.osv):
cr.execute(sql, (ids,))
return dict(cr.fetchall())
def _comment_count(self, cr, uid, ids, name, arg, context=None):
""" count number of comment
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of comments IDs
@return: dictionay of Idea """
if not ids:
return {}
sql = """SELECT i.id, COUNT(1)
FROM idea_idea i LEFT OUTER JOIN idea_comment c ON i.id = c.idea_id
WHERE i.id = ANY(%s)
GROUP BY i.id
"""
cr.execute(sql, (ids,))
return dict(cr.fetchall())
def _vote_read(self, cr, uid, ids, name, arg, context = None):
""" Read Vote
@ -149,18 +130,15 @@ class idea_idea(osv.osv):
vote_obj.create(cr, uid, {'idea_id': id, 'user_id': uid, 'score': textual_value })
_columns = {
'user_id': fields.many2one('res.users', 'Creator', required=True, readonly=True),
'user_id': fields.many2one('res.users', 'Responsible', required=True, readonly=True),
'title': fields.char('Idea Summary', size=64, required=True),
'description': fields.text('Description', required=True, help='Content of the idea'),
'comment_ids': fields.one2many('idea.comment', 'idea_id', 'Comments'),
'create_date': fields.datetime('Creation date', readonly=True),
'vote_ids': fields.one2many('idea.vote', 'idea_id', 'Vote'),
'created_date': fields.datetime('Date'),
'vote_ids': fields.one2many('idea.vote', 'idea_id', 'Vote', readonly=True),
'my_vote': fields.function(_vote_read, fnct_inv = _vote_save, \
string="My Vote", method=True, type="selection", selection=VoteValues),
'vote_avg': fields.function(_vote_avg_compute, method=True, string="Average Score", type="float"),
'count_votes': fields.function(_vote_count, method=True, string="Count of votes", type="integer"),
'count_comments': fields.function(_comment_count, method=True, \
string="Count of comments", type="integer"),
'category_id': fields.many2one('idea.category', 'Category', required=True),
'state': fields.selection([('draft', 'Draft'), ('open', 'Opened'), \
('close', 'Accepted'), ('cancel', 'Cancelled')], \
@ -169,8 +147,7 @@ class idea_idea(osv.osv):
opened by the user, the state is \'Opened\'.\
\nIf the idea is accepted, the state is \'Accepted\'.'),
'stat_vote_ids': fields.one2many('idea.vote.stat', 'idea_id', 'Statistics', readonly=True),
'date': fields.date('Creation date'),
'vote_user': fields.integer('Maximum Vote per User',
'vote_limit': fields.integer('Maximum Vote per User',
help="Set to one if you require only one Vote per user"),
}
@ -178,7 +155,8 @@ class idea_idea(osv.osv):
'user_id': lambda self,cr,uid,context: uid,
'my_vote': lambda *a: '-1',
'state': lambda *a: 'draft',
'vote_user': lambda * a: 1,
'vote_limit': lambda * a: 1,
'created_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
_order = 'id desc'
@ -199,29 +177,6 @@ class idea_idea(osv.osv):
return True
idea_idea()
class idea_comment(osv.osv):
""" Apply Idea for Comment """
_name = 'idea.comment'
_description = 'Comments'
_rec_name = 'content'
_columns = {
'idea_id': fields.many2one('idea.idea', 'Idea', required=True, ondelete='cascade'),
'user_id': fields.many2one('res.users', 'User', required=True),
'content': fields.text('Comment', required=True),
'create_date': fields.datetime('Creation date', readonly=True),
}
_defaults = {
'user_id': lambda self, cr, uid, context: uid
}
_order = 'id desc'
idea_comment()
class idea_vote(osv.osv):
""" Apply Idea for Vote """
@ -230,12 +185,15 @@ class idea_vote(osv.osv):
_rec_name = 'score'
_columns = {
'user_id': fields.many2one('res.users', 'User'),
'idea_id': fields.many2one('idea.idea', 'Idea', required=True, ondelete='cascade'),
'score': fields.selection(VoteValues, 'Score', required=True),
'user_id': fields.many2one('res.users', 'By user', readonly="True"),
'idea_id': fields.many2one('idea.idea', 'Idea', readonly="True", ondelete='cascade'),
'score': fields.selection(VoteValues, 'Vote Status', readonly="True"),
'date': fields.datetime('Date', readonly="True"),
'comment': fields.text('Comment', readonly="True"),
}
_defaults = {
'score': lambda *a: DefaultVoteValue,
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
idea_vote()

View File

@ -47,10 +47,10 @@
id="base.menu_lunch_survey_root" sequence="6"/>
<menuitem name="Ideas" parent="base.menu_lunch_survey_root" id="menu_ideas"/>
<menuitem name="Categories" parent="menu_ideas"
id="menu_idea_category" action="action_idea_category" />
<!-- Idea Category Action -->
<record model="ir.actions.act_window" id="action_idea_category_tree">
@ -61,13 +61,18 @@
</record>
<menuitem name="Ideas" parent="base.menu_tools" id="menu_ideas1" sequence="4"/>
<menuitem
name="Ideas by Categories" parent="menu_ideas1"
id="menu_idea_category_tree"
action="action_idea_category_tree"/>
<menuitem name="Give Vote" parent="menu_ideas1"
id="menu_give_vote"
action="action_idea_select"/>
<!-- Oepn Ideas Action -->
<!-- Open Ideas Action -->
<record model="ir.actions.act_window" id="action_idea_idea_categ_open">
<field name="name">Open Ideas</field>
@ -108,9 +113,9 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Votes">
<field name="idea_id"/>
<field name="user_id"/>
<field name="score" />
<field name="user_id" />
<field name="score"/>
<field name="date"/>
</tree>
</field>
</record>
@ -123,9 +128,14 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Votes">
<field name="idea_id" select="1" />
<field name="user_id" select="1" />
<field name="score"/>
<group colspan="4">
<field name="user_id" select="1" />
<field name="date"/>
<newline/>
<field name="score"/>
</group>
<separator string="Comments:" colspan="4"/>
<field name="comment" colspan="4" nolabel="1"/>
</form>
</field>
</record>
@ -144,6 +154,7 @@
</group>
<newline/>
<group expand="1" string="Group By..." colspan="14">
<filter string="Vote date" icon="terp-crm" domain="[]" context="{'group_by':'date'}"/>
<filter string="Idea" icon="terp-crm" domain="[]" context="{'group_by':'idea_id'}"/>
<filter string="User" name="user" icon="terp-partner" domain="[]" context="{'group_by':'user_id'}"/>
</group>
@ -159,37 +170,25 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="New Idea">
<notebook>
<page string="Idea">
<field name="title" select="1" />
<field name="category_id" select="1"/>
<field name="date" />
<field name="user_id" select="1"/>
<field name="vote_avg" widget="progressbar"/>
<field name="vote_user"/>
<separator string="Description" colspan="4"/>
<field name="description" colspan="4" widget="text_wiki" nolabel="1"/>
<field name="state"/>
<group colspan="2" col="3">
<button name="idea_open" string="Open" states="draft" icon="gtk-go-forward"/>
<button name="idea_close" string="Close" states="open" icon="gtk-close" groups="base.group_extended"/>
<button name="idea_cancel" string="Cancel" states="open" icon="gtk-cancel" groups="base.group_extended"/>
</group>
</page>
<page string="Comments">
<field name="comment_ids" nolabel="1" colspan="4">
<form string="Comment">
<field name="user_id" colspan="2"/>
<separator string="User comment" colspan="4"/>
<field name="content" nolabel="1" colspan="4"/>
</form>
</field>
</page>
<page string="Vote">
<field name="vote_ids" nolabel="1" colspan="4" />
</page>
<page string="Statistics">
<field name="stat_vote_ids" colspan="4" mode="graph,tree" nolabel="1">
<group colspan="4" col="6">
<field name="title" select="1"/>
<field name="created_date" />
<field name="user_id" select="1"/>
<newline/>
<field name="category_id" select="1"/>
<field name="vote_avg" widget="progressbar"/>
<field name="vote_limit"/>
</group>
<notebook colspan="4">
<page string="Notes">
<separator string="Description" colspan="4"/>
<field name="description" nolabel="1"/>
</page>
<page string="Votes">
<field name="vote_ids" nolabel="1" colspan="4" />
</page>
<page string="Statistics">
<field name="stat_vote_ids" colspan="4" mode="graph,tree" nolabel="1">
<graph string="vote_stat of ideas" type="bar">
<field name="score"/>
<field name="nbr"/>
@ -199,8 +198,17 @@
<field name="nbr"/>
</tree>
</field>
</page>
</notebook>
</page>
</notebook>
<group colspan="4" col="6">
<field name="state"/>
<button name="idea_open" string="Open" states="draft" icon="gtk-go-forward"/>
<button name="idea_close" string="Close" states="open" icon="gtk-close" groups="base.group_extended"/>
<button name="idea_cancel" string="Cancel" states="open" icon="gtk-cancel" groups="base.group_extended"/>
<button name="%(action_idea_post_vote)d"
icon="gtk-execute" type="action" states="draft,open"
string="Give vote" />
</group>
</form>
</field>
</record>
@ -213,12 +221,11 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="All Ideas">
<field name="category_id" />
<field name="create_date"/>
<field name="user_id" />
<field name="title"/>
<field name="title"/>
<field name="category_id"/>
<field name="user_id"/>
<field name="created_date"/>
<field name="vote_avg" />
<field name="count_comments" />
<field name="count_votes" />
<button name="%(action_idea_post_vote)d" icon="gtk-execute"
type="action" states="draft,open" string="Vote" />
@ -251,30 +258,13 @@
<filter string="Category" icon="terp-crm" domain="[]" context="{'group_by':'category_id'}"/>
<filter string="State" icon="terp-crm" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Idea date" icon="terp-crm" domain="[]" context="{'group_by':'date'}"/>
<filter string="Vote date" icon="terp-crm" domain="[]" context="{'group_by':'created_date'}"/>
<filter string="User" name="user" icon="terp-partner" domain="[]" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
</record>
<!-- Comments on Idea Tree View -->
<record model="ir.ui.view" id="view_idea_comment_tree">
<field name="name">idea.comment.tree</field>
<field name="model">idea.comment</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Comments">
<field name="create_date" />
<field name="user_id" />
<field name="content" string="Comment" />
</tree>
</field>
</record>
<!-- Idea Action -->
<record model="ir.actions.act_window" id="action_idea_idea">
<field name="name">Ideas</field>
<field name="res_model">idea.idea</field>

View File

@ -1,7 +1,6 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_idea_category","idea.category","model_idea_category","base.group_user",1,0,0,0
"access_idea_idea","idea.idea","model_idea_idea","base.group_user",1,1,1,1
"access_idea_comment","idea.comment","model_idea_comment","base.group_user",1,1,1,1
"access_idea_vote","idea.vote","model_idea_vote","base.group_user",1,1,1,1
"access_idea_vote_stat","idea.vote.stat","model_idea_vote_stat","base.group_user",1,0,0,0
"access_idea_category_system","idea.category system","model_idea_category","base.group_system",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_idea_category idea.category model_idea_category base.group_user 1 0 0 0
3 access_idea_idea idea.idea model_idea_idea base.group_user 1 1 1 1
access_idea_comment idea.comment model_idea_comment base.group_user 1 1 1 1
4 access_idea_vote idea.vote model_idea_vote base.group_user 1 1 1 1
5 access_idea_vote_stat idea.vote.stat model_idea_vote_stat base.group_user 1 0 0 0
6 access_idea_category_system idea.category system model_idea_category base.group_system 1 1 1 1

View File

@ -8,10 +8,10 @@
name: Technical
- |
I create a New Idea of "Technical presentation for 1 hours in every day" and specify category "Technical".
-
!record {model: idea.idea, id: idea_idea_0}:
category_id: idea_category_technical0
created_date: '05/13/2010 19:16:26'
description: I want that Technical presentation are arranged for 1 hours in every
day.\nso, on that presentation, we can know all things what improvement and development
are done in our company.\n\n\n\n\n
@ -50,31 +50,34 @@
- |
In order to post vote I connect as user1 and open the idea page
I click on "Vote" wizard and vote the idea as "Normal"
I click on "Give Vote" wizard button and vote the idea as "Normal"
-
!record {model: idea.post.vote, id: idea_post_vote_0}:
vote: 50
- |
Now I click on "Post Vote" button of wizard.
Now I click on "Post" button of this wizard.
-
!python {model: idea.post.vote}: |
uid = ref('res_users_user0')
self.do_vote(cr, uid, [ref("idea_post_vote_0")], {'active_id': ref('idea_idea_0')})
self.do_vote(cr, uid, [ref("idea_post_vote_0")], {'active_ids': [ref('idea_idea_0')]})
- |
To add other vote I connect as user2 and open the idea page
I click on "Vote" wizard and vote the idea as "Very Good"
I click on "Give Vote" wizard and vote the idea as "Very Good" and put comment "We can learn many things from technical presentation".
-
!record {model: idea.post.vote, id: idea_post_vote_1}:
vote: 100
content: We can learn many things from technical presentation
- |
I click on "Post Vote" button of this wizard.
I click on "Post" button of this wizard.
-
!python {model: idea.post.vote}: |
uid = ref('res_users_user1')
self.do_vote(cr, uid, [ref("idea_post_vote_1")], {'active_id': ref('idea_idea_0')})
self.do_vote(cr, uid, [ref("idea_post_vote_1")], {'active_ids': [ref('idea_idea_0')]})
- |
I can see that the Average score changed in "Average score" field with value 75
@ -82,14 +85,6 @@
!record {model: idea.idea, id: idea_idea_0}:
vote_avg: 75
- |
I put one comment "We can learn many things from technical presentation" for the idea.
-
!record {model: idea.idea, id: idea.idea_idea_0}:
comment_ids:
- content: We can learn many things from technical presentation
idea_id: idea.idea_idea_0
user_id: res_users_user1
- |
I connect as Manager and close this idea by click on "Close" button.
-

View File

@ -34,7 +34,7 @@ class idea_post_vote(osv.osv_memory):
('25', 'Bad'),
('50', 'Normal'),
('75', 'Good'),
('100', 'Very Good') ], 'Post Vote', required=True),
('100', 'Very Good') ], 'Give Vote', required=True),
'content': fields.text('Comment'),
}
@ -48,25 +48,22 @@ class idea_post_vote(osv.osv_memory):
@param context: A standard dictionary for contextual values
"""
idea_obj = self.pool.get('idea.idea')
for idea in idea_obj.browse(cr, uid, context.get('active_ids', [])):
cr.execute('select count(id) from idea_vote where user_id=%s\
and idea_id=%s' % (uid, context.get('active_id')))
res = cr.fetchone()[0]
user_limit = idea.vote_user
if res >= user_limit:
for active_id in context.get('active_ids'):
cr.execute('select count(id) from idea_vote where user_id=%s\
and idea_id=%s' % (uid, active_id))
res = cr.fetchone()[0]
user_limit = idea.vote_limit
if res >= user_limit:
raise osv.except_osv(_('Warning !'),_("You can not give Vote for this idea more than %s times") % (user_limit))
if idea.state in ['draft', 'close', 'cancel']:
raise osv.except_osv(_("Warning !"), _("Draft/Accepted/Cancelled \
ideas Could not be voted"))
if idea.state != 'open':
raise osv.except_osv(_('Warning !'), _('idea should be in \
raise osv.except_osv(_('Warning !'), _('Idea should be in \
\'Open\' state before vote for that idea.'))
return False
def do_vote(self, cr, uid, ids, context):
def do_vote(self, cr, uid, ids, context=None):
"""
Create idea vote.
@ -75,21 +72,56 @@ ideas Could not be voted"))
@param ids: List of Idea Post votes IDs.
@return: Dictionary {}
"""
data = context and context.get('active_id', False) or False
data = context and context.get('active_ids', []) or []
vote_obj = self.pool.get('idea.vote')
comment_obj = self.pool.get('idea.comment')
for do_vote_obj in self.read(cr, uid, ids):
score = str(do_vote_obj['vote'])
comment = do_vote_obj['content']
dic = {'idea_id': data, 'user_id': uid, 'score': score}
if comment:
comment_id = comment_obj.create(cr, uid, {'idea_id': data, 'user_id': uid, 'content': comment})
vote = vote_obj.create(cr, uid, dic)
for id in data:
dic = {'idea_id': id, 'user_id': uid, 'score': score, 'comment': comment}
vote = vote_obj.create(cr, uid, dic)
return {}
idea_post_vote()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
class idea_select(osv.osv_memory):
""" Select idea for vote."""
_name = "idea.select"
_description = "select idea"
_columns = {
'idea_id': fields.many2one('idea.idea', 'Idea', required=True),
}
def open_vote(self, cr, uid, ids, context=None):
"""
This function load column.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of load column,
@return: dictionary of query logs clear message window
"""
idea_obj = self.browse(cr, uid, ids)
for idea in idea_obj:
idea_id = idea.idea_id.id
data_obj = self.pool.get('ir.model.data')
id2 = data_obj._get_id(cr, uid, 'idea', 'view_idea_post_vote')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
value = {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'idea.post.vote',
'views': [(id2, 'form'), (False, 'tree'), (False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'target': 'new',
'context': {'active_ids': [idea_id]}
}
return value
idea_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -9,8 +9,9 @@
<field name="model">idea.post.vote</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create Tasks">
<form string="Give Vote">
<group colspan="4" >
<separator colspan="4" string="Give Vote for Idea"/>
<field name="vote"/>
<separator string="Comment" colspan="4"/>
<field name="content" colspan="4" nolabel="1"/>
@ -18,8 +19,29 @@
<separator string="" colspan="4"/>
<group colspan="4" col="6">
<label string="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-ok" name="do_vote" string="Post Vote" type="object"/>
<button icon="gtk-cancel" special="cancel" string="Close"/>
<button icon="gtk-apply" name="do_vote" string="Post" type="object"/>
</group>
</form>
</field>
</record>
<record id="view_idea_select" model="ir.ui.view">
<field name="name">idea.select.form</field>
<field name="model">idea.select</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Select Idea for Vote">
<group colspan="4" >
<separator string="Select Idea for Vote" colspan="4"/>
<field name="idea_id"/>
</group>
<separator string="" colspan="4"/>
<group colspan="4" col="6">
<label string="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Close"/>
<button icon="gtk-go-forward" name="open_vote" string="Next" type="object"/>
</group>
</form>
</field>
@ -36,12 +58,16 @@
<field name="target">new</field>
</record>
<!-- Post Idea for vote Action Window -->
<act_window id="action_idea_post_vote_values"
key2="client_action_multi" name="vote"
res_model="idea.post.vote" src_model="idea.idea"
view_mode="form" target="new" view_type="form" />
<record id="action_idea_select" model="ir.actions.act_window">
<field name="name">Idea select</field>
<field name="res_model">idea.select</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_idea_select"/>
<field name="target">new</field>
<field name="context">{'model': 'idea.idea'}</field>
</record>
</data>
</openerp>