Merge lp:~openerp-dev/openobject-addons/trunk-rating-aja into lp:openobject-addons

Proposed by Mahendra Barad(OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-rating-aja
Merge into: lp:openobject-addons
Diff against target: 1255 lines (+1077/-1)
28 files modified
base_setup/res_config.py (+3/-1)
base_setup/res_config_view.xml (+9/-0)
rating/__openerp__.py (+44/-0)
rating/static/src/js/rating.js (+24/-0)
rating/static/src/xml/rating.xml (+9/-0)
rating/views/rating.xml (+11/-0)
rating_issue/__init__.py (+2/-0)
rating_issue/__openerp__.py (+41/-0)
rating_issue/controllers/__init__.py (+3/-0)
rating_issue/controllers/main.py (+61/-0)
rating_issue/project_issue.py (+77/-0)
rating_issue/project_issue_data.xml (+55/-0)
rating_issue/project_issue_view.xml (+104/-0)
rating_project/__init__.py (+2/-0)
rating_project/__openerp__.py (+45/-0)
rating_project/controllers/__init__.py (+3/-0)
rating_project/controllers/main.py (+41/-0)
rating_project/project.py (+54/-0)
rating_project/project_data.xml (+58/-0)
rating_project/project_demo.xml (+24/-0)
rating_project/project_view.xml (+110/-0)
rating_sale/__init__.py (+3/-0)
rating_sale/__openerp__.py (+48/-0)
rating_sale/controllers/__init__.py (+3/-0)
rating_sale/controllers/main.py (+21/-0)
rating_sale/rate_product.py (+87/-0)
rating_sale/rate_product_view.xml (+132/-0)
rating_sale/security/ir.model.access.csv (+3/-0)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-rating-aja
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+218008@code.launchpad.net
To post a comment you must log in.
9361. By Mahendra Barad(OpenERP)

[IMP]fix typo and js loading

9362. By Mahendra Barad(OpenERP)

[IMP]change location of rating template

9363. By Mahendra Barad(OpenERP)

[IMP]improve the view of button and template

9364. By Mahendra Barad(OpenERP)

[IMP]fix typo

9365. By Mahendra Barad(OpenERP)

[Merge]with trunk

9366. By Mahendra Barad(OpenERP)

[IMP]mail template

9367. By Mahendra Barad(OpenERP)

[IMP]text color of template and domain to publish rating in rating issue and project

9368. By Mahendra Barad(OpenERP)

[Merge]with trunk

9369. By Mahendra Barad(OpenERP)

[ADD]survey module in project issue

Unmerged revisions

9369. By Mahendra Barad(OpenERP)

[ADD]survey module in project issue

9368. By Mahendra Barad(OpenERP)

[Merge]with trunk

9367. By Mahendra Barad(OpenERP)

[IMP]text color of template and domain to publish rating in rating issue and project

9366. By Mahendra Barad(OpenERP)

[IMP]mail template

9365. By Mahendra Barad(OpenERP)

[Merge]with trunk

9364. By Mahendra Barad(OpenERP)

[IMP]fix typo

9363. By Mahendra Barad(OpenERP)

[IMP]improve the view of button and template

9362. By Mahendra Barad(OpenERP)

[IMP]change location of rating template

9361. By Mahendra Barad(OpenERP)

[IMP]fix typo and js loading

9360. By Mahendra Barad(OpenERP)

[Merge]with trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'base_setup/res_config.py'
--- base_setup/res_config.py 2014-02-17 13:48:19 +0000
+++ base_setup/res_config.py 2014-05-12 07:24:43 +0000
@@ -43,6 +43,8 @@
43 help="""This installs the module google_calendar."""),43 help="""This installs the module google_calendar."""),
44 'font': fields.many2one('res.font', string="Report Font", domain=[('mode', 'in', ('Normal', 'Regular', 'all', 'Book'))],44 'font': fields.many2one('res.font', string="Report Font", domain=[('mode', 'in', ('Normal', 'Regular', 'all', 'Book'))],
45 help="Set the font into the report header, it will be used as default font in the RML reports of the user company"),45 help="Set the font into the report header, it will be used as default font in the RML reports of the user company"),
46 'module_rating': fields.boolean('Allow your customer to rate the services and products provided',
47 help="This allows customers to give rating on Product/Services")
4648
47 }49 }
48 50
@@ -108,4 +110,4 @@
108 help='Get access to statistics with your mass mailing, manage campaigns.'),110 help='Get access to statistics with your mass mailing, manage campaigns.'),
109 }111 }
110112
111# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
112\ No newline at end of file113\ No newline at end of file
114# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
113115
=== modified file 'base_setup/res_config_view.xml'
--- base_setup/res_config_view.xml 2014-02-17 13:48:19 +0000
+++ base_setup/res_config_view.xml 2014-05-12 07:24:43 +0000
@@ -73,6 +73,15 @@
73 </div>73 </div>
74 </group>74 </group>
75 <group>75 <group>
76 <label for="id" string="Rating"/>
77 <div>
78 <div>
79 <field name="module_rating" class="oe_inline"/>
80 <label for="module_rating"/>
81 </div>
82 </div>
83 </group>
84 <group>
76 <label for="id" string="Google Drive"/>85 <label for="id" string="Google Drive"/>
77 <div name="google_drive">86 <div name="google_drive">
78 <div name="module_google_drive">87 <div name="module_google_drive">
7988
=== added directory 'rating'
=== added file 'rating/__init__.py'
=== added file 'rating/__openerp__.py'
--- rating/__openerp__.py 1970-01-01 00:00:00 +0000
+++ rating/__openerp__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,44 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 'name': 'Customer Rating',
24 'version': '1.0',
25 'category': 'Tools',
26 'description': """
27This module Allows a customer to give rating.
28""",
29 'author': 'OpenERP SA',
30 'website': 'http://openerp.com',
31 'depends': [
32 'mail','survey',
33 ],
34 'data': [
35 'views/rating.xml',
36 ],
37 'qweb': ['static/src/xml/rating.xml'],
38 'installable': True,
39 'application': True,
40 'auto_install': False,
41 'bootstrap': True,
42}
43
44# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
045
=== added directory 'rating/static'
=== added directory 'rating/static/src'
=== added directory 'rating/static/src/img'
=== added file 'rating/static/src/img/bad.png'
1Binary files rating/static/src/img/bad.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/bad.png 2014-05-12 07:24:43 +0000 differ46Binary files rating/static/src/img/bad.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/bad.png 2014-05-12 07:24:43 +0000 differ
=== added file 'rating/static/src/img/great.png'
2Binary files rating/static/src/img/great.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/great.png 2014-05-12 07:24:43 +0000 differ47Binary files rating/static/src/img/great.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/great.png 2014-05-12 07:24:43 +0000 differ
=== added file 'rating/static/src/img/okay.png'
3Binary files rating/static/src/img/okay.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/okay.png 2014-05-12 07:24:43 +0000 differ48Binary files rating/static/src/img/okay.png 1970-01-01 00:00:00 +0000 and rating/static/src/img/okay.png 2014-05-12 07:24:43 +0000 differ
=== added directory 'rating/static/src/js'
=== added file 'rating/static/src/js/rating.js'
--- rating/static/src/js/rating.js 1970-01-01 00:00:00 +0000
+++ rating/static/src/js/rating.js 2014-05-12 07:24:43 +0000
@@ -0,0 +1,24 @@
1openerp.rating = function(instance) {
2
3var QWeb = instance.web.qweb;
4
5instance.web_kanban.RatingSmily = instance.web_kanban.AbstractField.extend({
6 init: function(parent, field, $node) {
7 this._super.apply(this, arguments);
8 this.parent = parent;
9 var domain = []
10 domain.push([this.field.relation_field, '=', this.parent.id])
11 if (_.contains(['project.task', 'project.issue'], this.field.relation))
12 domain.push(['rating_published', '=', true])
13 this.dataset = new instance.web.DataSetSearch(this, this.field.relation, {}, domain);
14 },
15 renderElement: function() {
16 var self = this;
17 self.dataset.read_slice(self.options.rating_field).then(function(result) {
18 self.$el.append($(QWeb.render("RatingSmily", {'widget': result})));
19 });
20 },
21});
22
23instance.web_kanban.fields_registry.add('rating_smily','instance.web_kanban.RatingSmily');
24};
025
=== added directory 'rating/static/src/xml'
=== added file 'rating/static/src/xml/rating.xml'
--- rating/static/src/xml/rating.xml 1970-01-01 00:00:00 +0000
+++ rating/static/src/xml/rating.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,9 @@
1<template>
2 <t t-name="RatingSmily">
3 <t t-foreach="widget" t-as="rec" >
4 <t t-if="rec.rating_state">
5 <img t-attf-src="rating/static/src/img/#{rec.rating_state}.png" class="oe_kanban_image" t-att-title="rec.name or rated_user[1]"/>
6 </t>
7 </t>
8 </t>
9</template>
010
=== added directory 'rating/views'
=== added file 'rating/views/rating.xml'
--- rating/views/rating.xml 1970-01-01 00:00:00 +0000
+++ rating/views/rating.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<openerp>
4 <data>
5 <template id="assets_backend" name="rating assets" inherit_id="web.assets_backend">
6 <xpath expr="." position="inside">
7 <script type="text/javascript" src="/rating/static/src/js/rating.js"></script>
8 </xpath>
9 </template>
10 </data>
11</openerp>
012
=== added directory 'rating_issue'
=== added file 'rating_issue/__init__.py'
--- rating_issue/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_issue/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,2 @@
1import project_issue
2import controllers
03
=== added file 'rating_issue/__openerp__.py'
--- rating_issue/__openerp__.py 1970-01-01 00:00:00 +0000
+++ rating_issue/__openerp__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,41 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 'name': 'Issue Rating',
24 'version': '1.0',
25 'category': 'Hidden',
26 'description': """
27This module Allows a customer to give rating on Project Issue.
28""",
29 'author': 'OpenERP SA',
30 'website': 'http://openerp.com',
31 'depends': [
32 'rating',
33 'project_issue'
34 ],
35 'data': ['project_issue_data.xml','project_issue_view.xml'],
36 'installable': True,
37 'auto_install': True,
38 'bootstrap': True,
39}
40
41# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
042
=== added directory 'rating_issue/controllers'
=== added file 'rating_issue/controllers/__init__.py'
--- rating_issue/controllers/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_issue/controllers/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,3 @@
1import main
2
3# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
04
=== added file 'rating_issue/controllers/main.py'
--- rating_issue/controllers/main.py 1970-01-01 00:00:00 +0000
+++ rating_issue/controllers/main.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,61 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import werkzeug
23from openerp.addons.web.http import request
24from openerp.addons.web.controllers.main import login_redirect
25from openerp.addons.web import http
26
27class IssueRating(http.Controller):
28
29 @http.route('/project/issue/rating', type='http', auth="public")
30 def rating(self, action, id, state=None, **post):
31 if not request.session.uid:
32 return login_redirect()
33 issue_pool = request.registry['project.issue']
34 values = {
35 'rating_state': str(state)
36 }
37 rated_stage_id = request.registry['project.task.type'].search(request.cr, request.uid, [('name','=','Rated')], context=request.context)
38 if rated_stage_id:
39 values['stage_id'] = rated_stage_id[0]
40 task_pool.write(request.cr, request.uid, [int(id)], values, context=request.context)
41 return werkzeug.utils.redirect('/web#id=%s&db=%s&view_type=form&action=%s'%(id, request.db, action))
42
43 @http.route(['/survey/start/<model("survey.survey"):survey>/<int:id>',
44 '/survey/start/<model("survey.survey"):survey>/<string:token>/<int:id>'],
45 type='http', auth='public', multilang=True, website=True)
46 def rating_survey(self, survey, token=None, id=None, **post):
47 cr, uid, context = request.cr, request.uid, request.context
48 issue_obj = request.registry['project.issue']
49 survey_obj = request.registry['survey.survey']
50 user_input_obj = request.registry['survey.user_input']
51 issue = issue_obj.browse(cr, uid, id, context=context)
52 if not issue.response_id:
53 response_id = user_input_obj.create(cr, uid, {'survey_id': survey.id}, context=context)
54 issue_obj.write(cr, uid, id, {'response_id': response_id}, context=context)
55 else:
56 response_id = issue.response_id.id
57 user_input = user_input_obj.browse(cr, uid, [response_id], context=context)[0]
58 # Select the right page
59 if user_input.state == 'new': # Intro page
60 data = {'survey': survey, 'page': None, 'token': user_input.token}
61 return request.website.render('survey.survey_init', data)
062
=== added file 'rating_issue/project_issue.py'
--- rating_issue/project_issue.py 1970-01-01 00:00:00 +0000
+++ rating_issue/project_issue.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,77 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import fields, osv
23
24class ProjectIssue(osv.Model):
25 _inherit = 'project.issue'
26 _columns = {
27 'rating_state': fields.selection([('great', 'Great'),('okay', 'Okay'),('bad', 'Not Good')], 'Rating'),
28 'rating_published': fields.boolean('Publish', help="Publish on the Issue"),
29 'stage_name': fields.related('stage_id', 'name', type='char', string='Stage Name', readonly=True),
30 'response_id': fields.many2one('survey.user_input', "Response"),
31 'survey': fields.related('project_id', 'survey_id', type='many2one', relation='survey.survey', string='Survey'),
32 }
33
34 def send_rating_request(self, cr, uid, ids, context=None):
35 data_pool = self.pool['ir.model.data']
36 template_pool = self.pool['email.template']
37 mail_pool = self.pool['mail.mail']
38 res = False
39 local_context = context.copy()
40 issue = self.browse(cr, uid, ids[0],context)
41 dummy, template_id = data_pool.get_object_reference(cr, uid, 'rating_issue', 'issue_rating_request')
42 dummy, act_id = data_pool.get_object_reference(cr, uid, 'project_issue', 'project_issue_form_view')
43 local_context.update({
44 'action_id': self.pool['ir.actions.act_window'].search(cr, uid, [('view_id', '=', act_id)], context=context)[0],
45 'survey': 1
46 })
47 mail_id = template_pool.send_mail(cr, uid, template_id, issue.id, context=local_context)
48 if mail_id:
49 res = mail_pool.send(cr, uid, [mail_id], context=context)
50 return res
51
52 def set_rating_state_published(self, cr, uid, ids, context=None):
53 return self.write(cr, uid, ids, {'rating_published': True}, context=context)
54 def set_rating_state_unpublished(self, cr, uid, ids, context=None):
55 return self.write(cr, uid, ids, {'rating_published': False}, context=context)
56
57 def action_print_survey(self, cr, uid, ids, context=None):
58 """ If response is available then print this response otherwise print survey form (print template of the survey) """
59 context = context if context else {}
60 tasks = self.browse(cr, uid, ids, context=context)[0]
61 survey_obj = self.pool.get('survey.survey')
62 response_obj = self.pool.get('survey.user_input')
63 if not tasks.response_id:
64 return survey_obj.action_print_survey(cr, uid, [tasks.survey.id], context=context)
65 else:
66 response = response_obj.browse(cr, uid, tasks.response_id.id, context=context)
67 context.update({'survey_token': response.token})
68 return survey_obj.action_print_survey(cr, uid, [tasks.survey.id], context=context)
69
70class Project(osv.Model):
71 _inherit = "project.project"
72
73 _columns = {
74 'issues': fields.one2many('project.issue', 'project_id', "Issue Activities"),
75 'survey_id': fields.many2one('survey.survey', 'Task Survey'),
76 }
77
078
=== added file 'rating_issue/project_issue_data.xml'
--- rating_issue/project_issue_data.xml 1970-01-01 00:00:00 +0000
+++ rating_issue/project_issue_data.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,55 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="issue_rating_request" model="email.template">
5 <field name="name">Issue Rating Request</field>
6 <field name="email_from">${object.user_id.email or ''}</field>
7 <field name="subject">${object.name}</field>
8 <field name="model_id" ref="rating_issue.model_project_issue"/>
9 <field name="email_to" >${object.partner_id.email}</field>
10 <field name="partner_to">${object.partner_id.id}</field>
11 <field name="auto_delete" eval="True"/>
12 <field name="body_html"><![CDATA[
13<body>
14 <div style="height:auto;text-align: center;font-size : 30px;color: #8A89BA;">
15 <strong>${object.name or ''}</strong>
16 </div>
17
18 <div style="max-width:600px; height:auto; margin-left:30px; margin-top:0px;">
19 <p>Information about the ${object.name or ''}</p>
20 <p>Project : ${object.project_id.name or ''} </p>
21 <p>Assigned To : ${object.user_id.name or ''} </p>
22 <p>Description : ${object.description or ''} </p>
23 <p>I haven't heard since long over Support Ticket : ${object.name or ''} </p>
24 <p>I hope the information provided to you would have helped you.<br/>
25For now, I am closing this case but if yo find any difficulty with this Ticket just reply to this mail and your Ticket will be re-opened Automatically. </p>
26 <strong>Help us to improve our process by rating our work</strong>
27 <div style="margin-top:20px;max-width:600px;height:200px;align=center;" >
28 <div style="width:170px;align:center;float:left;">
29 <a href="/project/issue/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=great">
30 <img style="margin-left:20px; margin-top:10px; " alt="Great" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzJCRDBCRjAyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzJCRDBCRjEyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJFRTI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJEMEJFRjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpDqubAAABBwSURBVHja7FxrkBXF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" />
31 </a>
32 <div style="margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:green;">It was great</div>
33 </div>
34 <div style="width:170px;align:center;float:left;">
35 <a href="/project/issue/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=okay">
36 <img style="margin-left:50px; margin-top:10px;" alt="Idle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzJCRDBCRjQyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzJCRDBCRjUyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJGMjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJEMEJGMzI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pu56lwQAAAotSURBVHja7FxdbFRF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" />
37 </a>
38 <div style="margin-left:48px;margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:orange;">It was ok</div>
39 </div>
40 <div style="width:230px;align:center;float:left;">
41 <a href="/project/issue/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=bad">
42 <img style="margin-left:95px; margin-top:10px;" alt="Bad" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzU4MEJGMDEyOEJEMTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzU4MEJGMDIyOEJEMTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJGNjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NTgwQkYwMDI4QkQxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlrzXtkAABC0SURBVHja7Jx7jFbF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" />
43 </a>
44 <div style="margin-left:70px;margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:red;">It wasn't good</div>
45 </div>
46 <div style="width:170px;align:center;float:left;"><p>Thanks <br/>The support team</p></div>
47 </div>
48 <div style="font-size:13px;"><a href="/survey/start/${'survey' in ctx and ctx['survey'] or ''}/phantom/${object.id}">Fill the survey</a></div>
49 </div>
50</body>
51 ]]>
52 </field>
53 </record>
54 </data>
55</openerp>
056
=== added file 'rating_issue/project_issue_view.xml'
--- rating_issue/project_issue_view.xml 1970-01-01 00:00:00 +0000
+++ rating_issue/project_issue_view.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,104 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="project_issue_form_view_rating_inherit" model="ir.ui.view">
5 <field name="name">issue rating</field>
6 <field name="model">project.issue</field>
7 <field name="inherit_id" ref="project_issue.project_issue_form_view" />
8 <field name="arch" type="xml">
9 <xpath expr="//field[@name='kanban_state']" position="after">
10 <field name="rating_state" invisible='1'/>
11 <field name="survey" invisible='1'/>
12 <div class="oe_right" attrs="{'invisible': [('stage_name', '!=', 'Rated')]}">
13 <button name="action_print_survey" class="oe_stat_button" icon="fa-print" type="object" help="Print survey report" attrs="{'invisible':[('survey','=',False)]}">
14 <div>Print<br/>Interview</div>
15 </button>
16 <img src="rating/static/src/img/great.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'great')]}"/>
17 <img src="rating/static/src/img/okay.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'okay')]}"/>
18 <img src="rating/static/src/img/bad.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'bad')]}"/>
19 </div>
20 </xpath>
21 <xpath expr="//header" position="inside">
22 <field name="stage_name" invisible="1"/>
23 <field name="rating_published" invisible="1"/>
24 <button name="send_rating_request" string="Send a Rating Request" type="object" attrs="{'invisible': [('stage_name', '!=', 'Done')]}"/>
25 <button name="set_rating_state_published" type="object" string="Publish Rating" attrs="{'invisible': ['|',('stage_name', '!=', 'Rated'),('rating_published', '=', True)]}"/>
26 <button name="set_rating_state_unpublished" type="object" string="UnPublish Rating" attrs="{'invisible': ['|',('stage_name', '!=', 'Rated'),('rating_published', '=', False)]}"/>
27 </xpath>
28 </field>
29 </record>
30
31 <record model="ir.ui.view" id="view_issue_kanban_faces">
32 <field name="name">project.issue.kanban</field>
33 <field name="model">project.project</field>
34 <field name="arch" type="xml">
35 <kanban version="7.0" create="false" class="oe_background_grey">
36 <field name="name"/>
37 <field name="user_id"/>
38 <field name="issues"/>
39 <templates>
40 <t t-name="kanban-box">
41 <div class="oe_kanban_color_0 oe_kanban_card">
42 <div class="oe_kanban_content">
43 <center><h4>Project : <field name="name"/></h4></center>
44 <div class="oe_center" t-if="record.user_id.raw_value">
45 <center><small>Assigned To : <t t-raw="record.user_id.raw_value[1]"/></small></center>
46 <br/><b>Ratings </b><br/>
47 </div>
48 <div class="oe_items_list" style="width:284px">
49 <field name="issues" widget="rating_smily" options="{'rating_field': ['rating_state','name', 'project_id']}" />
50 </div>
51 </div>
52 </div>
53 </t>
54 </templates>
55 </kanban>
56 </field>
57 </record>
58
59 <record id="action_view_issue_faces" model="ir.actions.act_window">
60 <field name="name">Issues Faces</field>
61 <field name="type">ir.actions.act_window</field>
62 <field name="domain">[('id', '=', active_id)]</field>
63 <field name="res_model">project.project</field>
64 <field name="view_mode">kanban</field>
65 </record>
66
67 <record id="action_view_issue_faces_view" model="ir.actions.act_window.view">
68 <field eval="0" name="sequence"/>
69 <field name="view_mode">kanban</field>
70 <field name="view_id" ref="view_issue_kanban_faces"/>
71 <field name="act_window_id" ref="action_view_issue_faces"/>
72 </record>
73
74 <record id="project_issue_view_rating" model="ir.ui.view">
75 <field name="name">project.issue.view.rating</field>
76 <field name="model">project.project</field>
77 <field name="inherit_id" ref="project.edit_project"/>
78 <field name="priority" eval="20"/>
79 <field name="arch" type="xml">
80 <xpath expr="//div[@name='buttons']" position="inside">
81 <button name="%(action_view_issue_faces)d" type="action" string="Rating(Issues)" icon="fa-star" class="oe_stat_button"/>
82 </xpath>
83 </field>
84 </record>
85
86 <!-- Overwrite the project_issue action to add view_id -->
87 <record model="ir.actions.act_window" id="project_issue.project_issue_categ_act0">
88 <field name="name">Issues</field>
89 <field name="res_model">project.issue</field>
90 <field name="view_type">form</field>
91 <field name="view_mode">kanban,tree,calendar</field>
92 <field name="view_id" ref="project_issue.project_issue_form_view"/>
93 <field name="domain" eval=""/>
94 <field name="search_view_id" ref="project_issue.view_project_issue_filter"/>
95 <field name="help" type="html">
96 <p>
97 The OpenERP issues tacker allows you to efficiantly manage things
98 like internal requests, software development bugs, customer
99 complaints, project troubles, material breakdowns, etc.
100 </p>
101 </field>
102 </record>
103 </data>
104</openerp>
0105
=== added directory 'rating_project'
=== added file 'rating_project/__init__.py'
--- rating_project/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_project/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,2 @@
1import project
2import controllers
03
=== added file 'rating_project/__openerp__.py'
--- rating_project/__openerp__.py 1970-01-01 00:00:00 +0000
+++ rating_project/__openerp__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,45 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 'name': 'Project Rating',
24 'version': '1.0',
25 'category': 'Hidden',
26 'description': """
27This module Allows a customer to give rating on Project.
28""",
29 'author': 'OpenERP SA',
30 'website': 'http://openerp.com',
31 'depends': [
32 'rating',
33 'project'
34 ],
35 'data': [
36 'project_data.xml',
37 'project_view.xml',
38 ],
39 'demo': ['project_demo.xml'],
40 'installable': True,
41 'auto_install': True,
42 'bootstrap': True,
43}
44
45# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
046
=== added directory 'rating_project/controllers'
=== added file 'rating_project/controllers/__init__.py'
--- rating_project/controllers/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_project/controllers/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,3 @@
1import main
2
3# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
04
=== added file 'rating_project/controllers/main.py'
--- rating_project/controllers/main.py 1970-01-01 00:00:00 +0000
+++ rating_project/controllers/main.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,41 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import werkzeug
23from openerp.addons.web.http import request
24from openerp.addons.web.controllers.main import login_redirect
25from openerp.addons.web import http
26
27class TaskRating(http.Controller):
28
29 @http.route('/project/task/rating', type='http', auth="public")
30 def rating(self, action, id, state=None, **post):
31 if not request.session.uid:
32 return login_redirect()
33 task_pool = request.registry['project.task']
34 values = {
35 'rating_state': str(state)
36 }
37 rated_stage_id = request.registry['project.task.type'].search(request.cr, request.uid, [('name','=','Rated')], context=request.context)
38 if rated_stage_id:
39 values['stage_id'] = rated_stage_id[0]
40 task_pool.write(request.cr, request.uid, [int(id)], values, context=request.context)
41 return werkzeug.utils.redirect('/web#id=%s&view_type=form&action=%s'%(id, action))
042
=== added file 'rating_project/project.py'
--- rating_project/project.py 1970-01-01 00:00:00 +0000
+++ rating_project/project.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,54 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import fields, osv
23
24class Task(osv.Model):
25 _inherit = 'project.task'
26 _columns = {
27 'rating_state': fields.selection([('great', 'Great'),('okay', 'Okay'),('bad', 'Not Good')], 'Rating'),
28 'rating_published': fields.boolean('Publish', help="Publish on the task"),
29 'stage_name': fields.related('stage_id', 'name', type='char', string='Stage Name', readonly=True),
30 'survey_id': fields.many2one('survey.survey', 'Task Survey'),
31 }
32
33 def send_rating_request(self, cr, uid, ids, context=None):
34 data_pool = self.pool['ir.model.data']
35 template_pool = self.pool['email.template']
36 mail_pool = self.pool['mail.mail']
37 res = False
38 local_context = context.copy()
39 task = self.browse(cr, uid, ids[0],context)
40 dummy, template_id = data_pool.get_object_reference(cr, uid, 'rating_project', 'task_rating_request')
41 dummy, act_id = data_pool.get_object_reference(cr, uid, 'project', "view_task_form2")
42 local_context.update({
43 'action_id': self.pool['ir.actions.act_window'].search(cr, uid, [('view_id', '=', act_id)], context=context)[0],
44 'survey': self.pool['survey.survey'].search(cr, uid, [('title', '=', 'User Feedback Form')], context=context)[0]
45 })
46 mail_id = template_pool.send_mail(cr, uid, template_id, task.id, context=local_context)
47 if mail_id:
48 res = mail_pool.send(cr, uid, [mail_id], context=context)
49 return res;
50
51 def set_rating_state_published(self, cr, uid, ids, context=None):
52 return self.write(cr, uid, ids, {'rating_published': True}, context=context)
53 def set_rating_state_unpublished(self, cr, uid, ids, context=None):
54 return self.write(cr, uid, ids, {'rating_published': False}, context=context)
055
=== added file 'rating_project/project_data.xml'
--- rating_project/project_data.xml 1970-01-01 00:00:00 +0000
+++ rating_project/project_data.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,58 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="project_tt_rated" model="project.task.type">
5 <field name="sequence">25</field>
6 <field name="name">Rated</field>
7 <field name="case_default" eval="True"/>
8 <field name="fold" eval="True"/>
9 </record>
10
11 <record id="task_rating_request" model="email.template">
12 <field name="name">Task Rating Request</field>
13 <field name="email_from">${object.user_id.email or ''}</field>
14 <field name="subject">${object.name}</field>
15 <field name="model_id" ref="rating_project.model_project_task"/>
16 <field name="email_to" >${object.partner_id.email}</field>
17 <field name="partner_to">${object.partner_id.id}</field>
18 <field name="auto_delete" eval="True"/>
19 <field name="body_html"><![CDATA[
20<body>
21 <div style="height:auto; margin-left:30px; margin-top:10px;">
22 <br><h1 style="margin-top:15px; margin-bottom:20px;color:#A9AEE1;" align="center">${object.name or ''}</h1>
23 </div>
24 <div style="max-width:600px; height:auto; margin-left:30px;">
25 <br><h4 style="margin-left:50px;font-weight:normal;">Information about the ${object.name or ''} </h4>
26 <h4 style="margin-left:50px;font-weight:normal;">Project : ${object.project_id.name or ''} </h4>
27 <h4 style="margin-left:50px;font-weight:normal;">Assigned To : ${object.user_id.name or ''} </h4>
28 <h4 style="margin-left:50px;font-weight:normal;">Description : ${object.description or ''} </h4>
29 <h4 style="margin-left:50px;">How was the ${object.name or ''} provided?</h4>
30 <div style="max-width:600px;height:150px;align=center;" >
31 <div style="width:170px;align:center;float:left;">
32 <a href="/project/task/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=great">
33 <img style="margin-left:60px; margin-top:10px; " alt="Great" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzJCRDBCRjAyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzJCRDBCRjEyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJFRTI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJEMEJFRjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpDqubAAABBwSURBVHja7FxrkBXF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" />
34 </a>
35 <div style="margin-left:40px;margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:green;">It was great</div>
36 </div>
37 <div style="width:170px;align:center;float:left;">
38 <a href="/project/task/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=okay">
39 <img style="margin-left:70px; margin-top:10px;" alt="Idle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzJCRDBCRjQyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzJCRDBCRjUyOEI5MTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJGMjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJEMEJGMzI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pu56lwQAAAotSURBVHja7FxdbFRF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" />
40 </a>
41
42 <div style="margin-left:68px;margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:orange;">It was ok</div>
43 </div>
44 <div style="width:230px;align:center;float:left;">
45 <a href="/project/task/rating?action=${'action_id' in ctx and ctx['action_id'] or ''}&id=${object.id}&state=bad">
46 <img style="margin-left:95px; margin-top:10px;" alt="Bad" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzU4MEJGMDEyOEJEMTFFMDg5NzlBMzRDQTEwNDgyQTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzU4MEJGMDIyOEJEMTFFMDg5NzlBMzRDQTEwNDgyQTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkJEMEJGNjI4QjkxMUUwODk3OUEzNENBMTA0ODJBNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NTgwQkYwMDI4QkQxMUUwODk3OUEzNENBMTA0ODJBNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlrzXtkAABC0SURBVHja7Jx7jFbF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" />
47 </a>
48 <div style="margin-left:70px;margin-top:20px;font-size:19px;font-weight:bold;text-decoration:underline;color:red;">It wasn't good</div>
49 </div>
50 </div>
51 <div style="margin-left:30px;margin-top:10px;font-size:13px;"><a href="/survey/start/${'survey' in ctx and ctx['survey'] or ''}/phantom">Fill the survey</a></div>
52 </div>
53</body>
54 ]]>
55 </field>
56 </record>
57 </data>
58</openerp>
059
=== added file 'rating_project/project_demo.xml'
--- rating_project/project_demo.xml 1970-01-01 00:00:00 +0000
+++ rating_project/project_demo.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="1">
4 <record id="project.project_project_1" model="project.project">
5 <field name="type_ids" eval="[(4, ref('project.project_tt_analysis')) ,(4,ref('project.project_tt_specification')), (4,ref('project.project_tt_development')), (4,ref('project.project_tt_testing')), (4,ref('project.project_tt_deployment')),(4,ref('project_tt_rated'))]"/>
6 </record>
7
8 <record id="project.project_project_2" model="project.project">
9 <field name="type_ids" eval="[(4, ref('project.project_tt_specification')),(4,ref('project.project_tt_development')),(4,ref('project.project_tt_testing')),(4,ref('project.project_tt_merge')),(4,ref('project.project_tt_deployment')),(4,ref('project_tt_rated'))]"/>
10 </record>
11
12 <record id="project.project_project_3" model="project.project">
13 <field name="type_ids" eval="[(4, ref('project.project_tt_specification')),(4,ref('project.project_tt_development')),(4,ref('project.project_tt_testing')),(4,ref('project.project_tt_merge')),(4,ref('project.project_tt_deployment')),(4,ref('project_tt_rated'))]"/>
14 </record>
15
16 <record id="project.project_project_4" model="project.project">
17 <field name="type_ids" eval="[(4, ref('project.project_tt_design')),(4,ref('project.project_tt_development')),(4,ref('project.project_tt_testing')),(4,ref('project_tt_rated'))]"/>
18 </record>
19
20 <record id="project.project_project_5" model="project.project">
21 <field name="type_ids" eval="[(4, ref('project.project_tt_development')),(4,ref('project_tt_rated'))]"/>
22 </record>
23 </data>
24</openerp>
025
=== added file 'rating_project/project_view.xml'
--- rating_project/project_view.xml 1970-01-01 00:00:00 +0000
+++ rating_project/project_view.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,110 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <!-- inherit the smily on Faces -->
6 <record id="view_task_form2_rating_inherit" model="ir.ui.view">
7 <field name="name">task rating</field>
8 <field name="model">project.task</field>
9 <field name="inherit_id" ref="project.view_task_form2" />
10 <field name="arch" type="xml">
11 <xpath expr="//field[@name='kanban_state']" position="after">
12 <field name="rating_state" invisible='1'/>
13 <field name="stage_name" invisible='1'/>
14 <div attrs="{'invisible': [('stage_name', '!=', 'Rated')]}">
15 <img src="rating/static/src/img/great.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'great')]}"/>
16 <img src="rating/static/src/img/okay.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'okay')]}"/>
17 <img src="rating/static/src/img/bad.png" class="oe_right" attrs="{'invisible': [('rating_state', '!=', 'bad')]}"/>
18 </div>
19 </xpath>
20 <xpath expr="//header" position="inside">
21 <field name="stage_name" invisible="1"/>
22 <field name="rating_published" invisible="1"/>
23 <button name="send_rating_request" string="Send a Rating Request" type="object" attrs="{'invisible': [('stage_name', '!=', 'Done')]}"/>
24 <button name="set_rating_state_published" type="object" string="Publish Rating" attrs="{'invisible': ['|',('stage_name', '!=', 'Rated'),('rating_published', '=', True)]}"/>
25 <button name="set_rating_state_unpublished" type="object" string="UnPublish Rating" attrs="{'invisible': ['|',('stage_name', '!=', 'Rated'),('rating_published', '=', False)]}"/>
26 </xpath>
27 </field>
28 </record>
29
30 <!-- rating smily kanban -->
31 <record model="ir.ui.view" id="view_task_kanban_faces">
32 <field name="name">project.rating.kanban</field>
33 <field name="model">project.project</field>
34 <field name="arch" type="xml">
35 <kanban version="7.0" create="false" class="oe_background_grey">
36 <field name="name"/>
37 <field name="user_id"/>
38 <field name="tasks"/>
39 <templates>
40 <t t-name="kanban-box">
41 <div class="oe_kanban_color_0 oe_kanban_card">
42 <div class="oe_kanban_content">
43 <center><h4>Project : <field name="name"/></h4></center>
44 <div class="oe_center" t-if="record.user_id.raw_value">
45 <center><small>Assigned To : <t t-raw="record.user_id.raw_value[1]"/></small></center>
46 <br/><b>Ratings </b><br/>
47 </div>
48 <div class="oe_items_list" style="width:284px">
49 <field name="tasks" widget="rating_smily" options="{'rating_field': ['rating_state','name', 'project_id']}" />
50 </div>
51 </div>
52 </div>
53 </t>
54 </templates>
55 </kanban>
56 </field>
57 </record>
58
59 <!-- action for Get state kanban -->
60 <record id="action_view_task_faces" model="ir.actions.act_window">
61 <field name="name">Tasks Faces</field>
62 <field name="type">ir.actions.act_window</field>
63 <field name="domain">[('id', '=', active_id)]</field>
64 <field name="res_model">project.project</field>
65 <field name="view_mode">kanban</field>
66 </record>
67 <record id="action_view_task_faces_view" model="ir.actions.act_window.view">
68 <field eval="25" name="sequence"/>
69 <field name="view_mode">kanban</field>
70 <field name="view_id" ref="view_task_kanban_faces"/>
71 <field name="act_window_id" ref="action_view_task_faces"/>
72 </record>
73
74 <!-- inherit get state button on project -->
75 <record id="project_view_rating" model="ir.ui.view">
76 <field name="name">project.view.rating</field>
77 <field name="model">project.project</field>
78 <field name="inherit_id" ref="project.edit_project"/>
79 <field name="priority" eval="20"/>
80 <field name="arch" type="xml">
81 <xpath expr="//div[@name='buttons']" position="inside">
82 <button name="%(action_view_task_faces)d" type="action" string="Rating" icon="fa-star" class="oe_stat_button"/>
83 </xpath>
84 </field>
85 </record>
86
87 <!-- Override the project action to add view_id -->
88 <record id="project.action_view_task" model="ir.actions.act_window">
89 <field name="name">Tasks</field>
90 <field name="res_model">project.task</field>
91 <field name="view_mode">kanban,tree,form,calendar,gantt,graph</field>
92 <field name="search_view_id" ref="project.view_task_search_form"/>
93 <field name="view_id" ref="project.view_task_form2"/>
94 <field name="help" type="html">
95 <p>
96 OpenERP's project management allows you to manage the pipeline
97 of tasks in order to get things done efficiently. You can
98 track progress, discuss on tasks, attach documents, etc.
99 </p>
100 </field>
101 </record>
102 <!-- Add form view action -->
103 <record id="open_view_task_form_view" model="ir.actions.act_window.view">
104 <field name="sequence" eval="2"/>
105 <field name="view_mode">form</field>
106 <field name="act_window_id" ref="project.action_view_task"/>
107 </record>
108
109 </data>
110</openerp>
0111
=== added directory 'rating_sale'
=== added file 'rating_sale/__init__.py'
--- rating_sale/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_sale/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,3 @@
1import controllers
2import rate_product
3
04
=== added file 'rating_sale/__openerp__.py'
--- rating_sale/__openerp__.py 1970-01-01 00:00:00 +0000
+++ rating_sale/__openerp__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,48 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 'name': 'Product/Service Rating',
24 'version': '1.0',
25 'category': 'Hidden',
26 'description': """
27This module Allows a customer to give rating on Product/Service.
28""",
29 'author': 'OpenERP SA',
30 'website': 'http://openerp.com',
31 'depends': [
32 'rating',
33 'website_sale',
34 'product'
35 ],
36 'data': [
37 'security/ir.model.access.csv',
38 'rate_product_view.xml'
39 ],
40 'js': [
41 'static/src/js/rating_sale.js'
42 ],
43 'installable': True,
44 'auto_install': True,
45 'bootstrap': True,
46}
47
48# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
049
=== added directory 'rating_sale/controllers'
=== added file 'rating_sale/controllers/__init__.py'
--- rating_sale/controllers/__init__.py 1970-01-01 00:00:00 +0000
+++ rating_sale/controllers/__init__.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,3 @@
1import main
2
3# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
04
=== added file 'rating_sale/controllers/main.py'
--- rating_sale/controllers/main.py 1970-01-01 00:00:00 +0000
+++ rating_sale/controllers/main.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,21 @@
1# -*- coding: utf-8 -*-
2
3import werkzeug
4from openerp.addons.web import http
5from openerp.addons.web.http import request
6from openerp.addons.web.controllers.main import login_redirect
7from openerp import SUPERUSER_ID
8
9class ProductRating(http.Controller):
10 @http.route(['/product/rating/<model("product.template"):product>'], type='http', auth="public", website=True)
11 def set_product_rating(self, product, rating=None, **kwargs):
12 if not request.session.uid:
13 return login_redirect()
14 cr, uid, context = request.cr, request.uid, request.context
15 rating_obj = request.registry.get('product.rating')
16 rating_ids = rating_obj.search(cr, SUPERUSER_ID, [('product_id', '=', product.id), ('rated_user', '=', uid)], context=context)
17 if rating_ids:
18 rating_obj.write(cr, uid, rating_ids, {'rating_state':rating}, context=context)
19 else:
20 rating_obj.create(cr, uid, {'rating_state':rating, 'product_id': product.id, 'rated_user': uid}, context=context)
21 return werkzeug.utils.redirect('shop/product/%s'%product.id)
022
=== added file 'rating_sale/rate_product.py'
--- rating_sale/rate_product.py 1970-01-01 00:00:00 +0000
+++ rating_sale/rate_product.py 2014-05-12 07:24:43 +0000
@@ -0,0 +1,87 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import fields, osv
23
24class ProductRate(osv.Model):
25 _inherit = 'product.template'
26
27 def _calulate_average(self, cr, uid, ids, context=None):
28 res = {
29 'great':0,
30 'okay':0,
31 'bad':0
32 }
33 rating_great = rating_ok = rating_bad = 0.0
34 for rec in self.browse(cr, uid, ids, context=context):
35 for rate in rec.rating_ids:
36 res[rate.rating_state] += 1
37 if len(rec.rating_ids):
38 res['great'] = ((100*res['great'])/len(rec.rating_ids))
39 res['okay'] = ((100*res['okay'])/len(rec.rating_ids))
40 res['bad'] = ((100*res['bad'])/len(rec.rating_ids))
41 return res
42
43 def _product_average_rate(self, cr, uid, ids, names, arg, context=None):
44 res = self._calulate_average(cr, uid ,ids, context)
45 rating = 0.0
46 img = ''
47 for key,value in res.items():
48 rating += value
49 rating = float('%.2f'%(rating/3))
50 if rating >= 90:
51 img = '<img src="/rating/static/src/img/great.png"/><h3>'+str(rating)+'%</h3>'
52 elif rating >= 50:
53 img = '<img src="/rating/static/src/img/okay.png"/><h3>'+str(rating)+'%</h3>'
54 elif rating > 0:
55 img = '<img src="/rating/static/src/img/bad.png"/><h3>'+str(rating)+'%</h3>'
56 for id in ids:
57 res[id] = img
58 return res
59
60 _columns = {
61 'product_average_rating': fields.function(_product_average_rate, string='Average Rating', type="html"),
62 'allow_rating': fields.boolean('Allow Rating for this Product'),
63 'rating_ids': fields.one2many('product.rating', 'product_id'),
64 }
65
66 _defaults = {
67 'allow_rating': True,
68 }
69
70 def average_rate(self, cr, uid, ids, context=None):
71 res = []
72 result = self._calulate_average(cr, uid, ids, context)
73 res.append(('great', result['great'], 'label-success'))
74 res.append(('okay', result['okay'], 'label-warning'))
75 res.append(('bad', result['bad'], 'label-danger'))
76 res.sort(key=lambda x: x[1], reverse=True)
77 return res
78
79class ProductRating(osv.Model):
80 _name = "product.rating"
81
82 _columns = {
83 'name': fields.related('product_id', 'name', type="char"),
84 'product_id': fields.many2one('product.product', 'Product'),
85 'rated_user' : fields.many2one('res.users', 'Rated User'),
86 'rating_state': fields.selection([('great', 'Great'),('okay', 'Okay'),('bad', 'Not Good')], 'Select Rate', required=False),
87 }
088
=== added file 'rating_sale/rate_product_view.xml'
--- rating_sale/rate_product_view.xml 1970-01-01 00:00:00 +0000
+++ rating_sale/rate_product_view.xml 2014-05-12 07:24:43 +0000
@@ -0,0 +1,132 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <template id="rating_template" inherit_id="website_sale.product" name="Exptended Template for the Rating">
5 <xpath expr="//form[@action='/shop/add_cart']" position="after">
6 <div id="product_rating" t-if="product.website_published == True and product.allow_rating == True">
7 <div class="panel panel-default">
8 <div class="panel-heading ">
9 <a class="btn btn-primary btn-block fa fa-star" data-toggle="modal" data-target="#modelrating">Rate the Product</a>
10 <center>Last <span t-esc="len(product.rating_ids)"/> customer ratings</center>
11 </div>
12 <div class="panel-body">
13 <t t-foreach="product.average_rate()" t-as="rec">
14 <t t-if="rec_first">
15 <div class="row">
16 <div class="col-xs-6 col-sm-2">
17 <img alt="rating" class="mt4" width="55px" height="55px" t-attf-src="/rating/static/src/img/#{rec[0]}.png"/>
18 </div>
19 <div class="col-md-6 mb16">
20 <h3><p t-attf-class="label #{rec[2]}">
21 <span t-esc="rec[1]" />% <span t-esc="rec[0]"/>!</p></h3>
22 </div>
23 </div>
24 </t>
25 <t t-if="not rec_first" >
26 <img alt="rating" style="margin-left: 10px;" width="35px" height="35px" t-attf-src="/rating/static/src/img/#{rec[0]}.png"/>
27 <div t-attf-class="mt32 label #{rec[2]}">
28 <span t-esc="rec[1]"/> % <span t-esc="rec[0]"/>
29 </div>
30 </t>
31 </t>
32 </div>
33 </div>
34 <div class="modal fade" id="modelrating" role="dialog" aria-hidden="true">
35 <div class="modal-dialog">
36 <div id="rating" class="modal-content">
37 <div class="modal-header">
38 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&amp;times;</button>
39 <h4 class="modal-title">Please take second to rate Product</h4>
40 </div>
41 <div class="modal-body" id="rating-dialog">
42 <div class="row">
43 <div class="col-xs-6 col-md-4 text-center">
44 <a t-attf-href="/product/rating/#{ slug(product) }?{{keep_query( rating='great')}}">
45 <img src="/rating/static/src/img/great.png"/>
46 <div class="text-success">It was Great</div>
47 </a>
48 </div>
49 <div class="col-xs-6 col-md-4 text-center">
50 <a t-attf-href="/product/rating/#{ slug(product) }?{{keep_query( rating='okay')}}">
51 <img src="/rating/static/src/img/okay.png"/>
52 <div class="text-warning">It was Okay</div>
53 </a>
54 </div>
55 <div class="col-xs-6 col-md-4 text-center">
56 <a t-attf-href="/product/rating/#{ slug(product) }?{{keep_query( rating='bad')}}">
57 <img src="/rating/static/src/img/bad.png"/>
58 <div class="text-danger">It wasn't Good</div>
59 </a>
60 </div>
61 </div>
62 </div>
63 <div class="modal-footer">
64 <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
65 </div>
66 </div>
67 </div>
68 </div>
69 </div>
70 </xpath>
71 </template>
72
73 <!-- rating smily kanban -->
74 <record model="ir.ui.view" id="view_product_kanban_faces">
75 <field name="name">product.rating.kanban</field>
76 <field name="model">product.product</field>
77 <field name="arch" type="xml">
78 <kanban version="7.0" create="false">
79 <field name="name"/>
80 <field name="rating_ids"/>
81 <templates>
82 <t t-name="kanban-box">
83 <div class="oe_view_nocontent">
84 <div class="oe_view_nocontent_content">
85 <center><h4>Product : <field name="name"/></h4></center>
86 <br/><b>Ratings </b><br/>
87 <div class="oe_items_list">
88 <field name="rating_ids" widget="rating_smily" options="{'rating_field': ['rating_state','rated_user', 'product_id']}" />
89 </div>
90 </div>
91 </div>
92 </t>
93 </templates>
94 </kanban>
95 </field>
96 </record>
97
98 <!-- action for Get state kanban -->
99 <record id="action_view_product_state" model="ir.actions.act_window">
100 <field name="name">Product State</field>
101 <field name="type">ir.actions.act_window</field>
102 <field name="domain">[('id', '=', active_id)]</field>
103 <field name="res_model">product.product</field>
104 <field name="view_mode">kanban</field>
105 </record>
106 <record id="action_view_product_state_view" model="ir.actions.act_window.view">
107 <field eval="0" name="sequence"/>
108 <field name="view_mode">kanban</field>
109 <field name="view_id" ref="view_product_kanban_faces"/>
110 <field name="act_window_id" ref="action_view_product_state"/>
111 </record>
112
113 <record id="product_service_rate_form_view" model="ir.ui.view">
114 <field name="name">product.service.rate.form</field>
115 <field name="model">product.product</field>
116 <field name="inherit_id" ref="product.product_normal_form_view"/>
117 <field name="arch" type="xml">
118 <xpath expr="//div[@name='options']" position="after">
119 <div attrs="{'invisible': [('website_published', '=', False) ] }">
120 <field name="allow_rating"/>
121 <label for="allow_rating"/>
122 </div>
123 </xpath>
124 <xpath expr="//div[@name='buttons']" position="inside">
125 <field name="product_average_rating" attrs="{'invisible': [('website_published', '=', False) ] }"/>
126 <button name="%(action_view_product_state)d" type="action" string="Ratings" icon="fa-star" class="oe_stat_button" attrs="{'invisible': [('website_published', '=', False) ] }">
127 </button>
128 </xpath>
129 </field>
130 </record>
131 </data>
132</openerp>
0133
=== added directory 'rating_sale/security'
=== added file 'rating_sale/security/ir.model.access.csv'
--- rating_sale/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ rating_sale/security/ir.model.access.csv 2014-05-12 07:24:43 +0000
@@ -0,0 +1,3 @@
1id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2access_product_rating_user,product.rating.user,model_product_rating,base.group_user,1,1,1,0
3access_product_rating_all,product.rating,model_product_rating,,1,0,0,0

Subscribers

People subscribed via source and target branches

to all changes: