diff --git a/addons/gamification/__manifest__.py b/addons/gamification/__manifest__.py index 975c9bccfd6..0270a25a56b 100644 --- a/addons/gamification/__manifest__.py +++ b/addons/gamification/__manifest__.py @@ -30,6 +30,12 @@ Both goals and badges are flexibles and can be adapted to a large range of modul 'security/ir.model.access.csv', 'data/goal_base.xml', 'data/badge.xml', + 'data/gamification_karma_rank_data.xml', 'views/gamification.xml', + 'views/gamification_karma_rank_views.xml', + 'views/mail_templates.xml' + ], + 'demo': [ + 'data/gamification_karma_rank_demo.xml' ], } diff --git a/addons/gamification/data/gamification_karma_rank_data.xml b/addons/gamification/data/gamification_karma_rank_data.xml new file mode 100644 index 00000000000..616c143d985 --- /dev/null +++ b/addons/gamification/data/gamification_karma_rank_data.xml @@ -0,0 +1,13 @@ + + + + + + Newbie +

You just began the adventure! Welcome!

+

Keep going !

+ 1 + +
+
+
diff --git a/addons/gamification/data/gamification_karma_rank_demo.xml b/addons/gamification/data/gamification_karma_rank_demo.xml new file mode 100644 index 00000000000..d9c89691b3a --- /dev/null +++ b/addons/gamification/data/gamification_karma_rank_demo.xml @@ -0,0 +1,36 @@ + + + + + Student +

You begin to understand things ! Keep going!

+

Keep going !

+ 100 + +
+ + + Bachelor +

Hey ! You're not so dumb after all !

+

Keep going !

+ 500 + +
+ + + Master +

You're good ! Really Good !

+

Keep going !

+ 2000 + +
+ + + Doctor +

Ok, RESPECT !

+

Keep going !

+ 10000 + +
+ +
diff --git a/addons/gamification/models/gamification_karma_rank.py b/addons/gamification/models/gamification_karma_rank.py index 061082545b4..26b89a3db33 100644 --- a/addons/gamification/models/gamification_karma_rank.py +++ b/addons/gamification/models/gamification_karma_rank.py @@ -3,7 +3,52 @@ 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_required' + + name = fields.Text(string='Rank Name', translate=True, required=True) + description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False,) + description_reach_next = fields.Html( + string='Motivation phrase', translate=html_translate, sanitize_attributes=False, + help="Motivation phrase to reach next rank") + karma_required = 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): + tools.image_resize_images(vals) + res = super(KarmaRank, self).write(vals) + users = self.env['res.users'].sudo().search([('karma', '>', 0)]) + users._recompute_rank() + return res diff --git a/addons/gamification/models/res_users.py b/addons/gamification/models/res_users.py index fccddf8bfb5..d7fd35769df 100644 --- a/addons/gamification/models/res_users.py +++ b/addons/gamification/models/res_users.py @@ -12,12 +12,8 @@ class Users(models.Model): 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") - - @api.multi - def add_karma(self, karma): - for user in self: - user.karma += karma - return True + 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') @@ -42,3 +38,52 @@ class Users(models.Model): 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 [] diff --git a/addons/gamification/security/ir.model.access.csv b/addons/gamification/security/ir.model.access.csv index 6a4d9f64a0a..41f36a87a5f 100644 --- a/addons/gamification/security/ir.model.access.csv +++ b/addons/gamification/security/ir.model.access.csv @@ -25,3 +25,6 @@ badge_user_employee,"Badge-user Employee",model_gamification_badge_user,base.gro badge_user_manager,"Badge-user Manager",model_gamification_badge_user,base.group_erp_manager,1,1,1,1 badge_user_portal,"Badge-user Portal",gamification.model_gamification_badge_user,base.group_portal,1,1,1,0 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 diff --git a/addons/gamification/static/img/rank_bachelor.png b/addons/gamification/static/img/rank_bachelor.png new file mode 100644 index 00000000000..8dd6b54fd3f Binary files /dev/null and b/addons/gamification/static/img/rank_bachelor.png differ diff --git a/addons/gamification/static/img/rank_doctor.png b/addons/gamification/static/img/rank_doctor.png new file mode 100644 index 00000000000..1454d3f3c6d Binary files /dev/null and b/addons/gamification/static/img/rank_doctor.png differ diff --git a/addons/gamification/static/img/rank_master.png b/addons/gamification/static/img/rank_master.png new file mode 100644 index 00000000000..8354dd3cb61 Binary files /dev/null and b/addons/gamification/static/img/rank_master.png differ diff --git a/addons/gamification/static/img/rank_newbie.png b/addons/gamification/static/img/rank_newbie.png new file mode 100644 index 00000000000..adf608ce302 Binary files /dev/null and b/addons/gamification/static/img/rank_newbie.png differ diff --git a/addons/gamification/static/img/rank_student.png b/addons/gamification/static/img/rank_student.png new file mode 100644 index 00000000000..5a52b7ab9a2 Binary files /dev/null and b/addons/gamification/static/img/rank_student.png differ diff --git a/addons/gamification/views/gamification_karma_rank_views.xml b/addons/gamification/views/gamification_karma_rank_views.xml new file mode 100644 index 00000000000..d0d84c5114f --- /dev/null +++ b/addons/gamification/views/gamification_karma_rank_views.xml @@ -0,0 +1,71 @@ + + + + + Ranks + gamification.karma.rank + tree,form + +

+ Create a new rank +

+ A rank correspond to a fixed karma level. The more you have karma, the more your rank is high. + This is used to quickly know which user is new or old or highly or not active. +

+
+
+ + + gamification.karma.ranks.view.search + gamification.karma.rank + + + + + + + + + + + + gamification.karma.ranks.view.tree + gamification.karma.rank + + + + + + + + + + + + gamification.karma.rank.view.form + gamification.karma.rank + +
+ +
+ +
+
+ + + + + + + + + + +
+ + + diff --git a/addons/gamification/views/mail_templates.xml b/addons/gamification/views/mail_templates.xml new file mode 100644 index 00000000000..cf840157222 --- /dev/null +++ b/addons/gamification/views/mail_templates.xml @@ -0,0 +1,51 @@ + + + + + New rank reached + + Reception of ${object.name} + ${(object.partner_id.email_formatted or object.email) |safe} + ${object.partner_id.id} + New rank: ${object.rank_id.name} + ${object.partner_id.lang} + + +
+ + + + + + + +
+

+ Congratulations + ${object.partner_id.name or ''}! +

+

+ You just reached a new rank : ${object.rank_id.name} +

+

Continue your work to become a ${object.next_rank_id.name} !

+
+ % set gamification_redirection_data = object.get_gamification_redirection_data() + % for data in gamification_redirection_data + % set url = data['url'] + % set label = data['label'] + ${label} + % endfor +
+
+

+ +

+
+
+
+ Thank you,
+
+
+
+
+
diff --git a/addons/website_forum/views/forum.xml b/addons/website_forum/views/forum.xml index 6a168613cdc..60fb3093ebb 100644 --- a/addons/website_forum/views/forum.xml +++ b/addons/website_forum/views/forum.xml @@ -293,6 +293,6 @@ - +