mirror of
https://github.com/bringout/oca-ocb-vertical-industry.git
synced 2026-04-21 07:12:04 +02:00
19.0 vanilla
This commit is contained in:
parent
4607ccbd2e
commit
825ff6514e
487 changed files with 184979 additions and 195262 deletions
|
|
@ -1,21 +1,49 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.tools import SQL
|
||||
|
||||
|
||||
class Users(models.Model):
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
karma = fields.Integer('Karma', default=0, copy=False)
|
||||
karma = fields.Integer('Karma', compute='_compute_karma', store=True, readonly=False)
|
||||
karma_tracking_ids = fields.One2many('gamification.karma.tracking', 'user_id', string='Karma Changes', groups="base.group_system")
|
||||
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')
|
||||
rank_id = fields.Many2one('gamification.karma.rank', 'Rank', index='btree_not_null')
|
||||
next_rank_id = fields.Many2one('gamification.karma.rank', 'Next Rank')
|
||||
|
||||
@api.depends('karma_tracking_ids.new_value')
|
||||
def _compute_karma(self):
|
||||
if self.env.context.get('skip_karma_computation'):
|
||||
# do not need to update the user karma
|
||||
# e.g. during the tracking consolidation
|
||||
return
|
||||
|
||||
self.env['gamification.karma.tracking'].flush_model()
|
||||
|
||||
select_query = """
|
||||
SELECT DISTINCT ON (user_id) user_id, new_value
|
||||
FROM gamification_karma_tracking
|
||||
WHERE user_id = ANY(%(user_ids)s)
|
||||
ORDER BY user_id, tracking_date DESC, id DESC
|
||||
"""
|
||||
self.env.cr.execute(select_query, {'user_ids': self.ids})
|
||||
|
||||
user_karma_map = {
|
||||
values['user_id']: values['new_value']
|
||||
for values in self.env.cr.dictfetchall()
|
||||
}
|
||||
|
||||
for user in self:
|
||||
user.karma = user_karma_map.get(user.id, 0)
|
||||
|
||||
self.sudo()._recompute_rank()
|
||||
|
||||
@api.depends('badge_ids')
|
||||
def _get_user_badge_level(self):
|
||||
""" Return total badge per level of users
|
||||
|
|
@ -40,37 +68,59 @@ class Users(models.Model):
|
|||
self.browse(user_id)['{}_badge'.format(level)] = count
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, values_list):
|
||||
res = super(Users, self).create(values_list)
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
|
||||
karma_trackings = []
|
||||
for user in res:
|
||||
if user.karma:
|
||||
karma_trackings.append({'user_id': user.id, 'old_value': 0, 'new_value': user.karma})
|
||||
if karma_trackings:
|
||||
self.env['gamification.karma.tracking'].sudo().create(karma_trackings)
|
||||
self._add_karma_batch({
|
||||
user: {
|
||||
'gain': int(vals['karma']),
|
||||
'old_value': 0,
|
||||
'origin_ref': f'res.users,{self.env.uid}',
|
||||
'reason': _('User Creation'),
|
||||
}
|
||||
for user, vals in zip(res, vals_list)
|
||||
if vals.get('karma')
|
||||
})
|
||||
|
||||
res._recompute_rank()
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
karma_trackings = []
|
||||
if 'karma' in vals:
|
||||
for user in self:
|
||||
if user.karma != vals['karma']:
|
||||
karma_trackings.append({'user_id': user.id, 'old_value': user.karma, 'new_value': vals['karma']})
|
||||
self._add_karma_batch({
|
||||
user: {
|
||||
'gain': int(vals['karma']) - user.karma,
|
||||
'origin_ref': f'res.users,{self.env.uid}',
|
||||
}
|
||||
for user in self
|
||||
if int(vals['karma']) != user.karma
|
||||
})
|
||||
return super().write(vals)
|
||||
|
||||
result = super(Users, self).write(vals)
|
||||
def _add_karma(self, gain, source=None, reason=None):
|
||||
self.ensure_one()
|
||||
values = {'gain': gain, 'source': source, 'reason': reason}
|
||||
return self._add_karma_batch({self: values})
|
||||
|
||||
if karma_trackings:
|
||||
self.env['gamification.karma.tracking'].sudo().create(karma_trackings)
|
||||
if 'karma' in vals:
|
||||
self._recompute_rank()
|
||||
return result
|
||||
def _add_karma_batch(self, values_per_user):
|
||||
if not values_per_user:
|
||||
return
|
||||
|
||||
def add_karma(self, karma):
|
||||
for user in self:
|
||||
user.karma += karma
|
||||
create_values = []
|
||||
for user, values in values_per_user.items():
|
||||
origin = values.get('source') or self.env.user
|
||||
reason = values.get('reason') or _('Add Manually')
|
||||
origin_description = f'{origin.display_name} #{origin.id}'
|
||||
old_value = values.get('old_value', user.karma)
|
||||
|
||||
create_values.append({
|
||||
'new_value': old_value + values['gain'],
|
||||
'old_value': old_value,
|
||||
'origin_ref': f'{origin._name},{origin.id}',
|
||||
'reason': f'{reason} ({origin_description})',
|
||||
'user_id': user.id,
|
||||
})
|
||||
|
||||
self.env['gamification.karma.tracking'].sudo().create(create_values)
|
||||
return True
|
||||
|
||||
def _get_tracking_karma_gain_position(self, user_domain, from_date=None, to_date=None):
|
||||
|
|
@ -90,49 +140,46 @@ class Users(models.Model):
|
|||
:param to_date: compute karma gained before this date (included) or until
|
||||
end of time;
|
||||
|
||||
:return list: [{
|
||||
'user_id': user_id (belonging to current record set),
|
||||
'karma_gain_total': integer, karma gained in the given timeframe,
|
||||
'karma_position': integer, ranking position
|
||||
}, {..}] ordered by karma_position desc
|
||||
:rtype: list[dict]
|
||||
:return:
|
||||
::
|
||||
|
||||
[{
|
||||
'user_id': user_id (belonging to current record set),
|
||||
'karma_gain_total': integer, karma gained in the given timeframe,
|
||||
'karma_position': integer, ranking position
|
||||
}, {..}]
|
||||
|
||||
ordered by descending karma position
|
||||
"""
|
||||
if not self:
|
||||
return []
|
||||
|
||||
where_query = self.env['res.users']._where_calc(user_domain)
|
||||
user_from_clause, user_where_clause, where_clause_params = where_query.get_sql()
|
||||
where_query = self.env['res.users']._search(user_domain, bypass_access=True)
|
||||
|
||||
params = []
|
||||
if from_date:
|
||||
date_from_condition = 'AND tracking.tracking_date::timestamp >= timestamp %s'
|
||||
params.append(from_date)
|
||||
if to_date:
|
||||
date_to_condition = 'AND tracking.tracking_date::timestamp <= timestamp %s'
|
||||
params.append(to_date)
|
||||
params.append(tuple(self.ids))
|
||||
|
||||
query = """
|
||||
sql = SQL("""
|
||||
SELECT final.user_id, final.karma_gain_total, final.karma_position
|
||||
FROM (
|
||||
SELECT intermediate.user_id, intermediate.karma_gain_total, row_number() OVER (ORDER BY intermediate.karma_gain_total DESC) AS karma_position
|
||||
FROM (
|
||||
SELECT "res_users".id as user_id, COALESCE(SUM("tracking".new_value - "tracking".old_value), 0) as karma_gain_total
|
||||
FROM %(user_from_clause)s
|
||||
FROM %s
|
||||
LEFT JOIN "gamification_karma_tracking" as "tracking"
|
||||
ON "res_users".id = "tracking".user_id AND "res_users"."active" = TRUE
|
||||
WHERE %(user_where_clause)s %(date_from_condition)s %(date_to_condition)s
|
||||
ON "res_users".id = "tracking".user_id AND "res_users"."active" IS TRUE
|
||||
WHERE %s %s %s
|
||||
GROUP BY "res_users".id
|
||||
ORDER BY karma_gain_total DESC
|
||||
) intermediate
|
||||
) final
|
||||
WHERE final.user_id IN %%s""" % {
|
||||
'user_from_clause': user_from_clause,
|
||||
'user_where_clause': user_where_clause or (not from_date and not to_date and 'TRUE') or '',
|
||||
'date_from_condition': date_from_condition if from_date else '',
|
||||
'date_to_condition': date_to_condition if to_date else ''
|
||||
}
|
||||
WHERE final.user_id IN %s""",
|
||||
where_query.from_clause,
|
||||
where_query.where_clause or SQL("TRUE"),
|
||||
SQL("AND tracking.tracking_date::DATE >= %s::DATE", from_date) if from_date else SQL(),
|
||||
SQL("AND tracking.tracking_date::DATE <= %s::DATE", to_date) if to_date else SQL(),
|
||||
tuple(self.ids),
|
||||
)
|
||||
|
||||
self.env.cr.execute(query, tuple(where_clause_params + params))
|
||||
self.env.cr.execute(sql)
|
||||
return self.env.cr.dictfetchall()
|
||||
|
||||
def _get_karma_position(self, user_domain):
|
||||
|
|
@ -148,32 +195,36 @@ WHERE final.user_id IN %%s""" % {
|
|||
:param user_domain: general domain (i.e. active, karma > 1, website, ...)
|
||||
to compute the absolute position of the current record set
|
||||
|
||||
:return list: [{
|
||||
'user_id': user_id (belonging to current record set),
|
||||
'karma_position': integer, ranking position
|
||||
}, {..}] ordered by karma_position desc
|
||||
:rtype: list[dict]
|
||||
:return:
|
||||
|
||||
::
|
||||
|
||||
[{
|
||||
'user_id': user_id (belonging to current record set),
|
||||
'karma_position': integer, ranking position
|
||||
}, {..}] ordered by karma_position desc
|
||||
"""
|
||||
if not self:
|
||||
return {}
|
||||
|
||||
where_query = self.env['res.users']._where_calc(user_domain)
|
||||
user_from_clause, user_where_clause, where_clause_params = where_query.get_sql()
|
||||
where_query = self.env['res.users']._search(user_domain, bypass_access=True)
|
||||
|
||||
# we search on every user in the DB to get the real positioning (not the one inside the subset)
|
||||
# then, we filter to get only the subset.
|
||||
query = """
|
||||
sql = SQL("""
|
||||
SELECT sub.user_id, sub.karma_position
|
||||
FROM (
|
||||
SELECT "res_users"."id" as user_id, row_number() OVER (ORDER BY res_users.karma DESC) AS karma_position
|
||||
FROM %(user_from_clause)s
|
||||
WHERE %(user_where_clause)s
|
||||
FROM %s
|
||||
WHERE %s
|
||||
) sub
|
||||
WHERE sub.user_id IN %%s""" % {
|
||||
'user_from_clause': user_from_clause,
|
||||
'user_where_clause': user_where_clause or 'TRUE',
|
||||
}
|
||||
|
||||
self.env.cr.execute(query, tuple(where_clause_params + [tuple(self.ids)]))
|
||||
WHERE sub.user_id IN %s""",
|
||||
where_query.from_clause,
|
||||
where_query.where_clause or SQL("TRUE"),
|
||||
tuple(self.ids),
|
||||
)
|
||||
self.env.cr.execute(sql)
|
||||
return self.env.cr.dictfetchall()
|
||||
|
||||
def _rank_changed(self):
|
||||
|
|
@ -290,10 +341,9 @@ WHERE sub.user_id IN %%s""" % {
|
|||
|
||||
if self.next_rank_id:
|
||||
return self.next_rank_id
|
||||
elif not self.rank_id:
|
||||
return self.env['gamification.karma.rank'].search([], order="karma_min ASC", limit=1)
|
||||
else:
|
||||
return self.env['gamification.karma.rank']
|
||||
domain = [('karma_min', '>', self.rank_id.karma_min)] if self.rank_id else []
|
||||
return self.env['gamification.karma.rank'].search(domain, order="karma_min ASC", limit=1)
|
||||
|
||||
def get_gamification_redirection_data(self):
|
||||
"""
|
||||
|
|
@ -303,3 +353,18 @@ WHERE sub.user_id IN %%s""" % {
|
|||
"""
|
||||
self.ensure_one()
|
||||
return []
|
||||
|
||||
def action_karma_report(self):
|
||||
self.ensure_one()
|
||||
|
||||
return {
|
||||
'name': _('Karma Updates'),
|
||||
'res_model': 'gamification.karma.tracking',
|
||||
'target': 'current',
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'list',
|
||||
'context': {
|
||||
'default_user_id': self.id,
|
||||
'search_default_user_id': self.id,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue