From aefd64e8cfe41db54588dac2c50cf2a50316cc7a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 24 Dec 2013 14:00:23 +0100 Subject: [PATCH] [REF] gamification: compute_code is now similar to ir.actions, cleanup code bzr revid: mat@openerp.com-20131224130023-e4gc91ell38zdtfj --- addons/gamification/data/goal_base.xml | 2 +- addons/gamification/data/goal_definition.py | 9 ---- addons/gamification/models/goal.py | 49 +++++++++++++------ .../static/src/js/gamification.js | 45 +++++++---------- addons/gamification/views/challenge.xml | 6 +-- addons/gamification/views/goal.xml | 2 +- 6 files changed, 57 insertions(+), 56 deletions(-) diff --git a/addons/gamification/data/goal_base.xml b/addons/gamification/data/goal_base.xml index 48dd770bbcc..5da7b86679d 100644 --- a/addons/gamification/data/goal_base.xml +++ b/addons/gamification/data/goal_base.xml @@ -61,7 +61,7 @@ Mail Group Following Follow mail groups to receive news python - self.number_following(cr, uid, 'mail.group') + result = pool.get('mail.followers').search(cr, uid, [('res_model', '=', 'mail.group'), ('partner_id', '=', object.user_id.partner_id.id)], count=True, context=context) diff --git a/addons/gamification/data/goal_definition.py b/addons/gamification/data/goal_definition.py index 937168fc0a2..e16f2c7b11f 100644 --- a/addons/gamification/data/goal_definition.py +++ b/addons/gamification/data/goal_definition.py @@ -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) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 698d20d0159..8792e219d71 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -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 diff --git a/addons/gamification/static/src/js/gamification.js b/addons/gamification/static/src/js/gamification.js index 22cfd5f3ab5..2a8db5f369d 100644 --- a/addons/gamification/static/src/js/gamification.js +++ b/addons/gamification/static/src/js/gamification.js @@ -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({ diff --git a/addons/gamification/views/challenge.xml b/addons/gamification/views/challenge.xml index 973194738cd..3aa4410aaf2 100644 --- a/addons/gamification/views/challenge.xml +++ b/addons/gamification/views/challenge.xml @@ -101,9 +101,9 @@ -
-

Depending on the Diasplay mode, reports will be individual or shared.

-
+
+

Depending on the Display mode, reports will be individual or shared.

+
diff --git a/addons/gamification/views/goal.xml b/addons/gamification/views/goal.xml index d76b41882df..a269f710c02 100644 --- a/addons/gamification/views/goal.xml +++ b/addons/gamification/views/goal.xml @@ -244,7 +244,7 @@ - +