[ADD] rating_project, rating_project_issue : using the rating mixin, tasks and issues are rated when their stage changed. A email template is sent to the customer of the object.

This commit is contained in:
aja-odoo
2015-01-08 12:28:22 +01:00
committed by Jérome Maes
parent b11e24c726
commit c8581af592
15 changed files with 459 additions and 0 deletions
+2
View File
@@ -44,6 +44,8 @@ class project_configuration(osv.osv_memory):
'module_project_issue': fields.boolean("Track issues and bugs",
help='Provides management of issues/bugs in projects.\n'
'-This installs the module project_issue.'),
'module_rating_project': fields.boolean('Allow customers to rate provided services',
help="This allows customers to give rating on provided services"),
'time_unit': fields.many2one('product.uom', 'Working time unit', required=True,
help="""This will set the unit of measure used in projects and tasks."""),
'module_project_issue_sheet': fields.boolean("Invoice working time on issues",
+4
View File
@@ -80,6 +80,10 @@
<field name="module_project_issue" class="oe_inline"/>
<label for="module_project_issue"/>
</div>
<div>
<field name="module_rating_project" class="oe_inline"/>
<label for="module_rating_project"/>
</div>
<div name="module_project_issue_sheet">
<field name="module_project_issue_sheet" class="oe_inline"/>
<label for="module_project_issue_sheet"/>
+21
View File
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Odoo, Open Source Management Solution
# Copyright (C) 2014-Today Odoo SA (<http://www.odoo.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import models
+21
View File
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
{
'name': 'Project Rating',
'version': '1.0',
'category': 'Hidden',
'description': """
This module Allows a customer to give rating on Project.
""",
'author': 'Odoo SA',
'website': 'http://odoo.com',
'depends': [
'rating',
'project'
],
'data': [
'data/project_data.xml',
'views/project_view.xml',
],
'demo': ['data/project_demo.xml'],
'installable': True,
}
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="rating_project_request_email_template" model="mail.template">
<field name="name">Rating Project Request</field>
<field name="email_from">${object.rated_partner_id.email or ''}</field>
<field name="subject">${object.res_name}</field>
<field name="model_id" ref="rating.model_rating_rating"/>
<field name="email_to" >${object.partner_id.email}</field>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<body>
<div style="max-width:600px; height:auto; margin-left:30px;">
<div style="margin-left:30px;align=center;">
Dear ${object.partner_id.name},
</div><br>
<div style="margin-left:30px;align=center;" width="60%">
We hope the services provided have met your expectations.
<br>If you have any more questions or comments, do not hesitate to reply to this e-mail.
<br><br>Please, help us to improve ourself by rating the service we provide.
</div><br>
<table style="margin-left:50px;" width="70%">
<tr>
<td>
<a href="/rating/${object.access_token}/10">
<img alt="Great" src="rating/static/src/img/rating_10.png" title="It was great"/>
</a>
</td>
<td>
<a href="/rating/${object.access_token}/5">
<img alt="Okay" src="rating/static/src/img/rating_5.png" title="It was okay"/>
</a>
</td>
<td>
<a href="/rating/${object.access_token}/0">
<img alt="Bad" src="rating/static/src/img/rating_0.png" title="It wasn't good"/>
</a>
</td>
</tr>
</table><br>
<h4 style="margin-left:30px;font-weight:normal;">Thank you </h4>
<h4 style="margin-left:30px;font-weight:normal;">${object.rated_partner_id.name or ''} </h4>
</div>
</body>
]]>
</field>
</record>
<!-- add the email template as value for the project stage 2 -->
<record id="project.project_stage_2" model="project.task.type">
<field name="rating_template_id" ref="rating_project_request_email_template"/>
</record>
</data>
</openerp>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="rating_task_1" model="rating.rating">
<field name="res_model">project.task</field>
<field name="res_id" ref="project.project_task_3"/>
</record>
<record id="rating_task_2" model="rating.rating">
<field name="res_model">project.task</field>
<field name="res_id" ref="project.project_task_8"/>
</record>
<record id="rating_task_3" model="rating.rating">
<field name="res_model">project.task</field>
<field name="res_id" ref="project.project_task_15"/>
</record>
<record id="rating_task_4" model="rating.rating">
<field name="res_model">project.task</field>
<field name="res_id" ref="project.project_task_18"/>
</record>
<record id="rating_task_5" model="rating.rating">
<field name="res_model">project.task</field>
<field name="res_id" ref="project.project_task_24"/>
</record>
<function model="rating.rating" name="apply_rating" eval="(10, 'project.task', ref('project.project_task_3'))"/>
<function model="rating.rating" name="apply_rating" eval="(0, 'project.task', ref('project.project_task_8'))"/>
<function model="rating.rating" name="apply_rating" eval="(5, 'project.task', ref('project.project_task_15'))"/>
<function model="rating.rating" name="apply_rating" eval="(10, 'project.task', ref('project.project_task_18'))"/>
<function model="rating.rating" name="apply_rating" eval="(10, 'project.task', ref('project.project_task_24'))"/>
</data>
</openerp>
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import project
+70
View File
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
from openerp import models, fields, api
class ProjectTaskType(models.Model):
_inherit = 'project.task.type'
rating_template_id = fields.Many2one(
'mail.template',
string='Rating Email Template',
domain=[('model', '=', 'rating.rating')],
help="Select an email template. An email will be sent to the customer when the task reach this step.")
class Task(models.Model):
_name = 'project.task'
_inherit = ['project.task', 'rating.mixin']
@api.multi
def write(self, values):
if 'stage_id' in values and values.get('stage_id'):
template = self.env['project.task.type'].browse(values.get('stage_id')).rating_template_id
if template:
rated_partner_id = self.user_id.partner_id
partner_id = self.partner_id
if partner_id and rated_partner_id:
self.rating_send_request(template, partner_id, rated_partner_id)
return super(Task, self).write(values)
class Project(models.Model):
_inherit = "project.project"
@api.one
@api.depends('percentage_satisfaction_task')
def _compute_percentage_satisfaction_project(self):
self.percentage_satisfaction_project = self.percentage_satisfaction_task
@api.one
@api.depends('tasks.rating_ids.rating')
def _compute_percentage_satisfaction_task(self):
activity = self.tasks.rating_get_grades()
self.percentage_satisfaction_task = activity['great'] * 100 / sum(activity.values()) if sum(activity.values()) else -1
@api.one
@api.depends('use_tasks')
def _display_happy_customer(self):
self.is_visible_happy_customer = self.use_tasks
percentage_satisfaction_task = fields.Integer(
compute='_compute_percentage_satisfaction_task', string='% Happy', store=True, default=-1)
percentage_satisfaction_project = fields.Integer(
compute="_compute_percentage_satisfaction_project", string="% Happy", store=True, default=-1)
is_visible_happy_customer = fields.Boolean(
compute="_display_happy_customer", string="Is Visible", store=True, default=True)
@api.multi
def action_view_task_rating(self):
""" return the action to see all the rating about the tasks of the project """
action = self.env['ir.actions.act_window'].for_xml_id('rating', 'action_view_rating')
return dict(action, domain=[('rating', '!=', -1), ('res_id', 'in', self.tasks.ids), ('res_model', '=', 'project.task')])
@api.multi
def action_view_all_rating(self):
""" return the action to see all the rating about the all sort of activity of the project (tasks, issues, ...) """
return self.action_view_task_rating()
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- project.project form view with rating satisfaction state button -->
<record id="view_project_project_rating_form" model="ir.ui.view">
<field name="name">project.project.rating.form.view</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="project.edit_project"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button name="action_view_task_rating"
attrs="{'invisible': ['|', ('use_tasks','=', False), ('percentage_satisfaction_task','=', -1)]}"
class="oe_stat_button"
type="object"
icon="fa-smile-o">
<field string="% Happy on task" name="percentage_satisfaction_task" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
<!-- inherit project.task.type form view to add email template for task -->
<record id="view_project_task_type_rating_form" model="ir.ui.view">
<field name="name">project.task.type.form.view.inherit</field>
<field name="model">project.task.type</field>
<field name="inherit_id" ref="project.task_type_edit"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='sequence']" position="after">
<field name="rating_template_id"/>
</xpath>
</field>
</record>
<record id="view_project_project_rating_kanban" model="ir.ui.view">
<field name="name">rating.project.project.kanban.inherit</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="project.view_project_kanban"/>
<field name="arch" type="xml">
<field name="use_tasks" position="after">
<field name="percentage_satisfaction_project" invisible="1"/>
<field name="is_visible_happy_customer" invisible="1"/>
</field>
<xpath expr="//div[contains(@class, 'oe_kanban_project_list')]" position="after">
<div class="row oe_margin_top_8 oe_kanban_project_list">
<a t-if="record.is_visible_happy_customer.raw_value and record.percentage_satisfaction_project.raw_value &gt; -1" name="action_view_all_rating" type="object" title="Percentage of happy people about this project">
<img t-if="record.percentage_satisfaction_project.raw_value &gt;= 0 and record.percentage_satisfaction_project.raw_value &lt;= 30" class="rating" src="rating/static/src/img/rating_0.png" style="width:10%;height:10%"></img>
<img t-if="record.percentage_satisfaction_project.raw_value &gt; 30 and record.percentage_satisfaction_project.raw_value &lt;= 69" class="rating" src="rating/static/src/img/rating_5.png" style="width:10%;height:10%"></img>
<img t-if="record.percentage_satisfaction_project.raw_value &gt;= 70" class="rating" src="rating/static/src/img/rating_10.png" style="width:10%;height:10%"></img>
<img t-if="record.percentage_satisfaction_project.raw_value &lt; 0" class="rating" src="rating/static/src/img/rating_-1.png" style="width:10%;height:10%"></img>
<t t-if="record.percentage_satisfaction_project.raw_value &gt;= 0">
<t t-raw="record.percentage_satisfaction_project.raw_value"/> %
</t>
</a>
</div>
</xpath>
</field>
</record>
</data>
</openerp>
+21
View File
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Odoo, Open Source Management Solution
# Copyright (C) 2014-Today Odoo SA (<http://www.odoo.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import models
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
{
'name': 'Issue Rating',
'version': '1.0',
'category': 'Hidden',
'description': """
This module allows a customer to give rating on Project Issue.
""",
'author': 'Odoo SA',
'website': 'http://odoo.com',
'depends': [
'rating_project',
'project_issue'
],
'data': [
'views/project_issue_view.xml',
],
'demo': [
'data/project_issue_demo.xml',
],
'installable': True,
'auto_install' : True,
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="rating_issue_1" model="rating.rating">
<field name="res_model">project.issue</field>
<field name="res_id" ref="project_issue.crm_case_outputincorrect0"/>
</record>
<record id="rating_issue_2" model="rating.rating">
<field name="res_model">project.issue</field>
<field name="res_id" ref="project_issue.crm_case_addmenustothemodule0"/>
</record>
<record id="rating_issue_3" model="rating.rating">
<field name="res_model">project.issue</field>
<field name="res_id" ref="project_issue.crm_case_improvereportsinhrms0"/>
</record>
<function model="rating.rating" name="apply_rating" eval="(10, 'project.issue',
ref('project_issue.crm_case_outputincorrect0'))"/>
<function model="rating.rating" name="apply_rating" eval="(0, 'project.issue',
ref('project_issue.crm_case_addmenustothemodule0'))"/>
<function model="rating.rating" name="apply_rating" eval="(5, 'project.issue',
ref('project_issue.crm_case_improvereportsinhrms0'))"/>
</data>
</openerp>
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import project_issue
@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models
class ProjectIssue(models.Model):
_name = "project.issue"
_inherit = ['project.issue', 'rating.mixin']
@api.multi
def write(self, values):
if 'stage_id' in values and values.get('stage_id'):
template = self.env['project.task.type'].browse(values.get('stage_id')).rating_template_id
if template:
rated_partner_id = self.user_id.partner_id
partner_id = self.partner_id
if partner_id and rated_partner_id:
self.rating_send_request(template, partner_id, rated_partner_id)
return super(ProjectIssue, self).write(values)
class Project(models.Model):
_inherit = "project.project"
@api.multi
@api.depends('percentage_satisfaction_task', 'percentage_satisfaction_issue')
def _compute_percentage_satisfaction_project(self):
super(Project, self)._compute_percentage_satisfaction_project()
Rating = self.env['rating.rating']
for record in self.filtered(lambda record: record.use_tasks or record.use_issues):
if record.use_tasks or record.use_issues:
# built the domain according the project parameters (use tasks and/or issues)
res_models = []
domain = []
if record.use_tasks:
res_models.append('project.task')
domain += ['&', ('res_model', '=', 'project.task'), ('res_id', 'in', record.tasks.ids)]
if record.use_issues:
res_models.append('project.issue')
domain += ['&', ('res_model', '=', 'project.issue'), ('res_id', 'in', record.issue_ids.ids)]
if len(res_models) == 2:
domain = ['|'] + domain
domain = ['&', ('rating', '>=', 0)] + domain
# get the number of rated tasks and issues with a read_group (more perfomant !)
grouped_data = Rating.read_group(domain, ['res_model'], ['res_model'])
# compute the number of each model and total number
res = dict.fromkeys(res_models, 0)
for data in grouped_data:
res[data['res_model']] += data['res_model_count']
nbr_rated_task = res.get('project.task', 0)
nbr_rated_issue = res.get('project.issue', 0)
nbr_project_rating = nbr_rated_issue + nbr_rated_task
# compute the weighted arithmetic average
ratio_task = float(nbr_rated_task) / float(nbr_project_rating) if nbr_project_rating else 0
ratio_issue = float(nbr_rated_issue) / float(nbr_project_rating) if nbr_project_rating else 0
record.percentage_satisfaction_project = round((ratio_task*record.percentage_satisfaction_task)+(ratio_issue*record.percentage_satisfaction_issue)) if nbr_project_rating else -1
else:
record.percentage_satisfaction_project = -1
@api.one
@api.depends('issue_ids.rating_ids.rating')
def _compute_percentage_satisfaction_issue(self):
project_issue = self.env['project.issue'].search([('project_id', '=', self.id)])
activity = project_issue.rating_get_grades()
self.percentage_satisfaction_issue = activity['great'] * 100 / sum(activity.values()) if sum(activity.values()) else -1
@api.one
@api.depends('use_tasks', 'use_issues')
def _display_happy_customer(self):
self.is_visible_happy_customer = self.use_tasks if self.use_tasks else self.use_issues
percentage_satisfaction_issue = fields.Integer(compute='_compute_percentage_satisfaction_issue', string='% Happy', store=True, default=-1)
@api.multi
def action_view_issue_rating(self):
""" return the action to see all the rating about the issues of the project """
action = self.env['ir.actions.act_window'].for_xml_id('rating', 'action_view_rating')
issues = self.env['project.issue'].search([('project_id', 'in', self.ids)])
return dict(action, domain=[('res_id', 'in', issues.ids), ('res_model', '=', 'project.issue')])
@api.multi
def action_view_all_rating(self):
action = super(Project, self).action_view_all_rating()
task_domain = action['domain'][1:] # remove the (rating != -1) condition
domain = []
if self.use_tasks: # add task domain, if neeeded
domain = ['&'] + task_domain
if self.use_issues: # add issue domain if needed
issues = self.env['project.issue'].search([('project_id', 'in', self.ids)])
domain = domain + ['&', ('res_id', 'in', issues.ids), ('res_model', '=', 'project.issue')]
if self.use_tasks and self.use_issues:
domain = ['|'] + domain
domain = [('rating', '!=', -1)] + domain # prepend the condition to avoid empty rating
return dict(action, domain=domain)
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- inherit get state button on project -->
<record id="project_issue_view_rating" model="ir.ui.view">
<field name="name">project.issue.view.rating</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="project.edit_project"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button name="action_view_issue_rating"
attrs="{'invisible': ['|', ('use_issues','=', False), ('percentage_satisfaction_issue','=', -1)]}"
class="oe_stat_button"
type="object"
icon="fa-smile-o">
<field string="% Happy on issue" name="percentage_satisfaction_issue" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
</data>
</openerp>