diff --git a/addons/gamification/models/badge.py b/addons/gamification/models/badge.py index 099176dc88f..4f11c4192f0 100644 --- a/addons/gamification/models/badge.py +++ b/addons/gamification/models/badge.py @@ -43,10 +43,37 @@ class gamification_badge_user(osv.Model): 'comment': fields.text('Comment'), 'badge_name': fields.related('badge_id', 'name', type="char", string="Badge Name"), 'create_date': fields.datetime('Created', readonly=True), - 'create_uid': fields.many2one('res.users', 'Creator', readonly=True), + 'create_uid': fields.many2one('res.users', string='Creator', readonly=True), } + def _send_badge(self, cr, uid, ids, user_from=False, context=None): + """Send a notification to a user for receiving a badge + + Does not verify constrains on badge granting. + The users are added to the owner_ids (create badge_user if needed) + The stats counters are incremented + :param ids: list(int) of badge users that will receive the badge + :param user_from: optional id of the res.users object that has sent the badge + """ + res = True + temp_obj = self.pool.get('email.template') + user_obj = self.pool.get('res.users') + template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_badge_received', context) + ctx = context.copy() + for badge_user in self.browse(cr, uid, ids, context=context): + + ctx.update({'user_from': user_obj.browse(cr, uid, user_from).name}) + body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.badge.user', badge_user.id, context=ctx) + + res = user_obj.message_post(cr, uid, badge_user.user_id.id, body=body_html, context=context) + return res + + def create(self, cr, uid, vals, context=None): + self.pool.get('gamification.badge').check_granting(cr, uid, badge_id=vals.get('badge_id'), context=context) + return super(gamification_badge_user, self).create(cr, uid, vals, context=context) + + class gamification_badge(osv.Model): """Badge object that users can send and receive""" @@ -96,7 +123,7 @@ class gamification_badge(osv.Model): """ 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: + if self._can_grant_badge(cr, uid, badge.id, context) != 1: # if the user cannot grant this badge at all, result is 0 result[badge.id] = 0 elif not badge.rule_max: @@ -183,37 +210,13 @@ class gamification_badge(osv.Model): 'rule_auth': 'everyone', } - def send_badge(self, cr, uid, badge_id, badge_user_ids, user_from=False, context=None): - """Send a notification to a user for receiving a badge + def check_granting(self, cr, uid, badge_id, context=None): + """Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception + if not - Does NOT verify constrains on badge granting. - The users are added to the owner_ids (create badge_user if needed) - The stats counters are incremented - :param badge_id: id of the badge to deserve - :param badge_user_ids: list(int) of badge users that will receive the badge - :param user_from: optional id of the res.users object that has sent the badge + Do not check for SUPERUSER_ID """ - badge = self.browse(cr, uid, badge_id, context=context) - # template_env = TemplateHelper() - - res = None - temp_obj = self.pool.get('email.template') - template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_badge_received', context) - ctx = context.copy() - for badge_user in self.pool.get('gamification.badge.user').browse(cr, uid, badge_user_ids, context=context): - - ctx.update({'user_from': self.pool.get('res.users').browse(cr, uid, user_from).name}) - - body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.badge.user', badge_user.id, context=ctx) - - # as SUPERUSER as normal user don't have write access on a badge - res = self.message_post(cr, SUPERUSER_ID, badge.id, partner_ids=[badge_user.user_id.partner_id.id], body=body_html, type='comment', subtype='mt_comment', context=context) - return res - - def check_granting(self, cr, uid, user_from_id, badge_id, context=None): - """Check the user 'user_from_id' can grant the badge 'badge_id' and raise the appropriate exception - if not""" - status_code = self._can_grant_badge(cr, uid, user_from_id, badge_id, context=context) + status_code = self._can_grant_badge(cr, uid, badge_id, context=context) if status_code == 1: return True elif status_code == 2: @@ -228,10 +231,10 @@ class gamification_badge(osv.Model): _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): + def _can_grant_badge(self, cr, uid, 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 uid: the id of the res.users trying to send the badge :param badge_id: the granted badge id :return: integer representing the permission. 1: can grant @@ -240,16 +243,19 @@ class gamification_badge(osv.Model): 4: don't have the required badges 5: user's monthly limit reached """ + if uid == SUPERUSER_ID: + return 1 + badge = self.browse(cr, uid, badge_id, context=context) if badge.rule_auth == 'nobody': return 2 - elif badge.rule_auth == 'users' and user_from_id not in [user.id for user in badge.rule_auth_user_ids]: + elif badge.rule_auth == 'users' and uid not in [user.id for user in badge.rule_auth_user_ids]: return 3 elif badge.rule_auth == 'having': - all_user_badges = self.pool.get('gamification.badge.user').search(cr, uid, [('user_id', '=', user_from_id)], context=context) + all_user_badges = self.pool.get('gamification.badge.user').search(cr, uid, [('user_id', '=', uid)], context=context) for required_badge in badge.rule_auth_badge_ids: if required_badge.id not in all_user_badges: return 4 diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py index 4d34fe7b640..0f3e64626cb 100644 --- a/addons/gamification/models/challenge.py +++ b/addons/gamification/models/challenge.py @@ -732,9 +732,14 @@ class gamification_challenge(osv.Model): return (sorted_challengers[0]['user'], sorted_challengers[1]['user'], sorted_challengers[2]['user']) def reward_user(self, cr, uid, user_id, badge_id, context=None): - """Create a badge user and send the badge to him""" - user_badge_id = self.pool.get('gamification.badge.user').create(cr, uid, {'user_id': user_id, 'badge_id': badge_id}, context=context) - return self.pool.get('gamification.badge').send_badge(cr, uid, badge_id, [user_badge_id], user_from=None, context=context) + """Create a badge user and send the badge to him + + :param user_id: the user to reward + :param badge_id: the concerned badge + """ + badge_user_obj = self.pool.get('gamification.badge.user') + user_badge_id = badge_user_obj.create(cr, uid, {'user_id': user_id, 'badge_id': badge_id}, context=context) + return badge_user_obj._send_badge(cr, uid, [user_badge_id], user_from=None, context=context) class gamification_challenge_line(osv.Model): diff --git a/addons/gamification/views/badge.xml b/addons/gamification/views/badge.xml index f0ee1a8423d..33c0e21ea7a 100644 --- a/addons/gamification/views/badge.xml +++ b/addons/gamification/views/badge.xml @@ -56,6 +56,9 @@ +
+ Security rules to define who is allowed to manually grant badges. Not enforced for administrator. +
diff --git a/addons/gamification/wizard/grant_badge.py b/addons/gamification/wizard/grant_badge.py index 725512a55bb..e100b2dce29 100644 --- a/addons/gamification/wizard/grant_badge.py +++ b/addons/gamification/wizard/grant_badge.py @@ -43,16 +43,13 @@ class grant_badge_wizard(osv.TransientModel): if uid == wiz.user_id.id: raise osv.except_osv(_('Warning!'), _('You can not grant a badge to yourself')) - #check if the badge granting is legitimate - if badge_obj.check_granting(cr, uid, user_from_id=uid, badge_id=wiz.badge_id.id, context=context): - #create the badge - values = { - 'user_id': wiz.user_id.id, - 'badge_id': wiz.badge_id.id, - 'comment': wiz.comment, - } - badge_user = badge_user_obj.create(cr, uid, values, context=context) - #notify the user - result = badge_obj.send_badge(cr, uid, wiz.badge_id.id, [badge_user], user_from=uid, context=context) + #create the badge + values = { + 'user_id': wiz.user_id.id, + 'badge_id': wiz.badge_id.id, + 'comment': wiz.comment, + } + badge_user = badge_user_obj.create(cr, uid, values, context=context) + result = badge_obj._send_badge(cr, uid, badge_user, user_from=uid, context=context) return result diff --git a/addons/hr_gamification/wizard/grant_badge.py b/addons/hr_gamification/wizard/grant_badge.py index 95efe444114..539781216e1 100644 --- a/addons/hr_gamification/wizard/grant_badge.py +++ b/addons/hr_gamification/wizard/grant_badge.py @@ -48,18 +48,13 @@ class hr_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.check_granting(cr, uid, - user_from_id=uid, - badge_id=wiz.badge_id.id, - context=context): + values = { + 'user_id': wiz.user_id.id, + 'badge_id': wiz.badge_id.id, + 'employee_id': wiz.employee_id.id, + 'comment': wiz.comment, + } - values = { - 'user_id': wiz.user_id.id, - 'badge_id': wiz.badge_id.id, - 'employee_id': wiz.employee_id.id, - 'comment': wiz.comment, - } - badge_user = badge_user_obj.create(cr, uid, values, context=context) - - result = badge_obj.send_badge(cr, uid, wiz.badge_id.id, [badge_user], user_from=uid, context=context) + badge_user = badge_user_obj.create(cr, uid, values, context=context) + result = badge_obj.send_badge(cr, uid, wiz.badge_id.id, [badge_user], user_from=uid, context=context) return result \ No newline at end of file