website_forum/models/forum_post_vote.py

114 lines
4.4 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import UserError, AccessError
class Vote(models.Model):
_name = 'forum.post.vote'
_description = 'Post Vote'
_order = 'create_date desc, id desc'
post_id = fields.Many2one('forum.post', string='Post', ondelete='cascade', required=True)
user_id = fields.Many2one('res.users', string='User', required=True, default=lambda self: self._uid, ondelete='cascade')
vote = fields.Selection([('1', '1'), ('-1', '-1'), ('0', '0')], string='Vote', required=True, default='1')
create_date = fields.Datetime('Create Date', index=True, readonly=True)
forum_id = fields.Many2one('forum.forum', string='Forum', related="post_id.forum_id", store=True, readonly=False)
recipient_id = fields.Many2one('res.users', string='To', related="post_id.create_uid", store=True, readonly=False)
_sql_constraints = [
('vote_uniq', 'unique (post_id, user_id)', "Vote already exists!"),
]
def _get_karma_value(self, old_vote, new_vote, up_karma, down_karma):
"""Return the karma to add / remove based on the old vote and on the new vote."""
karma_values = {'-1': down_karma, '0': 0, '1': up_karma}
karma = karma_values[new_vote] - karma_values[old_vote]
if old_vote == new_vote:
reason = _('no changes')
elif new_vote == '1':
reason = _('upvoted')
elif new_vote == '-1':
reason = _('downvoted')
elif old_vote == '1':
reason = _('no more upvoted')
else:
reason = _('no more downvoted')
return karma, reason
@api.model_create_multi
def create(self, vals_list):
# can't modify owner of a vote
if not self.env.is_admin():
for vals in vals_list:
vals.pop('user_id', None)
votes = super(Vote, self).create(vals_list)
for vote in votes:
vote._check_general_rights()
vote._check_karma_rights(vote.vote == '1')
# karma update
vote._vote_update_karma('0', vote.vote)
return votes
def write(self, values):
# can't modify owner of a vote
if not self.env.is_admin():
values.pop('user_id', None)
for vote in self:
vote._check_general_rights(values)
vote_value = values.get('vote')
if vote_value is not None:
upvote = vote.vote == '-1' if vote_value == '0' else vote_value == '1'
vote._check_karma_rights(upvote)
# karma update
vote._vote_update_karma(vote.vote, vote_value)
res = super(Vote, self).write(values)
return res
def _check_general_rights(self, vals=None):
if vals is None:
vals = {}
post = self.post_id
if vals.get('post_id'):
post = self.env['forum.post'].browse(vals.get('post_id'))
if not self.env.is_admin():
# own post check
if self._uid == post.create_uid.id:
raise UserError(_('It is not allowed to vote for its own post.'))
# own vote check
if self._uid != self.user_id.id:
raise UserError(_('It is not allowed to modify someone else\'s vote.'))
def _check_karma_rights(self, upvote=False):
# karma check
if upvote and not self.post_id.can_upvote:
raise AccessError(_('%d karma required to upvote.', self.post_id.forum_id.karma_upvote))
elif not upvote and not self.post_id.can_downvote:
raise AccessError(_('%d karma required to downvote.', self.post_id.forum_id.karma_downvote))
def _vote_update_karma(self, old_vote, new_vote):
if self.post_id.parent_id:
karma, reason = self._get_karma_value(
old_vote,
new_vote,
self.forum_id.karma_gen_answer_upvote,
self.forum_id.karma_gen_answer_downvote)
source = _('Answer %s', reason)
else:
karma, reason = self._get_karma_value(
old_vote,
new_vote,
self.forum_id.karma_gen_question_upvote,
self.forum_id.karma_gen_question_downvote)
source = _('Question %s', reason)
self.recipient_id.sudo()._add_karma(karma, self.post_id, source)