[FIX][IMP] portal_rating: round decimal ratings to two decimals

When hovering the number of stars of a course in front-end, for instance,
one can see "4,16666666666667 stars on 5". This is not very convenient.
The number is rounded up to two decimals instead. -> "4,17 stars on 5".

Same fix is done in backend in slides-specific kanban view of ratings. Value
is now rounded.

Finally _rating_get_repartition is fixed round values to the nearest half
value. We generally receive integer values between 0 and 5 but other values
may exist. Getting a repartition rounded at nearest half integer is sufficient
notably when looking at star-based display which covers only complete or half
complete stars.

Task-2728564

Part-of: odoo/odoo#82792
Co-authored-by: Noé Antoine <nan@odoo.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
This commit is contained in:
Noe Antoine
2022-02-22 19:47:53 +00:00
committed by Thibault Delavallée
co-authored by Thibault Delavallée
parent 6e12ba51bb
commit 9355631e89
4 changed files with 14 additions and 8 deletions
@@ -138,13 +138,14 @@ PortalChatter.include({
if (!result['rating_stats']) {
return;
}
const self = this;
const ratingData = {
'avg': Math.round(result['rating_stats']['avg'] * 100) / 100,
'percent': [],
};
_.each(_.keys(result['rating_stats']['percent']).reverse(), function (rating) {
_.each(_.sortBy(_.keys(result['rating_stats']['percent'])).reverse(), function (rating) {
ratingData['percent'].push({
'num': rating,
'num': self.roundToHalf(rating),
'percent': utils.round_precision(result['rating_stats']['percent'][rating], 0.01),
});
});
@@ -4,7 +4,10 @@
<t t-set="val_integer" t-value="Math.floor(val)"/>
<t t-set="val_decimal" t-value="val - val_integer"/>
<t t-set="empty_star" t-value="5 - (val_integer+Math.ceil(val_decimal))"/>
<div class="o_website_rating_static" t-att-style="inline_mode ? 'display:inline' : ''" t-attf-aria-label="#{val} stars on 5" t-attf-title="#{val} stars on 5">
<div class="o_website_rating_static"
t-att-style="inline_mode ? 'display:inline' : ''"
t-attf-aria-label="#{Math.round(val * 100) / 100} stars on 5"
t-attf-title="#{Math.round(val * 100) / 100} stars on 5">
<t t-foreach="_.range(0, val_integer)" t-as="num">
<i class="fa fa-star" role="img"></i>
</t>
+6 -4
View File
@@ -6,7 +6,7 @@ import operator
from odoo import api, fields, models, tools
from odoo.addons.rating.models import rating_data
from odoo.osv import expression
from odoo.tools.float_utils import float_compare
from odoo.tools.float_utils import float_compare, float_round
class RatingMixin(models.AbstractModel):
@@ -224,17 +224,19 @@ class RatingMixin(models.AbstractModel):
base_domain = expression.AND([self._rating_domain(), [('rating', '>=', 1)]])
if domain:
base_domain += domain
data = self.env['rating.rating'].read_group(base_domain, ['rating'], ['rating', 'res_id'])
rg_data = self.env['rating.rating'].read_group(base_domain, ['rating'], ['rating', 'res_id'])
# init dict with all posible rate value, except 0 (no value for the rating)
values = dict.fromkeys(range(1, 6), 0)
values.update((d['rating'], d['rating_count']) for d in data)
for rating_rg in rg_data:
rating_val_round = float_round(rating_rg['rating'], precision_digits=1)
values[rating_val_round] = values.get(rating_val_round, 0) + rating_rg['rating_count']
# add other stats
if add_stats:
rating_number = sum(values.values())
result = {
'repartition': values,
'avg': sum(float(key * values[key]) for key in values) / rating_number if rating_number > 0 else 0,
'total': sum(it['rating_count'] for it in data),
'total': sum(it['rating_count'] for it in rg_data),
}
return result
return values
@@ -12,7 +12,7 @@
<field name="partner_id"/>
<templates>
<t t-name="kanban-box">
<t t-set="val_stars" t-value="record.rating.raw_value"/>
<t t-set="val_stars" t-value="Math.round(record.rating.raw_value * 10) / 10"/>
<t t-set="val_integer" t-value="Math.floor(val_stars)"/>
<t t-set="val_decimal" t-value="val_stars - val_integer"/>
<t t-set="empty_star" t-value="5 - (val_integer + Math.ceil(val_decimal))"/>