def _compute_rating_satisfaction(self): """ Compute the rating satisfaction percentage, this is done separately from rating_count and rating_avg since the query is different, to avoid computing if it is not necessary""" domain = expression.AND([ self._rating_domain(), [('rating', '>=', rating_data.RATING_LIMIT_MIN)] ]) # See `_compute_rating_percentage_satisfaction` above read_group_res = self.env['rating.rating'].read_group( domain, ['res_id', 'rating'], groupby=['res_id', 'rating'], lazy=False) default_grades = {'great': 0, 'okay': 0, 'bad': 0} grades_per_record = { record_id: default_grades.copy() for record_id in self.ids } for group in read_group_res: record_id = group['res_id'] grade = rating_data._rating_to_grade(group['rating']) grades_per_record[record_id][grade] += group['__count'] for record in self: grade_repartition = grades_per_record.get(record.id, default_grades) grade_count = sum(grade_repartition.values()) record.rating_percentage_satisfaction = grade_repartition[ 'great'] * 100 / grade_count if grade_count else -1
def rating_get_grades(self, domain=None): """ get the repatition of rating grade for the given res_ids. :param domain : optional domain of the rating to include/exclude in grades computation :return dictionnary where the key is the grade (great, okay, bad), and the value, the number of object (res_model, res_id) having the grade the grade are compute as 0-30% : Bad 31-69%: Okay 70-100%: Great """ data = self._rating_get_repartition(domain=domain) res = dict.fromkeys(['great', 'okay', 'bad'], 0) for key in data: grade = rating_data._rating_to_grade(key) res[grade] += data[key] return res
def _compute_rating_percentage_satisfaction(self): # build domain and fetch data domain = [('parent_res_model', '=', self._name), ('parent_res_id', 'in', self.ids), ('rating', '>=', rating_data.RATING_LIMIT_MIN), ('consumed', '=', True)] if self._rating_satisfaction_days: domain += [ ('write_date', '>=', fields.Datetime.to_string(fields.datetime.now() - timedelta( days=self._rating_satisfaction_days))) ] data = self.env['rating.rating'].read_group( domain, ['parent_res_id', 'rating'], ['parent_res_id', 'rating'], lazy=False) # get repartition of grades per parent id default_grades = {'great': 0, 'okay': 0, 'bad': 0} grades_per_parent = dict( (parent_id, dict(default_grades)) for parent_id in self.ids) # map: {parent_id: {'great': 0, 'bad': 0, 'ok': 0}} rating_scores_per_parent = defaultdict( int) # contains the total of the rating values per record for item in data: parent_id = item['parent_res_id'] grade = rating_data._rating_to_grade(item['rating']) grades_per_parent[parent_id][grade] += item['__count'] rating_scores_per_parent[ parent_id] += item['rating'] * item['__count'] # compute percentage per parent for record in self: repartition = grades_per_parent.get(record.id, default_grades) rating_count = sum(repartition.values()) record.rating_count = rating_count record.rating_percentage_satisfaction = repartition[ 'great'] * 100 / rating_count if rating_count else -1 record.rating_avg = rating_scores_per_parent[ record.id] / rating_count if rating_count else 0 record.rating_avg_percentage = record.rating_avg / 5