diff options
Diffstat (limited to 'addons/gamification')
| -rw-r--r-- | addons/gamification/__manifest__.py | 4 | ||||
| -rw-r--r-- | addons/gamification/data/cron.xml | 13 | ||||
| -rw-r--r-- | addons/gamification/data/gamification_karma_rank_demo.xml | 9 | ||||
| -rw-r--r-- | addons/gamification/data/gamification_karma_tracking_demo.xml | 83 | ||||
| -rw-r--r-- | addons/gamification/models/__init__.py | 1 | ||||
| -rw-r--r-- | addons/gamification/models/gamification_karma_tracking.py | 69 | ||||
| -rw-r--r-- | addons/gamification/models/res_users.py | 88 | ||||
| -rw-r--r-- | addons/gamification/security/ir.model.access.csv | 4 | ||||
| -rw-r--r-- | addons/gamification/tests/__init__.py | 1 | ||||
| -rw-r--r-- | addons/gamification/tests/test_karma_tracking.py | 195 | ||||
| -rw-r--r-- | addons/gamification/views/gamification_karma_tracking_views.xml | 63 |
11 files changed, 512 insertions, 18 deletions
diff --git a/addons/gamification/__manifest__.py b/addons/gamification/__manifest__.py index 0270a25a56b..314dcf070a2 100644 --- a/addons/gamification/__manifest__.py +++ b/addons/gamification/__manifest__.py @@ -33,9 +33,11 @@ Both goals and badges are flexibles and can be adapted to a large range of modul 'data/gamification_karma_rank_data.xml', 'views/gamification.xml', 'views/gamification_karma_rank_views.xml', + 'views/gamification_karma_tracking_views.xml', 'views/mail_templates.xml' ], 'demo': [ - 'data/gamification_karma_rank_demo.xml' + 'data/gamification_karma_rank_demo.xml', + 'data/gamification_karma_tracking_demo.xml', ], } diff --git a/addons/gamification/data/cron.xml b/addons/gamification/data/cron.xml index 0ed59d39e11..4e59205647b 100644 --- a/addons/gamification/data/cron.xml +++ b/addons/gamification/data/cron.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <odoo> <data noupdate="1"> <record forcecreate="True" id="ir_cron_check_challenge" model="ir.cron"> @@ -10,5 +11,17 @@ <field name="numbercall">-1</field> <field eval="False" name="doall" /> </record> + + <record id="ir_cron_consolidate_last_month" model="ir.cron"> + <field name="name">Gamification: Karma tracking consolidation</field> + <field name="model_id" ref="model_gamification_karma_tracking"/> + <field name="state">code</field> + <field name="code">model._consolidate_last_month()</field> + <field name="active" eval="True"/> + <field name="interval_number">1</field> + <field name="interval_type">months</field> + <field name="numbercall">-1</field> + <field name="nextcall" eval="(DateTime.now() + relativedelta(day=1, months=1)).strftime('%Y-%m-%d 04:00:00')" /> + </record> </data> </odoo> diff --git a/addons/gamification/data/gamification_karma_rank_demo.xml b/addons/gamification/data/gamification_karma_rank_demo.xml index 839e8750047..848e7fd68d0 100644 --- a/addons/gamification/data/gamification_karma_rank_demo.xml +++ b/addons/gamification/data/gamification_karma_rank_demo.xml @@ -1,13 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <odoo><data noupdate="1"> - <!-- Set demo karma for test tour as demo user--> - <record id="base.user_demo" model="res.users"> - <field name="karma">20</field> - </record> - <record id="base.demo_user0" model="res.users"> - <field name="karma">10</field> - </record> - <!--Ranks--> <record id="rank_student" model="gamification.karma.rank"> <field name="description_motivational" type="html"> @@ -44,5 +36,4 @@ </div> </field> </record> - </data></odoo> diff --git a/addons/gamification/data/gamification_karma_tracking_demo.xml b/addons/gamification/data/gamification_karma_tracking_demo.xml new file mode 100644 index 00000000000..01f4d8ac929 --- /dev/null +++ b/addons/gamification/data/gamification_karma_tracking_demo.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo><data noupdate="1"> + + <!--base.user_demo--> + <record id="karma_tracking_user_demo_1st_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_demo"/> + <field name="old_value">0</field> + <field name="new_value">1000</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=1, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_demo_2nd_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_demo"/> + <field name="old_value">1000</field> + <field name="new_value">1500</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=2, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_demo_5th_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_demo"/> + <field name="old_value">1500</field> + <field name="new_value">2000</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=5, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_demo_20th_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_demo"/> + <field name="old_value">2000</field> + <field name="new_value">2050</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=20, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="base.user_demo" model="res.users"> + <field name="karma">2500</field> + </record> + + <!--base.demo_user0 --> + <record id="karma_tracking_user_portal_2nd_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.demo_user0"/> + <field name="old_value">0</field> + <field name="new_value">5</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=2, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_portal_3rd_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.demo_user0"/> + <field name="old_value">5</field> + <field name="new_value">10</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=3, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_portal_10th_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.demo_user0"/> + <field name="old_value">10</field> + <field name="new_value">20</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=10, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_portal_today_0" model="gamification.karma.tracking"> + <field name="user_id" ref="base.demo_user0"/> + <field name="old_value">20</field> + <field name="new_value">25</field> + <field name="tracking_date" eval="(DateTime.now()).strftime('%Y-%m-%d')"/> + </record> + <record id="base.demo_user0" model="res.users"> + <field name="karma">30</field> + </record> + + <!--base.user_admin (already have a tracking to 2500)--> + <record id="karma_tracking_user_admin_1st_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_admin"/> + <field name="old_value">0</field> + <field name="new_value">2000</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=1, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_admin_5th_day_last_month" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_admin"/> + <field name="old_value">2000</field> + <field name="new_value">2250</field> + <field name="tracking_date" eval="(DateTime.now() - relativedelta(day=5, months=1)).strftime('%Y-%m-%d')"/> + </record> + <record id="karma_tracking_user_admin_today" model="gamification.karma.tracking"> + <field name="user_id" ref="base.user_admin"/> + <field name="old_value">2250</field> + <field name="new_value">2500</field> + <field name="tracking_date" eval="(DateTime.now()).strftime('%Y-%m-%d')"/> + </record> + +</data> +</odoo> diff --git a/addons/gamification/models/__init__.py b/addons/gamification/models/__init__.py index 926a5af2a07..659fcff70a1 100644 --- a/addons/gamification/models/__init__.py +++ b/addons/gamification/models/__init__.py @@ -5,4 +5,5 @@ from . import goal from . import challenge from . import badge from . import gamification_karma_rank +from . import gamification_karma_tracking from . import res_users diff --git a/addons/gamification/models/gamification_karma_tracking.py b/addons/gamification/models/gamification_karma_tracking.py new file mode 100644 index 00000000000..f7b184ad24d --- /dev/null +++ b/addons/gamification/models/gamification_karma_tracking.py @@ -0,0 +1,69 @@ +# -*- 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 diff --git a/addons/gamification/models/res_users.py b/addons/gamification/models/res_users.py index 3e8b6d8e1cd..3dc95de74a1 100644 --- a/addons/gamification/models/res_users.py +++ b/addons/gamification/models/res_users.py @@ -3,16 +3,12 @@ from odoo import api, fields, models -import logging - -_logger = logging.getLogger(__name__) - class Users(models.Model): _inherit = 'res.users' - karma = fields.Integer('Karma', default=0) + 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") @@ -46,11 +42,28 @@ class Users(models.Model): @api.model_create_multi def create(self, values_list): res = super(Users, self).create(values_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) + 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']}) + result = super(Users, self).write(vals) + + if karma_trackings: + self.env['gamification.karma.tracking'].sudo().create(karma_trackings) if 'karma' in vals: self._recompute_rank() return result @@ -60,6 +73,68 @@ class Users(models.Model): user.karma += karma return True + def _get_tracking_karma_gain_position(self, user_domain, from_date=None, to_date=None): + """ Get absolute position in term of gained karma for users. First a ranking + of all users is done given a user_domain; then the position of each user + belonging to the current record set is extracted. + + Example: in website profile, search users with name containing Norbert. Their + positions should not be 1 to 4 (assuming 4 results), but their actual position + in the karma gain ranking (with example user_domain being karma > 1, + website published True). + + :param user_domain: general domain (i.e. active, karma > 1, website, ...) + to compute the absolute position of the current record set + :param from_date: compute karma gained after this date (included) or from + beginning of time; + :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 + """ + 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() + + 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 = """ +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 + 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 + 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 '' + } + + self.env.cr.execute(query, tuple(where_clause_params + params)) + return self.env.cr.dictfetchall() + def _rank_changed(self): """ Method that can be called on a batch of users with the same new rank @@ -68,7 +143,7 @@ class Users(models.Model): if template: for u in self: if u.rank_id.karma_min > 0: - template.send_mail(u.id, force_send=len(self) == 1, notif_layout='mail.mail_notification_light') + template.send_mail(u.id, force_send=False, notif_layout='mail.mail_notification_light') def _recompute_rank(self): """ @@ -161,7 +236,6 @@ class Users(models.Model): 'next_rank_id': lower_rank.id, }) - def _get_next_rank(self): """ For fresh users with 0 karma that don't have a rank_id and next_rank_id yet this method returns the first karma rank (by karma ascending). This acts as a diff --git a/addons/gamification/security/ir.model.access.csv b/addons/gamification/security/ir.model.access.csv index 41f36a87a5f..728360ab386 100644 --- a/addons/gamification/security/ir.model.access.csv +++ b/addons/gamification/security/ir.model.access.csv @@ -27,4 +27,6 @@ badge_user_portal,"Badge-user Portal",gamification.model_gamification_badge_user badge_user_public,"Badge-user Public",gamification.model_gamification_badge_user,base.group_public,1,0,0,0 gamification_karma_rank_access_all,gamification.karma.rank.access.all,gamification.model_gamification_karma_rank,,1,0,0,0 -gamification_karma_rank_access_user_manager,gamification.karma.rank.access.user.manager,gamification.model_gamification_karma_rank,base.group_erp_manager,1,1,1,1 +gamification_karma_rank_access_user_manager,gamification.karma.rank.access.user.manager,gamification.model_gamification_karma_rank,base.group_system,1,1,1,1 +gamification_karma_tracking_access_all,gamification.karma.tracking.access.all,gamification.model_gamification_karma_tracking,,0,0,0,0 +gamification_karma_tracking_access_user_manager,gamification.karma.tracking.access.user.manager,gamification.model_gamification_karma_tracking,base.group_system,1,1,1,1 diff --git a/addons/gamification/tests/__init__.py b/addons/gamification/tests/__init__.py index a6a599bf6c8..963887eb670 100644 --- a/addons/gamification/tests/__init__.py +++ b/addons/gamification/tests/__init__.py @@ -3,3 +3,4 @@ from . import test_challenge from . import test_recompute_rank +from . import test_karma_tracking diff --git a/addons/gamification/tests/test_karma_tracking.py b/addons/gamification/tests/test_karma_tracking.py new file mode 100644 index 00000000000..145b745b436 --- /dev/null +++ b/addons/gamification/tests/test_karma_tracking.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import date +from dateutil.relativedelta import relativedelta +from unittest.mock import patch + +from odoo import exceptions, fields +from odoo.tests import common + + +class TestKarmaTrackingCommon(common.SavepointCase): + + @classmethod + def setUpClass(cls): + super(TestKarmaTrackingCommon, cls).setUpClass() + cls.test_user = cls.env['res.users'].with_context(no_reset_password=True, mail_create_nosubscribe=True).create({ + 'name': 'Test User', + 'login': 'test', + 'email': 'test@example.com', + 'karma': 0, + 'groups_id': [(4, cls.env.ref('base.group_user').id)] + }) + cls.test_user_2 = cls.env['res.users'].with_context(no_reset_password=True, mail_create_nosubscribe=True).create({ + 'name': 'Test User 2', + 'login': 'test2', + 'email': 'test2@example.com', + 'karma': 0, + 'groups_id': [(4, cls.env.ref('base.group_user').id)] + }) + cls.env['gamification.karma.tracking'].search([]).unlink() + + cls.test_date = fields.Date.today() + relativedelta(month=4, day=1) + + @classmethod + def _create_trackings(cls, user, karma, steps, date, days_delta=1): + old_value = user.karma + for step in range(steps): + new_value = old_value + karma + cls.env['gamification.karma.tracking'].create([{ + 'user_id': user.id, + 'old_value': old_value, + 'new_value': new_value, + 'consolidated': False, + 'tracking_date': fields.Date.to_string(date) + }]) + old_value = new_value + date = date + relativedelta(days=days_delta) + + def test_computation_gain(self): + self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30) + self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2) + + results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([]) + self.assertEqual(results[0]['user_id'], self.test_user_2.id) + self.assertEqual(results[0]['karma_gain_total'], 200) + self.assertEqual(results[0]['karma_position'], 1) + self.assertEqual(results[1]['user_id'], self.test_user.id) + self.assertEqual(results[1]['karma_gain_total'], 40) + self.assertEqual(results[1]['karma_position'], 2) + + results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([], to_date=self.test_date + relativedelta(day=2)) + self.assertEqual(results[0]['user_id'], self.test_user.id) + self.assertEqual(results[0]['karma_gain_total'], 20) + self.assertEqual(results[0]['karma_position'], 1) + self.assertEqual(results[1]['user_id'], self.test_user_2.id) + self.assertEqual(results[1]['karma_gain_total'], 10) + self.assertEqual(results[1]['karma_position'], 2) + + results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([], from_date=self.test_date + relativedelta(months=1, day=1)) + self.assertEqual(results[0]['user_id'], self.test_user_2.id) + self.assertEqual(results[0]['karma_gain_total'], 50) + self.assertEqual(results[0]['karma_position'], 1) + self.assertEqual(results[1]['user_id'], self.test_user.id) + self.assertEqual(results[1]['karma_gain_total'], 20) + self.assertEqual(results[1]['karma_position'], 2) + + results = self.env['res.users']._get_tracking_karma_gain_position([]) + self.assertEqual(len(results), 0) + + def test_consolidation_cron(self): + self.patcher = patch('odoo.addons.gamification.models.gamification_karma_tracking.fields.Date', wraps=fields.Date) + self.mock_datetime = self.patcher.start() + self.mock_datetime.today.return_value = date(self.test_date.year, self.test_date.month + 1, self.test_date.day) + + self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30) + self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2) + self.env['gamification.karma.tracking']._consolidate_last_month() + consolidated = self.env['gamification.karma.tracking'].search([ + ('user_id', 'in', (self.test_user | self.test_user_2).ids), + ('consolidated', '=', True), + ('tracking_date', '=', self.test_date) + ]) + self.assertEqual(len(consolidated), 2) + unconsolidated = self.env['gamification.karma.tracking'].search([ + ('user_id', 'in', (self.test_user | self.test_user_2).ids), + ('consolidated', '=', False), + ]) + self.assertEqual(len(unconsolidated), 6) # 5 for test user 2, 1 for test user + + self.patcher.stop() + + def test_consolidation_monthly(self): + Tracking = self.env['gamification.karma.tracking'] + base_test_user_karma = self.test_user.karma + base_test_user_2_karma = self.test_user_2.karma + self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30) + self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2) + + Tracking._process_consolidate(self.test_date) + consolidated = Tracking.search([ + ('user_id', '=', self.test_user_2.id), + ('consolidated', '=', True), + ('tracking_date', '=', self.test_date) + ]) + self.assertEqual(len(consolidated), 1) + self.assertEqual(consolidated.old_value, base_test_user_2_karma) # 15 2-days span, from 1 to 29 included = 15 steps -> 150 karma + self.assertEqual(consolidated.new_value, base_test_user_2_karma + 150) # 15 2-days span, from 1 to 29 included = 15 steps -> 150 karma + + remaining = Tracking.search([ + ('user_id', '=', self.test_user_2.id), + ('consolidated', '=', False) + ]) + self.assertEqual(len(remaining), 5) # 15 steps consolidated, remaining 5 + self.assertEqual(remaining[0].tracking_date, self.test_date + relativedelta(months=1, day=9)) # ordering: last first + self.assertEqual(remaining[-1].tracking_date, self.test_date + relativedelta(months=1, day=1)) + + Tracking._process_consolidate(self.test_date + relativedelta(months=1)) + consolidated = Tracking.search([ + ('user_id', '=', self.test_user_2.id), + ('consolidated', '=', True), + ]) + self.assertEqual(len(consolidated), 2) + self.assertEqual(consolidated[0].new_value, base_test_user_2_karma + 200) # 5 remaining 2-days span, from 1 to 9 included = 5 steps -> 50 karma + self.assertEqual(consolidated[0].old_value, base_test_user_2_karma + 150) # coming from previous iteration + self.assertEqual(consolidated[0].tracking_date, self.test_date + relativedelta(months=1)) # tracking set at beginning of month + self.assertEqual(consolidated[-1].new_value, base_test_user_2_karma + 150) # previously created one still present + self.assertEqual(consolidated[-1].old_value, base_test_user_2_karma) # previously created one still present + + remaining = Tracking.search([ + ('user_id', '=', self.test_user_2.id), + ('consolidated', '=', False) + ]) + self.assertFalse(remaining) + + # current user not-in-details tests + current_user_trackings = Tracking.search([ + ('user_id', '=', self.test_user.id), + ]) + self.assertEqual(len(current_user_trackings), 2) + self.assertEqual(current_user_trackings[0].new_value, base_test_user_karma + 40) + self.assertEqual(current_user_trackings[-1].old_value, base_test_user_karma) + + def test_user_as_erp_manager(self): + self.test_user.write({'groups_id': [ + (4, self.env.ref('base.group_partner_manager').id), + (4, self.env.ref('base.group_erp_manager').id) + ]}) + user = self.env['res.users'].with_user(self.test_user).create({ + 'name': 'Test Ostérone', 'karma': '32', + 'login': 'dummy', 'email': 'dummy@example.com', + }) + with self.assertRaises(exceptions.AccessError): + user.read(['karma_tracking_ids']) + + user.write({'karma': 60}) + user.add_karma(10) + self.assertEqual(user.karma, 70) + trackings = self.env['gamification.karma.tracking'].sudo().search([('user_id', '=', user.id)]) + self.assertEqual(len(trackings), 3) # create + write + add_karma + + def test_user_tracking(self): + self.test_user.write({'groups_id': [ + (4, self.env.ref('base.group_partner_manager').id), + (4, self.env.ref('base.group_system').id) + ]}) + user = self.env['res.users'].with_user(self.test_user).create({ + 'name': 'Test Ostérone', 'karma': '32', + 'login': 'dummy', 'email': 'dummy@example.com', + }) + self.assertEqual(user.karma, 32) + self.assertEqual(len(user.karma_tracking_ids), 1) + self.assertEqual(user.karma_tracking_ids.old_value, 0) + self.assertEqual(user.karma_tracking_ids.new_value, 32) + + user.write({'karma': 60}) + user.add_karma(10) + self.assertEqual(user.karma, 70) + self.assertEqual(len(user.karma_tracking_ids), 3) + self.assertEqual(user.karma_tracking_ids[2].old_value, 60) + self.assertEqual(user.karma_tracking_ids[2].new_value, 70) + self.assertEqual(user.karma_tracking_ids[1].old_value, 32) + self.assertEqual(user.karma_tracking_ids[1].new_value, 60) + self.assertEqual(user.karma_tracking_ids[0].old_value, 0) + self.assertEqual(user.karma_tracking_ids[0].new_value, 32) diff --git a/addons/gamification/views/gamification_karma_tracking_views.xml b/addons/gamification/views/gamification_karma_tracking_views.xml new file mode 100644 index 00000000000..998d0ff91ec --- /dev/null +++ b/addons/gamification/views/gamification_karma_tracking_views.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo><data> + <record id="gamification_karma_tracking_view_search" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.search</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <search string="Search Trackings"> + <field name="user_id"/> + <field name="tracking_date"/> + <filter string="Consolidated" name="filter_consolidated" + domain="[('consolidated', '=', True)]"/> + <group string="Group By" expand="1"> + <filter string="User" name="group_by_user_id" + context="{'group_by': 'user_id'}"/> + </group> + </search> + </field> + </record> + + <record id="gamification_karma_tracking_view_tree" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.tree</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <tree string="Trackings"> + <field name="user_id"/> + <field name="tracking_date"/> + <field name="old_value"/> + <field name="new_value"/> + <field name="consolidated"/> + </tree> + </field> + </record> + + <record id="gamification_karma_tracking_view_form" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.form</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <form string="Tracking"> + <sheet> + <group> + <field name="user_id"/> + <field name="tracking_date"/> + <field name="old_value"/> + <field name="new_value"/> + <field name="consolidated"/> + </group> + </sheet> + </form> + </field> + </record> + + <record id="gamification_karma_tracking_action" model="ir.actions.act_window"> + <field name="name">Trackings</field> + <field name="res_model">gamification.karma.tracking</field> + <field name="view_mode">tree,form</field> + </record> + + <menuitem id="gamification_karma_tracking_menu" + parent="gamification_menu" + action="gamification_karma_tracking_action" + sequence="50"/> + </data> +</odoo> |
