PURPOSE Allow karma gain tracking enabling notably display of top users based on weekly / monthly gain in website profile. SPECIFCIATIONS Each time a user gains karma a record is created in the gamification karma tracking model. Scheduled activity runs to consolidate the records into monthly gain records to avoid having crowdy table and unnecessary noise in karma gain. This model is made private and only accessible through some dedicated compute methods / controllers used in website profile. In website profile module buttons are added to see users ranking based on their total karma (like before) but also by last week and last month gains (using the newly introduced tracking model). LINKS Task ID 2003505 PR #34594
70 lines
2.8 KiB
Python
70 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import calendar
|
|
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class KarmaTracking(models.Model):
|
|
_name = 'gamification.karma.tracking'
|
|
_description = 'Track Karma Changes'
|
|
_rec_name = 'user_id'
|
|
_order = 'tracking_date DESC'
|
|
|
|
user_id = fields.Many2one('res.users', 'User', index=True, readonly=True, required=True, ondelete='cascade')
|
|
old_value = fields.Integer('Old Karma Value', required=True, readonly=True)
|
|
new_value = fields.Integer('New Karma Value', required=True, readonly=True)
|
|
consolidated = fields.Boolean('Consolidated')
|
|
tracking_date = fields.Date(default=fields.Date.context_today)
|
|
|
|
@api.model
|
|
def _consolidate_last_month(self):
|
|
""" Consolidate last month. Used by a cron to cleanup tracking records. """
|
|
previous_month_start = fields.Date.today() + relativedelta(months=-1, day=1)
|
|
return self._process_consolidate(previous_month_start)
|
|
|
|
def _process_consolidate(self, from_date):
|
|
""" Consolidate trackings into a single record for a given month, starting
|
|
at a from_date (included). End date is set to last day of current month
|
|
using a smart calendar.monthrange construction. """
|
|
end_date = from_date + relativedelta(day=calendar.monthrange(from_date.year, from_date.month)[1])
|
|
select_query = """
|
|
SELECT user_id,
|
|
(
|
|
SELECT old_value from gamification_karma_tracking old_tracking
|
|
WHERE old_tracking.user_id = gamification_karma_tracking.user_id
|
|
AND tracking_date::timestamp BETWEEN %(from_date)s AND %(to_date)s
|
|
AND consolidated IS NOT TRUE
|
|
ORDER BY tracking_date ASC LIMIT 1
|
|
), (
|
|
SELECT new_value from gamification_karma_tracking new_tracking
|
|
WHERE new_tracking.user_id = gamification_karma_tracking.user_id
|
|
AND tracking_date::timestamp BETWEEN %(from_date)s AND %(to_date)s
|
|
AND consolidated IS NOT TRUE
|
|
ORDER BY tracking_date DESC LIMIT 1
|
|
)
|
|
FROM gamification_karma_tracking
|
|
WHERE tracking_date::timestamp BETWEEN %(from_date)s AND %(to_date)s
|
|
AND consolidated IS NOT TRUE
|
|
GROUP BY user_id """
|
|
self.env.cr.execute(select_query, {
|
|
'from_date': from_date,
|
|
'to_date': end_date,
|
|
})
|
|
results = self.env.cr.dictfetchall()
|
|
if results:
|
|
for result in results:
|
|
result['consolidated'] = True
|
|
result['tracking_date'] = fields.Date.to_string(from_date)
|
|
self.create(results)
|
|
|
|
self.search([
|
|
('tracking_date', '>=', from_date),
|
|
('tracking_date', '<=', end_date),
|
|
('consolidated', '!=', True)]
|
|
).unlink()
|
|
return True
|