From 252365095a18b71ac0912ca2bc3f5262ffdd87b8 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 12 Apr 2013 10:54:52 +0200 Subject: [PATCH] [IMP] better badge views and checks bzr revid: mat@openerp.com-20130412085452-mnecqo80cgmo2ecs --- addons/gamification/badge.py | 68 ++++++++++++++++--- addons/gamification/badge_view.xml | 57 ++++++++++++---- addons/gamification/goal.py | 3 - addons/gamification/static/src/css/goal.css | 10 ++- .../static/src/js/gamification.js | 2 +- addons/hr_gamification/badge.py | 3 +- 6 files changed, 110 insertions(+), 33 deletions(-) diff --git a/addons/gamification/badge.py b/addons/gamification/badge.py index a681caa6ecf..3872c4362a2 100644 --- a/addons/gamification/badge.py +++ b/addons/gamification/badge.py @@ -26,6 +26,9 @@ from openerp.tools.safe_eval import safe_eval from templates import TemplateHelper from datetime import date +import logging + +_logger = logging.getLogger(__name__) class gamification_badge_user(osv.Model): @@ -130,6 +133,24 @@ class gamification_badge(osv.Model): ('create_date', '>=', first_month_day)], context=context)) return result + def _remaining_sending_calc(self, cr, uid, ids, name, args, context=None): + """Computes the number of badges remaining the user can send + + 0 if not allowed or no remaining + integer if limited sending + -1 if infinite (should not be displayed) + """ + result = dict.fromkeys(ids, False) + for badge in self.browse(cr, uid, ids, context=context): + if self.can_grant_badge(cr, uid, uid, badge.id, context) != 1: + result[badge.id] = 0 + elif not badge.rule_max: + result[badge.id] = -1 + else: + result[badge.id] = badge.rule_max_number - badge.stat_my_monthly_sending + + return result + _columns = { 'name': fields.char('Badge', required=True, translate=True), 'description': fields.text('Description'), @@ -161,6 +182,8 @@ class gamification_badge(osv.Model): type="integer", string='My Monthly Sending Total', help="The number of time the current user has sent this badge this month."), + 'remaining_sending': fields.function(_remaining_sending_calc, type='integer', + string='Remaining Sending Allowed', help="If a maxium is set"), 'rule_automatic': fields.selection([ ('goals', 'List of goals to reach'), @@ -338,22 +361,46 @@ class gamification_badge(osv.Model): return True + def check_granting(self, cr, uid, user_from_id, badge_id, context=None): + """Check the user can grant a badge and raise the appropriate exception + if not""" + context = context or {} + status_code = self.can_grant_badge(cr, uid, user_from_id, badge_id, context) + if status_code == 1: + return True + elif status_code == 2: + raise osv.except_osv(_('Warning!'), _('This badge can not be sent by users.')) + elif status_code == 3: + raise osv.except_osv(_('Warning!'), _('You are not in the user allowed list.')) + elif status_code == 4: + raise osv.except_osv(_('Warning!'), _('You do not have the required badges.')) + elif status_code == 5: + raise osv.except_osv(_('Warning!'), _('You have already sent this badge too many time this month.')) + else: + _logger.exception("Unknown badge status code: %d" % int(status_code)) + return False + def can_grant_badge(self, cr, uid, user_from_id, badge_id, context=None): """Check if a user can grant a badge to another user :param user_from_id: the id of the res.users trying to send the badge :param badge_id: the granted badge id - :return: boolean, True if succeeded to send, False otherwise + :return: integer representing the permission. + 1: can grant + 2: nobody can send + 3: user not in the allowed list + 4: don't have the required badges + 5: user's monthly limit reached """ context = context or {} badge = self.browse(cr, uid, badge_id, context=context) if badge.rule_auth == 'nobody': - raise osv.except_osv(_('Warning!'), _('This badge can not be sent by users.')) + return 2 - elif badge.rule_auth == 'list': + elif badge.rule_auth == 'users': if user_from_id not in [user.id for user in badge.rule_auth_user_ids]: - raise osv.except_osv(_('Warning!'), _('You are not in the user allowed list.')) + return 3 elif badge.rule_auth == 'having': badge_users = self.pool.get('gamification.badge.user').search( @@ -361,23 +408,24 @@ class gamification_badge(osv.Model): if len(badge_users) == 0: # the user_from has no badges - raise osv.except_osv(_('Warning!'), _('You do not have the required badges.')) + return 4 owners = [owner.id for owner in badge.owner_ids] granted = False for badge_user in badge_users: - if badge_user.id in owners: + if badge_user in owners: granted = True + break if not granted: - raise osv.except_osv(_('Warning!'), _('You do not have the required badges.')) + return 4 # else badge.rule_auth == 'everyone' -> no check if badge.rule_max and badge.stat_my_monthly_sending >= badge.rule_max_number: # sent the maximum number of time this month - raise osv.except_osv(_('Warning!'), _('You have already sent this badge too many time this month.')) + return 5 - return True + return 1 class grant_badge_wizard(osv.TransientModel): @@ -400,7 +448,7 @@ class grant_badge_wizard(osv.TransientModel): if uid == wiz.user_id.id: raise osv.except_osv(_('Warning!'), _('You can not send a badge to yourself')) - if badge_obj.can_grant_badge(cr, uid, + if badge_obj.check_granting(cr, uid, user_from_id=uid, badge_id=wiz.badge_id.id, context=context): diff --git a/addons/gamification/badge_view.xml b/addons/gamification/badge_view.xml index a590308cc5f..84fbbd14c68 100644 --- a/addons/gamification/badge_view.xml +++ b/addons/gamification/badge_view.xml @@ -93,8 +93,16 @@ - - +