diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 8f5e2918c0cd0086c1134dc0e2d0c65bdca95c0d..941477e69b2c41a45b0d1d9344ce7eacf69b1eca 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -46,15 +46,22 @@ class ChannelUsersRelation(models.Model): record.completion = math.ceil(100.0 * slide_done / slide_total) def _write(self, values): + partner_karma = False if 'completion' in values and values['completion'] >= 100: values['completed'] = True - result = super(ChannelUsersRelation, self)._write(values) - partner_has_completed = {channel_partner.partner_id.id: channel_partner.channel_id for channel_partner in self} - users = self.env['res.users'].sudo().search([('partner_id', 'in', list(partner_has_completed.keys()))]) + incomplete_channel_partners = self.filtered(lambda cp: not cp.completed) + partner_karma = dict.fromkeys(incomplete_channel_partners.mapped('partner_id').ids, 0) + for channel_partner in incomplete_channel_partners: + partner_karma[channel_partner.partner_id.id] += channel_partner.channel_id.karma_gen_channel_finish + partner_karma = {partner_id: karma_to_add + for partner_id, karma_to_add in partner_karma.items() if karma_to_add > 0} + + result = super(ChannelUsersRelation, self)._write(values) + + if partner_karma: + users = self.env['res.users'].sudo().search([('partner_id', 'in', list(partner_karma.keys()))]) for user in users: - users.add_karma(partner_has_completed[user.partner_id.id].karma_gen_channel_finish) - else: - result = super(ChannelUsersRelation, self)._write(values) + users.add_karma(partner_karma[user.partner_id.id]) return result @@ -146,7 +153,6 @@ class Channel(models.Model): can_upload = fields.Boolean('Can Upload', compute='_compute_can_upload') # karma generation karma_gen_slide_vote = fields.Integer(string='Lesson voted', default=1) - karma_gen_channel_share = fields.Integer(string='Course shared', default=2) karma_gen_channel_rank = fields.Integer(string='Course ranked', default=5) karma_gen_channel_finish = fields.Integer(string='Course finished', default=10) # TODO DBE : Add karma based action rules (like in forum) diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index c98d0b9a69f94bfc8cabd2bf99303af1be37e420..2b4a13eefc18763de8c2bcc893b80d8dc123f852 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -395,7 +395,9 @@ class Slide(models.Model): ('slide_id', 'in', self.ids), ('partner_id', '=', self.env.user.partner_id.id) ]) - new_slides = self_sudo - slide_partners.mapped('slide_id') + slide_id = slide_partners.mapped('slide_id') + new_slides = self_sudo - slide_id + channel = slide_id.channel_id for slide_partner in slide_partners: if upvote: @@ -409,7 +411,10 @@ class Slide(models.Model): new_slide.write({ 'slide_partner_ids': [(0, 0, {'vote': new_vote, 'partner_id': self.env.user.partner_id.id})] }) - self.env.user.add_karma(new_slide.channel_id.karma_gen_slide_vote) + if new_vote != 0: + self.env.user.add_karma(channel.karma_gen_slide_vote) + else: + self.env.user.add_karma(-channel.karma_gen_slide_vote) def action_set_viewed(self, quiz_attempts_inc=False): if not all(slide.channel_id.is_member for slide in self): diff --git a/addons/website_slides/tests/__init__.py b/addons/website_slides/tests/__init__.py index c9a6c617426488c197858220dd089e260cc6d210..69bfc7de9e21d79d63a849092df058e2a57f7e72 100644 --- a/addons/website_slides/tests/__init__.py +++ b/addons/website_slides/tests/__init__.py @@ -4,3 +4,4 @@ from . import common from . import test_security from . import test_statistics +from . import test_karma diff --git a/addons/website_slides/tests/test_karma.py b/addons/website_slides/tests/test_karma.py new file mode 100644 index 0000000000000000000000000000000000000000..df6d70823d4f8cb14561541f1ecfc917c62b1d38 --- /dev/null +++ b/addons/website_slides/tests/test_karma.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.website_slides.tests import common +from odoo.tests import tagged +from odoo.tools import mute_logger + + +@tagged('functional') +class TestKarmaGain(common.SlidesCase): + + def setUp(self): + super(TestKarmaGain, self).setUp() + + self.channel_2 = self.env['slide.channel'].sudo(self.user_publisher).create({ + 'name': 'Test Channel 2', + 'channel_type': 'training', + 'promote_strategy': 'most_voted', + 'enroll': 'public', + 'visibility': 'public', + 'website_published': True, + 'karma_gen_channel_finish': 100, + }) + + self.slide_2 = self.env['slide.slide'].sudo(self.user_publisher).create({ + 'name': 'How to travel through space and time', + 'channel_id': self.channel_2.id, + 'slide_type': 'presentation', + 'website_published': True, + 'completion_time': 2.0, + }) + + self.channel_3 = self.env['slide.channel'].sudo(self.user_publisher).create({ + 'name': 'Test Channel 3', + 'channel_type': 'training', + 'promote_strategy': 'most_voted', + 'enroll': 'public', + 'visibility': 'public', + 'website_published': True, + 'karma_gen_channel_finish': 50, + }) + + self.slide_3 = self.env['slide.slide'].sudo(self.user_publisher).create({ + 'name': 'How to duplicate yourself', + 'channel_id': self.channel_3.id, + 'slide_type': 'presentation', + 'website_published': True, + 'completion_time': 2.0, + }) + + def karma_gain_test(self, user): + # Add the user to the course + self.channel.sudo()._action_add_members(user.partner_id) + + # Init user env + channel = self.channel.sudo(user) + slide = self.slide.sudo(user) + self.assertEqual(user.karma, 0) + + # Finish the Course + karma = channel.karma_gen_channel_finish + slide.action_set_completed() + self.assertEqual(user.karma, karma) + + # Vote for a slide + karma = karma + channel.karma_gen_slide_vote + slide.action_like() + self.assertEqual(user.karma, karma) + slide.action_dislike() + self.assertEqual(user.karma, karma - channel.karma_gen_slide_vote) + slide.action_dislike() + self.assertEqual(user.karma, karma) + + # Finish two course at the same time (should not ever happen but hey, we never know) + self.channel_2.sudo()._action_add_members(user.partner_id) + self.channel_3.sudo()._action_add_members(user.partner_id) + + karma = karma + self.channel_2.karma_gen_channel_finish + self.channel_3.karma_gen_channel_finish + slides = self.slide_2.sudo(user) | self.slide_3.sudo(user) + slides.action_set_completed() + self.assertEqual(user.karma, karma) + + @mute_logger('odoo.models') + def test_users_karma_gain(self): + self.karma_gain_test(self.user_emp) + + @mute_logger('odoo.models') + def test_user_publisher_karma_gain(self): + self.karma_gain_test(self.user_publisher) + + @mute_logger('odoo.models') + def test_user_portal_karma_gain(self): + self.karma_gain_test(self.user_portal)