This commits avoid to call recompute when you write on the rank without touch the karma_min value. On write on karma_min, we have 2 cases: - Rank order are the same, just need to recompute the rank for the user that could be impacted. Eg. if karma_min changes from 45 to 50, we need to recheck for all user between 45 and 50 their new rank. - Rank order are not the same, we need to recompute for all users. (could be still improved if needed) When you recompute the rank on a list of users, depending of the number of users (bulk if more than 3 * number of rank) we check for each user what is the new rank, or for each rank whats is the new users. task-internal No way to edit a rank on the prod server. Lock sql -> crash server closes odoo/odoo#34835 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from werkzeug.exceptions import Forbidden
|
|
|
|
from odoo import api, tools, fields, models
|
|
from odoo.tools.translate import html_translate
|
|
|
|
|
|
class KarmaError(Forbidden):
|
|
""" Karma-related error, used for forum and posts. """
|
|
pass
|
|
|
|
|
|
class KarmaRank(models.Model):
|
|
_name = 'gamification.karma.rank'
|
|
_description = 'Rank based on karma'
|
|
_order = 'karma_min'
|
|
|
|
name = fields.Text(string='Rank Name', translate=True, required=True)
|
|
description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False,)
|
|
description_motivational = fields.Html(
|
|
string='Motivational', translate=html_translate, sanitize_attributes=False,
|
|
help="Motivational phrase to reach this rank")
|
|
karma_min = fields.Integer(string='Required Karma', help='Minimum karma needed to reach this rank')
|
|
user_ids = fields.One2many('res.users', 'rank_id', string='Users', help="Users having this rank")
|
|
image = fields.Binary('Rank Icon')
|
|
image_medium = fields.Binary(
|
|
"Medium-sized rank icon",
|
|
help="Medium-sized icon of the rank. It is automatically "
|
|
"resized as a 128x128px image, with aspect ratio preserved. "
|
|
"Use this field in form views or some kanban views.")
|
|
image_small = fields.Binary(
|
|
"Small-sized rank icon",
|
|
help="Small-sized icon of the rank. It is automatically "
|
|
"resized as a 64x64px image, with aspect ratio preserved. "
|
|
"Use this field anywhere a small image is required.")
|
|
|
|
@api.model_create_multi
|
|
def create(self, values_list):
|
|
for vals in values_list:
|
|
tools.image_resize_images(vals)
|
|
res = super(KarmaRank, self).create(values_list)
|
|
users = self.env['res.users'].sudo().search([('karma', '>', 0)])
|
|
users._recompute_rank()
|
|
return res
|
|
|
|
@api.multi
|
|
def write(self, vals):
|
|
if 'karma_min' in vals:
|
|
previous_ranks = self.env['gamification.karma.rank'].search([], order="karma_min DESC").ids
|
|
low = min(vals['karma_min'], self.karma_min)
|
|
high = max(vals['karma_min'], self.karma_min)
|
|
|
|
tools.image_resize_images(vals)
|
|
res = super(KarmaRank, self).write(vals)
|
|
|
|
if 'karma_min' in vals:
|
|
after_ranks = self.env['gamification.karma.rank'].search([], order="karma_min DESC").ids
|
|
if previous_ranks != after_ranks:
|
|
users = self.env['res.users'].sudo().search([('karma', '>', 0)])
|
|
else:
|
|
users = self.env['res.users'].sudo().search([('karma', '>=', low), ('karma', '<=', high)])
|
|
users._recompute_rank()
|
|
return res
|