[IMP] rating,project: display rating text based on the average rating

This commit adds a rating text field called `rating_avg_text` to display
a text based on the value of `rating_avg` field in `rating.mixin` model.
Here is the text displayed based on the value of `rating_avg`:

1. 'Satisfied' if the `rating_avg >= 3.66`
2. 'Okay' if the `2.33 <= rating_avg < 3.66`
3. 'Dissatisfied' if the `1 <= rating_avg < 2.33`
4. 'No Rating' if the `rating_avg < 1`
This commit is contained in:
Xavier BOL (xbo)
2022-01-05 13:58:01 +01:00
parent 1ae732c21f
commit b08dea5aad
3 changed files with 28 additions and 8 deletions
+3 -2
View File
@@ -849,13 +849,14 @@
<span id="button_worksheet" invisible="1"/>
<!-- Dummy tag used to organize buttons, englobing the 3 buttons modifies the width of the button -->
<span id="start_rating_buttons" invisible="1"/>
<field name="rating_avg" invisible="1"/>
<button name="action_open_ratings" type="object" attrs="{'invisible': [('rating_count', '=', 0)]}" class="oe_stat_button" groups="project.group_project_rating">
<i class="fa fa-fw o_button_icon fa-smile-o text-success" attrs="{'invisible': [('rating_avg', '&lt;', 3.66)]}" title="Satisfied"/>
<i class="fa fa-fw o_button_icon fa-meh-o text-warning" attrs="{'invisible': ['|', ('rating_avg', '&lt;', 2.33), ('rating_avg', '&gt;=', 3.66)]}" title="Okay"/>
<i class="fa fa-fw o_button_icon fa-frown-o text-danger" attrs="{'invisible': [('rating_avg', '&gt;=', 2.33)]}" title="Dissatisfied"/>
<div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="rating_avg" nolabel="1"/> / 5</span>
<span class="o_stat_text">Ratings</span>
<span class="o_stat_value"><field name="rating_avg_text" nolabel="1"/></span>
<span class="o_stat_text">Rating</span>
</div>
</button>
<!-- Dummy tag used to organize buttons -->
+7 -5
View File
@@ -10,6 +10,12 @@ from odoo.modules.module import get_resource_path
RATING_LIMIT_SATISFIED = 4
RATING_LIMIT_OK = 3
RATING_LIMIT_MIN = 1
RATING_TEXT = [
('top', 'Satisfied'),
('ok', 'Okay'),
('ko', 'Dissatisfied'),
('none', 'No Rating yet'),
]
class Rating(models.Model):
@@ -55,11 +61,7 @@ class Rating(models.Model):
partner_id = fields.Many2one('res.partner', string='Customer', help="Author of the rating")
rating = fields.Float(string="Rating Value", group_operator="avg", default=0, help="Rating value: 0=Unhappy, 5=Happy")
rating_image = fields.Binary('Image', compute='_compute_rating_image')
rating_text = fields.Selection([
('top', 'Satisfied'),
('ok', 'Okay'),
('ko', 'Dissatisfied'),
('none', 'No Rating yet')], string='Rating', store=True, compute='_compute_rating_text', readonly=True)
rating_text = fields.Selection(RATING_TEXT, string='Rating', store=True, compute='_compute_rating_text', readonly=True)
feedback = fields.Text('Comment', help="Reason of the rating")
message_id = fields.Many2one(
'mail.message', string="Message",
+18 -1
View File
@@ -5,7 +5,7 @@ from collections import defaultdict
from datetime import timedelta
from odoo import api, fields, models, tools
from odoo.addons.rating.models.rating import RATING_LIMIT_SATISFIED, RATING_LIMIT_OK, RATING_LIMIT_MIN
from odoo.addons.rating.models.rating import RATING_LIMIT_SATISFIED, RATING_LIMIT_OK, RATING_LIMIT_MIN, RATING_TEXT
from odoo.osv import expression
from odoo.tools.float_utils import float_compare
@@ -17,6 +17,9 @@ OPERATOR_MAPPING = {
'>': operator.gt,
'>=': operator.ge,
}
RATING_AVG_TOP = 3.66
RATING_AVG_OK = 2.33
RATING_AVG_MIN = RATING_LIMIT_MIN
class RatingParentMixin(models.AbstractModel):
@@ -98,6 +101,8 @@ class RatingMixin(models.AbstractModel):
rating_count = fields.Integer('Rating count', compute="_compute_rating_stats", compute_sudo=True)
rating_avg = fields.Float("Average Rating", groups='base.group_user',
compute='_compute_rating_stats', compute_sudo=True, search='_search_rating_avg')
rating_avg_text = fields.Selection(RATING_TEXT, groups='base.group_user',
compute='_compute_rating_avg_text', compute_sudo=True)
rating_percentage_satisfaction = fields.Float("Rating Satisfaction", compute='_compute_rating_satisfaction', compute_sudo=True)
rating_last_text = fields.Selection(string="Rating Text", groups='base.group_user', related="rating_ids.rating_text")
@@ -130,6 +135,18 @@ class RatingMixin(models.AbstractModel):
]
return [('id', 'in', res_ids)]
@api.depends('rating_avg')
def _compute_rating_avg_text(self):
for record in self:
if float_compare(record.rating_avg, RATING_AVG_TOP, 2) >= 0:
record.rating_avg_text = 'top'
elif float_compare(record.rating_avg, RATING_AVG_OK, 2) >= 0:
record.rating_avg_text = 'ok'
elif float_compare(record.rating_avg, RATING_AVG_MIN, 2) >= 0:
record.rating_avg_text = 'ko'
else:
record.rating_avg_text = 'none'
@api.depends('rating_ids.res_id', 'rating_ids.rating')
def _compute_rating_satisfaction(self):
""" Compute the rating satisfaction percentage, this is done separately from rating_count and rating_avg