Files
odoo_source/addons/website_slides/controllers/mail.py
T
Noe Antoine aead9a884e [IMP] website_slides: allow empty messages when reviewing courses
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
2022-02-22 19:47:53 +00:00

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',
}