1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/knowledge/models/knowledge_article_thread.py
2024-12-10 09:04:09 +07:00

124 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
class KnowledgeArticleThread(models.Model):
"""
This is the model for a comment thread linked to a `knowledge.article`. Each thread inherits
the `mail.thread` mixin.
These threads allow end-users to discuss specific parts of the body of a knowledge article.
Which enables reviews, taking notes, pinging a colleague to get more information on a topic, ...
Each initial comment starts its own thread, which will then accumulate replies, reactions, etc.
It is also possible to mark a thread as closed so that it no longer appears inside the editor
of the article if the conversation does not need to be continued.
"""
_name = "knowledge.article.thread"
_description = "Article Discussion Thread"
_inherit = ['mail.thread']
_mail_post_access = 'read' # if you can read, you can post a message on an article thread
_order = 'write_date desc, id desc'
_rec_name = 'display_name'
article_id = fields.Many2one('knowledge.article', ondelete="cascade", readonly=True, required=True)
is_resolved = fields.Boolean("Thread Closed", tracking=True)
@api.depends('article_id')
def _compute_display_name(self):
for record in self:
record.display_name = record.article_id.display_name
def toggle_thread(self):
"""Toggles the resolution state of the article"""
self.ensure_one()
self.is_resolved = not self.is_resolved
# ===========================================================================
# CRUD METHODS
# ===========================================================================
@api.model_create_multi
def create(self, vals_list):
return super(KnowledgeArticleThread, self.with_context(mail_create_nolog=True)).create(vals_list)
# ==========================================================================
# THREAD OVERRIDES
# ==========================================================================
def message_post(self, **kwargs):
"""This function overrides the 'mail.thread' message_post in order to let portal users that
have access to an article to post a message in the thread.
We need to apply this method with sudo for portal users because they do not have access to the
`mail.message` model, which is needed to post the message.
This idea is based on the method `portal_chatter_post` which needs to check access rights in
order to let the portal post in the chatter.
Before posting as a portal we filter what's being sent to lessen security risks. Notably
partner_ids should be a list of ids (not the records themselves) so that we don't allow command
executions, even with the sudo call.
"""
self.ensure_one()
if self.env.user._is_portal() and self.article_id.user_has_access:
authorized_keys = {'body', 'partner_ids', 'author_id'}
return super(KnowledgeArticleThread, self.sudo()).message_post(
**{key: kwargs.get(key) for key in authorized_keys},
message_type='comment', subtype_xmlid='mail.mt_comment'
)
return super().message_post(**kwargs)
def _get_access_action(self, access_uid=None, force_website=False):
self.ensure_one()
user = self.env['res.users'].sudo().browse(access_uid) if access_uid else self.env.user
action = {
'type': 'ir.actions.act_url',
'url': f'/knowledge/article/{self.article_id.id}',
}
if access_uid is None:
action['target_type'] = 'public'
if self.article_id.with_user(user).user_has_access or access_uid is None:
return action
return super()._get_access_action(access_uid=access_uid, force_website=force_website)
def _notify_thread_by_email(self, message, recipients_data, **kwargs):
"""We need to override this method to set our own mail template to be sent to users that
have been tagged inside a comment. We are using the template 'knowledge.knowledge_mail_notification_layout'
which is a simple template comprised of the comment sent and the person that tagged the notified user.
"""
kwargs['msg_vals'] = {**kwargs.get('msg_vals', {}), 'email_layout_xmlid': 'knowledge.knowledge_mail_notification_layout'}
return super()._notify_thread_by_email(message, recipients_data, **kwargs)
def _message_compute_subject(self):
self.ensure_one()
return _('New Mention in %s') % self.display_name
def _notify_get_recipients_groups(self, message, model_description, msg_vals=None):
groups = super()._notify_get_recipients_groups(
message, model_description, msg_vals=msg_vals
)
if message.model != 'knowledge.article.thread':
return groups
self.ensure_one()
action = self._notify_get_action_link('controller', controller='/knowledge/thread/resolve', **msg_vals)
user_actions = [{'url': action, 'title': _('Mark Comment as Closed')}]
new_groups = [(
'group_knowledge_article_thread_portal_and_users',
lambda pdata:
pdata['uid'] and self.article_id.with_user(pdata['uid']).user_has_access,
{
'actions': user_actions,
'active': True,
'has_button_access': True,
}
)]
return new_groups + groups