In order to reduce friction and ease the rating process for attendees, we do not force the constraint stating that the message must contain a message or an attachment onto the users. Instead, we allow ratings and replace the empty message by a blank space to avoid triggering the error message. If no stars are selected, an error message is now displayed to the user, asking to select a rating before submission, preventing them to post their review until then. Since we do not really support 0 stars ratings, and do not want the user to see that error message in case of the course, we set the default rating to 4.0 instead of 0.0. -> Therefore, we also remove the grey star contrast coloring on first review since we do not want the user to have the impression a choice has already be made beforehand. In that case, everything will be yellow. Void content detection is done by extracting it in both python (portal chatter post controller) and frontend (submission check) and relaxing it in slides modules. Task-2728564 Part-of: odoo/odoo#82792
94 lines
4.3 KiB
Python
94 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import werkzeug
|
|
|
|
from werkzeug.exceptions import NotFound, Forbidden
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from odoo.addons.portal.controllers.mail import _check_special_access, PortalChatter
|
|
from odoo.tools import plaintext2html, html2plaintext
|
|
|
|
|
|
class SlidesPortalChatter(PortalChatter):
|
|
|
|
def _portal_post_has_content(self, res_model, res_id, message, attachment_ids=None, **kw):
|
|
""" Relax constraint on slide model: having a rating value is sufficient
|
|
to consider we have a content. """
|
|
if res_model == 'slide.channel' and kw.get('rating_value'):
|
|
return True
|
|
return super()._portal_post_has_content(res_model, res_id, message, attachment_ids=attachment_ids, **kw)
|
|
|
|
@http.route(['/mail/chatter_post'], type='json', methods=['POST'], auth='public', website=True)
|
|
def portal_chatter_post(self, res_model, res_id, message, **kw):
|
|
result = super(SlidesPortalChatter, self).portal_chatter_post(res_model, res_id, message, **kw)
|
|
if result and res_model == 'slide.channel':
|
|
rating_value = kw.get('rating_value', False)
|
|
slide_channel = request.env[res_model].sudo().browse(int(res_id))
|
|
if rating_value and slide_channel and request.env.user.partner_id.id == int(kw.get('pid')):
|
|
# apply karma gain rule only once
|
|
request.env.user.add_karma(slide_channel.karma_gen_channel_rank)
|
|
result.update({
|
|
'default_rating_value': rating_value,
|
|
'rating_avg': slide_channel.rating_avg,
|
|
'rating_count': slide_channel.rating_count,
|
|
'force_submit_url': result.get('default_message_id') and '/slides/mail/update_comment',
|
|
})
|
|
return result
|
|
|
|
@http.route([
|
|
'/slides/mail/update_comment',
|
|
'/mail/chatter_update',
|
|
], type='json', auth="user", methods=['POST'])
|
|
def mail_update_message(self, res_model, res_id, message, message_id, attachment_ids=None, attachment_tokens=None, **post):
|
|
# keep this mechanism intern to slide currently (saas 12.5) as it is
|
|
# considered experimental
|
|
if res_model != 'slide.channel':
|
|
raise Forbidden()
|
|
res_id = int(res_id)
|
|
|
|
self._portal_post_check_attachments(attachment_ids, attachment_tokens)
|
|
|
|
pid = int(post['pid']) if post.get('pid') else False
|
|
if not _check_special_access(res_model, res_id, token=post.get('token'), _hash=post.get('hash'), pid=pid):
|
|
raise Forbidden()
|
|
|
|
# fetch and update mail.message
|
|
message_id = int(message_id)
|
|
message_body = plaintext2html(message)
|
|
domain = [
|
|
('model', '=', res_model),
|
|
('res_id', '=', res_id),
|
|
('is_internal', '=', False),
|
|
('author_id', '=', request.env.user.partner_id.id),
|
|
('message_type', '=', 'comment'),
|
|
('id', '=', message_id)
|
|
] # restrict to the given message_id
|
|
message = request.env['mail.message'].search(domain, limit=1)
|
|
if not message:
|
|
raise NotFound()
|
|
message.sudo().write({
|
|
'body': message_body,
|
|
'attachment_ids': [(4, aid) for aid in attachment_ids],
|
|
})
|
|
|
|
# update rating
|
|
if post.get('rating_value'):
|
|
domain = [('res_model', '=', res_model), ('res_id', '=', res_id), ('is_internal', '=', False), ('message_id', '=', message.id)]
|
|
rating = request.env['rating.rating'].sudo().search(domain, order='write_date DESC', limit=1)
|
|
rating.write({
|
|
'rating': float(post['rating_value']),
|
|
'feedback': html2plaintext(message.body),
|
|
})
|
|
channel = request.env[res_model].browse(res_id)
|
|
return {
|
|
'default_message_id': message.id,
|
|
'default_message': html2plaintext(message.body),
|
|
'default_rating_value': message.rating_value,
|
|
'rating_avg': channel.rating_avg,
|
|
'rating_count': channel.rating_count,
|
|
'default_attachment_ids': message.attachment_ids.sudo().read(['id', 'name', 'mimetype', 'file_size', 'access_token']),
|
|
'force_submit_url': '/slides/mail/update_comment',
|
|
}
|