Files
odoo_source/addons/gamification/models/res_users.py
T
David Beguin 9e082662af [IMP] gamification : add ranks based on karma
To encourage forum and slides users to be more active ranks are now added.
They are directly linked to karma. The more the user has karma the more his
rank will be high.

The default rank is Newbie, with 1 point of karma. Users with 0 karma are
considered as inactive on forum or slides. When a user reach a new rank
a mail is sent to him to congratulate him with his new rank.

To add a button in the mail template to allow users to go directly on
a website section (like forum or slides) simply override
get_gamification_redirection_data to add the target url.

Partial commit linked to eLearning project. Main specifications related
to gamification and user profile can be found on task 1922159 (PR #30514).
Main specifications related to eLearning can be found on task 1902304
(PR #29876).
2019-02-07 12:13:28 +00:00

90 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class Users(models.Model):
_inherit = 'res.users'
karma = fields.Integer('Karma', default=0)
badge_ids = fields.One2many('gamification.badge.user', 'user_id', string='Badges', copy=False)
gold_badge = fields.Integer('Gold badges count', compute="_get_user_badge_level")
silver_badge = fields.Integer('Silver badges count', compute="_get_user_badge_level")
bronze_badge = fields.Integer('Bronze badges count', compute="_get_user_badge_level")
rank_id = fields.Many2one('gamification.karma.rank', 'Rank', index=False)
next_rank_id = fields.Many2one('gamification.karma.rank', 'Next Rank', index=False)
@api.multi
@api.depends('badge_ids')
def _get_user_badge_level(self):
""" Return total badge per level of users
TDE CLEANME: shouldn't check type is forum ? """
for user in self:
user.gold_badge = 0
user.silver_badge = 0
user.bronze_badge = 0
self.env.cr.execute("""
SELECT bu.user_id, b.level, count(1)
FROM gamification_badge_user bu, gamification_badge b
WHERE bu.user_id IN %s
AND bu.badge_id = b.id
AND b.level IS NOT NULL
GROUP BY bu.user_id, b.level
ORDER BY bu.user_id;
""", [tuple(self.ids)])
for (user_id, level, count) in self.env.cr.fetchall():
# levels are gold, silver, bronze but fields have _badge postfix
self.browse(user_id)['{}_badge'.format(level)] = count
@api.model_create_multi
def create(self, values_list):
res = super(Users, self).create(values_list)
res._recompute_rank()
return res
@api.multi
def write(self, vals):
if 'karma' in vals:
self._recompute_rank()
return super(Users, self).write(vals)
@api.multi
def add_karma(self, karma):
for user in self:
user.karma += karma
return True
def _rank_changed(self):
if self.rank_id.karma_required > 0:
template = self.env.ref('gamification.mail_template_data_new_rank_reached', raise_if_not_found=False)
if template:
template.send_mail(self.id, force_send=True, notif_layout='mail.mail_notification_light')
def _recompute_rank(self):
"""
The caller should filter the users on karma > 0 before calling this method
to avoid looping on every single users
"""
ranks = [{'rank': rank, 'karma_required': rank.karma_required} for rank in
self.env['gamification.karma.rank'].search([], order="karma_required DESC")]
for user in self:
for i in range(0, len(ranks)):
if user.karma >= ranks[i]['karma_required']:
if user.rank_id != ranks[i]['rank']:
user.rank_id = ranks[i]['rank'].id
user.next_rank_id = ranks[i - 1]['rank'].id if i > 0 else False
user._rank_changed()
break
def get_gamification_redirection_data(self):
"""
Hook for other modules to add redirect button(s) in new rank reached mail
Must return a list of dictionnary including url and label.
E.g. return [{'url': '/forum', label: 'Go to Forum'}]
"""
self.ensure_one()
return []