[REF] gamification: compute_code is now similar to ir.actions, cleanup code

bzr revid: mat@openerp.com-20131224130023-e4gc91ell38zdtfj
This commit is contained in:
Martin Trigaux 2013-12-24 14:00:23 +01:00
parent 6f5815f44d
commit aefd64e8cf
6 changed files with 57 additions and 56 deletions

View File

@ -61,7 +61,7 @@
<field name="name">Mail Group Following</field>
<field name="description">Follow mail groups to receive news</field>
<field name="computation_mode">python</field>
<field name="compute_code">self.number_following(cr, uid, 'mail.group')</field>
<field name="compute_code">result = pool.get('mail.followers').search(cr, uid, [('res_model', '=', 'mail.group'), ('partner_id', '=', object.user_id.partner_id.id)], count=True, context=context)</field>
<field name="action_id" eval="ref('mail.action_view_groups')" />
</record>

View File

@ -30,12 +30,3 @@ class gamification_goal_definition_data(osv.Model):
of a user's goal. The return definition must be a float or integer.
"""
_inherit = 'gamification.goal.definition'
def number_following(self, cr, uid, xml_id="mail.thread", context=None):
"""Return the number of 'xml_id' objects the user is following
The model specified in 'xml_id' must inherit from mail.thread
"""
ref_obj = self.pool.get(xml_id)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return ref_obj.search(cr, uid, [('message_follower_ids', '=', user.partner_id.id)], count=True, context=context)

View File

@ -25,9 +25,9 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from openerp.tools.safe_eval import safe_eval
from openerp.tools.translate import _
from datetime import date, datetime, timedelta
import logging
import time
from datetime import date, datetime, timedelta
_logger = logging.getLogger(__name__)
@ -75,7 +75,6 @@ class gamification_goal_definition(osv.Model):
required=True),
'display_mode': fields.selection([
('progress', 'Progressive (using numerical values)'),
('checkbox', 'Checkbox (done or not-done)'),
('boolean', 'Exclusive (done or not-done)'),
],
string="Displayed as", required=True),
@ -91,8 +90,8 @@ class gamification_goal_definition(osv.Model):
'domain': fields.char("Filter Domain",
help="Domain for filtering records. The rule can contain reference to 'user' that is a browse record of the current user, e.g. [('user_id', '=', user.id)].",
required=True),
'compute_code': fields.char('Compute Code',
help="The name of the python method that will be executed to compute the current value. See the file gamification/goal_definition_data.py for examples."),
'compute_code': fields.text('Python Code',
help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id."),
'condition': fields.selection([
('higher', 'The higher the better'),
('lower', 'The lower the better')
@ -114,6 +113,15 @@ class gamification_goal_definition(osv.Model):
'display_mode': 'progress',
}
def number_following(self, cr, uid, model_name="mail.thread", context=None):
"""Return the number of 'model_name' objects the user is following
The model specified in 'model_name' must inherit from mail.thread
"""
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return self.pool.get('mail.followers').search(cr, uid, [('res_model', '=', model_name), ('partner_id', '=', user.partner_id.id)], count=True, context=context)
class gamification_goal(osv.Model):
"""Goal instance for a user
@ -221,6 +229,8 @@ class gamification_goal(osv.Model):
If a goal reaches the target value, the status is set to reached
If the end date is passed (at least +1 day, time not considered) without
the target value being reached, the goal is set as failed."""
if context is None:
context = {}
for goal in self.browse(cr, uid, ids, context=context):
towrite = {}
@ -233,14 +243,25 @@ class gamification_goal(osv.Model):
elif goal.definition_id.computation_mode == 'python':
# execute the chosen method
values = {'cr': cr, 'uid': goal.user_id.id, 'context': context, 'self': self.pool.get('gamification.goal.definition')}
result = safe_eval(goal.definition_id.compute_code, values, {})
if type(result) in (float, int, long) and result != goal.current:
towrite['current'] = result
cxt = {
'self': self.pool.get('gamification.goal'),
'object': goal,
'pool': self.pool,
'cr': cr,
'context': dict(context), # copy context to prevent side-effects of eval
'uid': uid,
'result': False,
'date': date, 'datetime': datetime, 'timedelta': timedelta, 'time': time
}
code = goal.definition_id.compute_code.strip()
safe_eval(code, cxt, mode="exec", nocopy=True)
# the result of the evaluated codeis put in the 'result' local variable, propagated to the context
result = cxt.get('result', False)
if result and type(result) in (float, int, long):
if result != goal.current:
towrite['current'] = result
else:
_logger.exception(_('Unvalid return content from the evaluation of %s' % str(goal.definition_id.compute_code)))
# raise osv.except_osv(_('Error!'), _('Unvalid return content from the evaluation of %s' % str(goal.definition_id.compute_code)))
_logger.exception(_('Invalid return content from the evaluation of %s' % code))
else: # count or sum
obj = self.pool.get(goal.definition_id.model_id.model)
@ -249,7 +270,7 @@ class gamification_goal(osv.Model):
# eval the domain with user replaced by goal user object
domain = safe_eval(goal.definition_id.domain, {'user': goal.user_id})
#add temporal clause(s) to the domain if fields are filled on the goal
# add temporal clause(s) to the domain if fields are filled on the goal
if goal.start_date and field_date_name:
domain.append((field_date_name, '>=', goal.start_date))
if goal.end_date and field_date_name:
@ -263,7 +284,7 @@ class gamification_goal(osv.Model):
else: # computation mode = count
new_value = obj.search(cr, uid, domain, context=context, count=True)
#avoid useless write if the new value is the same as the old one
# avoid useless write if the new value is the same as the old one
if new_value != goal.current:
towrite['current'] = new_value

View File

@ -7,9 +7,9 @@ openerp.gamification = function(instance) {
var self = this;
this._super(parent, action);
this.deferred = $.Deferred();
// this.res_user = new instance.web.DataSetSearch(this, 'res.users');
this.goals_info = {};
this.challenge_suggestions = {};
$(document).off('keydown.klistener');
},
events: {
// update a challenge and related goals
@ -49,6 +49,21 @@ openerp.gamification = function(instance) {
self.get_goal_todo_info();
});
});
},
'click .oe_goal h4': function(event) {
var self = this;
this.kkeys = [];
$(document).on('keydown.klistener', function(event) {
if ("37,38,39,40,65,66".indexOf(event.keyCode) < 0) {
$(document).off('keydown.klistener');
} else {
self.kkeys.push(event.keyCode);
if (self.kkeys.toString().indexOf("38,38,40,40,37,39,37,39,66,65") >= 0) {
new instance.web.Model('gamification.badge').call('check_progress', []);
$(document).off('keydown.klistener');
}
}
});
}
},
start: function() {
@ -63,6 +78,7 @@ openerp.gamification = function(instance) {
if (result.length === 0) {
self.$el.find(".oe_gamification_challenge_list").hide();
} else {
self.$el.find(".oe_gamification_challenge_list").empty();
_.each(result, function(item){
var $item = $(QWeb.render("gamification.ChallengeSummary", {challenge: item}));
self.render_money_fields($item);
@ -115,34 +131,7 @@ openerp.gamification = function(instance) {
this._super();
var sidebar = new instance.gamification.Sidebar(this);
sidebar.appendTo($('.oe_mail_wall_aside'));
}
});
instance.web_kanban.KanbanView.include({
start: function() {
this._super();
$(document).off('keydown.klistener');
},
events: {
'click': function(event) {
var self = this;
if (this.ViewManager.dataset.model === 'gamification.badge') {
this.kkeys = [];
$(document).off('keydown.klistener');
$(document).on('keydown.klistener', function(event) {
if ("37,38,39,40,65,66".indexOf(event.keyCode) < 0) {
$(document).off('keydown.klistener');
} else {
self.kkeys.push(event.keyCode);
if (self.kkeys.toString().indexOf("38,38,40,40,37,39,37,39,66,65") >= 0) {
new instance.web.Model('gamification.badge').call('check_progress', []);
$(document).off('keydown.klistener');
}
}
});
}
}
}
});
instance.web_kanban.KanbanRecord.include({

View File

@ -101,9 +101,9 @@
<field name="invited_user_ids" widget="many2many_tags" />
</group>
<group string="Notification Messages">
<div class="oe_grey">
<p>Depending on the Diasplay mode, reports will be individual or shared.</p>
</div>
<div class="oe_grey" colspan="4">
<p>Depending on the Display mode, reports will be individual or shared.</p>
</div>
<field name="report_message_frequency" />
<field name="report_header" placeholder="e.g. The following message contains the current progress of the sale team..." attrs="{'invisible': [('report_message_frequency','=','never')]}" />
<field name="report_message_group_id" attrs="{'invisible': [('report_message_frequency','=','never')]}" />

View File

@ -244,7 +244,7 @@
<field name="field_id" attrs="{'invisible':[('computation_mode','!=','sum')], 'required':[('computation_mode','=','sum')]}" domain="[('model_id','=',model_id)]" class="oe_inline"/>
<field name="field_date_id" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))]}" domain="[('ttype', 'in', ('date', 'datetime')), ('model_id','=',model_id)]" class="oe_inline"/>
<field name="domain" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}" class="oe_inline"/>
<field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}" placeholder="e.g. self.my_method(cr, uid)"/>
<field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}" placeholder="e.g. result = pool.get('mail.followers').search(cr, uid, [('res_model', '=', 'mail.group'), ('partner_id', '=', object.user_id.partner_id.id)], count=True, context=context)"/>
<field name="condition" widget="radio"/>
</group>
<group string="Formating Options">