[IMP] website_slides: allow to rate slide channel
This commit allows user to rate a slide channel: using the new Popup Rating Composer, users having access to the slide channel can submit a rating with a comment. Then, lower in the page, they can see the ratings of other users. Task-1902304
This commit is contained in:
@@ -17,7 +17,7 @@ Share and Publish Videos, Presentations and Documents'
|
||||
* Channel Subscription
|
||||
* Supported document types : PDF, images, YouTube videos and Google Drive documents)
|
||||
""",
|
||||
'depends': ['website', 'website_mail'],
|
||||
'depends': ['website', 'website_mail', 'website_rating'],
|
||||
'data': [
|
||||
'views/assets.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
|
||||
@@ -152,7 +152,14 @@ class WebsiteSlides(http.Controller):
|
||||
'pager': pager,
|
||||
'is_public_user': request.website.is_public_user(),
|
||||
'display_channel_settings': not request.httprequest.cookies.get('slides_channel_%s' % (channel.id), False) and channel.can_see_full,
|
||||
'rating_avg': channel.rating_avg,
|
||||
'rating_count': channel.rating_count,
|
||||
}
|
||||
if not request.env.user._is_public():
|
||||
values.update({
|
||||
'message_post_hash': channel._sign_token(request.env.user.partner_id.id),
|
||||
'message_post_pid': request.env.user.partner_id.id
|
||||
})
|
||||
if search:
|
||||
values['search'] = search
|
||||
return request.render('website_slides.slides_search', values)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import uuid
|
||||
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
from odoo.addons.http_routing.models.ir_http import slug
|
||||
from odoo.tools.translate import html_translate
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class Channel(models.Model):
|
||||
@@ -12,7 +14,7 @@ class Channel(models.Model):
|
||||
channels. """
|
||||
_name = 'slide.channel'
|
||||
_description = 'Slide Channel'
|
||||
_inherit = ['mail.thread', 'website.seo.metadata', 'website.published.multi.mixin']
|
||||
_inherit = ['mail.thread', 'website.seo.metadata', 'website.published.multi.mixin', 'rating.mixin']
|
||||
_order = 'sequence, id'
|
||||
_order_by_strategy = {
|
||||
'most_viewed': 'total_views desc',
|
||||
@@ -20,6 +22,9 @@ class Channel(models.Model):
|
||||
'latest': 'date_published desc',
|
||||
}
|
||||
|
||||
def _default_access_token(self):
|
||||
return str(uuid.uuid4())
|
||||
|
||||
# description
|
||||
name = fields.Char('Name', translate=True, required=True)
|
||||
active = fields.Boolean(default=True)
|
||||
@@ -37,6 +42,22 @@ class Channel(models.Model):
|
||||
string="Featuring Policy", default='most_voted', required=True)
|
||||
custom_slide_id = fields.Many2one('slide.slide', string='Slide to Promote')
|
||||
promoted_slide_id = fields.Many2one('slide.slide', string='Featured Slide', compute='_compute_promoted_slide_id', store=True)
|
||||
access_token = fields.Char("Security Token", copy=False, default=_default_access_token)
|
||||
|
||||
@api.depends('custom_slide_id', 'promote_strategy', 'slide_ids.likes',
|
||||
'slide_ids.total_views', "slide_ids.date_published")
|
||||
def _compute_promoted_slide_id(self):
|
||||
for record in self:
|
||||
if record.promote_strategy == 'none':
|
||||
record.promoted_slide_id = False
|
||||
elif record.promote_strategy == 'custom':
|
||||
record.promoted_slide_id = record.custom_slide_id
|
||||
elif record.promote_strategy:
|
||||
slides = self.env['slide.slide'].search(
|
||||
[('website_published', '=', True), ('channel_id', '=', record.id)],
|
||||
limit=1, order=self._order_by_strategy[record.promote_strategy])
|
||||
record.promoted_slide_id = slides and slides[0] or False
|
||||
|
||||
nbr_presentations = fields.Integer('Number of Presentations', compute='_count_presentations', store=True)
|
||||
nbr_documents = fields.Integer('Number of Documents', compute='_count_presentations', store=True)
|
||||
nbr_videos = fields.Integer('Number of Videos', compute='_count_presentations', store=True)
|
||||
@@ -147,6 +168,27 @@ class Channel(models.Model):
|
||||
if self.visibility == 'public':
|
||||
self.group_ids = False
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# ORM Overrides
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@api.model_cr_context
|
||||
def _init_column(self, column_name):
|
||||
""" Initialize the value of the given column for existing rows.
|
||||
Overridden here because we need to generate different access tokens
|
||||
and by default _init_column calls the default method once and applies
|
||||
it for every record.
|
||||
"""
|
||||
if column_name != 'access_token':
|
||||
super(Channel, self)._init_column(column_name)
|
||||
else:
|
||||
query = """
|
||||
UPDATE %(table_name)s
|
||||
SET %(column_name)s = md5(md5(random()::varchar || id::varchar) || clock_timestamp()::varchar)::uuid::varchar
|
||||
WHERE %(column_name)s IS NULL
|
||||
""" % {'table_name': self._table, 'column_name': column_name}
|
||||
self.env.cr.execute(query)
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
return super(Channel, self.with_context(mail_create_nosubscribe=True)).create(vals)
|
||||
@@ -179,6 +221,16 @@ class Channel(models.Model):
|
||||
'channels': [{'id': channel.id, 'name': channel.name, 'website_url': channel.website_url} for channel in self.search([])]
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Rating Mixin API
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@api.multi
|
||||
def _rating_domain(self):
|
||||
""" Only take the published rating into account to compute avg and count """
|
||||
domain = super(Channel, self)._rating_domain()
|
||||
return expression.AND([domain, [('website_published', '=', True)]])
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
""" Channel contain various categories to manage its slides """
|
||||
@@ -210,4 +262,4 @@ class Category(models.Model):
|
||||
record.nbr_documents = result[record.id].get('document', 0)
|
||||
record.nbr_videos = result[record.id].get('video', 0)
|
||||
record.nbr_infographics = result[record.id].get('infographic', 0)
|
||||
record.total = record.nbr_presentations + record.nbr_documents + record.nbr_videos + record.nbr_infographics
|
||||
record.total = record.nbr_presentations + record.nbr_documents + record.nbr_videos + record.nbr_infographics
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
<div>
|
||||
<p class="text-muted oe_no_empty" t-field="channel.description"/>
|
||||
</div>
|
||||
<t t-call="website_rating.rating_widget_stars_static">
|
||||
<t t-set="rating_avg" t-value="channel.rating_avg"/>
|
||||
<t t-set="rating_count" t-value="channel.rating_count"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -235,6 +239,15 @@
|
||||
</t>
|
||||
</div>
|
||||
<div class="row oe_no_empty" t-esc="channel.promoted_slide_id.description"/>
|
||||
<p class="row mt8">
|
||||
<t t-call="website_rating.rating_stars_static_popup_composer">
|
||||
<t t-set="rating_avg" t-value="rating_avg"/>
|
||||
<t t-set="rating_total" t-value="rating_count"/>
|
||||
<t t-set="object" t-value="channel"/>
|
||||
<t t-set="hash" t-value="message_post_hash"/>
|
||||
<t t-set="pid" t-value="message_post_pid"/>
|
||||
</t>
|
||||
</p>
|
||||
<p class="row mt8">
|
||||
<b>Share:</b>
|
||||
<t t-call="website_slides.slides_share">
|
||||
@@ -245,6 +258,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="o_slides_discussion_rating">
|
||||
<div class="container mt16 mb16">
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2">
|
||||
<t t-call="portal.message_thread">
|
||||
<t t-set="object" t-value="channel"/>
|
||||
<t t-set="display_rating" t-value="True"/>
|
||||
<t t-set="disable_composer" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div class="container mt16">
|
||||
<div class="row">
|
||||
|
||||
Reference in New Issue
Block a user