[IMP] website_project_issue: frontend view for issues under My Account page of website, and removed link to the backend and its related files
[ADD] website_project_issue_sheet: link module between website_project_issue and project_issue_sheet
Frontend integration of issues:
- issues details
- chatter integration
- timesheets
This commit is contained in:
committed by
Antony Lesuisse
parent
8bd6074f03
commit
56c5d0afeb
@@ -1,2 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
import controllers
|
||||||
|
|||||||
@@ -8,17 +8,15 @@
|
|||||||
'category': 'Tools',
|
'category': 'Tools',
|
||||||
'complexity': 'easy',
|
'complexity': 'easy',
|
||||||
'description': """
|
'description': """
|
||||||
This module adds issue menu and features to your portal if project_issue and portal are installed.
|
This module adds project issues inside your account's page on website if project_issue and website_portal are installed.
|
||||||
==================================================================================================
|
==================================================================================================
|
||||||
""",
|
""",
|
||||||
'author': 'OpenERP SA',
|
'author': 'OpenERP SA',
|
||||||
'depends': ['project_issue','portal', 'website'],
|
'depends': ['project_issue', 'website_portal'],
|
||||||
'data': [
|
'data': [
|
||||||
'security/portal_security.xml',
|
'security/portal_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'portal_project_issue_view.xml',
|
'views/project_issue_templates.xml',
|
||||||
'website_project_issue_view.xml',
|
|
||||||
'views/portal_project_issue.xml',
|
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': True,
|
'auto_install': True,
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
import main
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
from openerp import http
|
||||||
|
from openerp.addons.website_portal.controllers.main import website_account
|
||||||
|
from openerp.http import request
|
||||||
|
|
||||||
|
|
||||||
|
class WebsiteAccount(website_account):
|
||||||
|
@http.route(['/my', '/my/home'], type='http', auth="user", website=True)
|
||||||
|
def account(self):
|
||||||
|
response = super(WebsiteAccount, self).account()
|
||||||
|
user = request.env.user
|
||||||
|
# portal projects where you or someone from your company are a follower
|
||||||
|
project_issues = request.env['project.issue'].search([
|
||||||
|
'&',
|
||||||
|
('project_id.privacy_visibility', '=', 'portal'),
|
||||||
|
'|',
|
||||||
|
('message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
||||||
|
('message_follower_ids', 'child_of', [user.partner_id.id])
|
||||||
|
])
|
||||||
|
response.qcontext.update({'issues': project_issues})
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class WebsiteProjectIssue(http.Controller):
|
||||||
|
@http.route(['/my/issues/<int:issue_id>'], type='http', auth="user", website=True)
|
||||||
|
def issues_followup(self, issue_id=None):
|
||||||
|
issue = request.env['project.issue'].browse(issue_id)
|
||||||
|
return request.website.render("website_project_issue.issues_followup", {'issue': issue})
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<record id="open_view_issue" model="ir.actions.act_window">
|
|
||||||
<field name="name">Issues</field>
|
|
||||||
<field name="res_model">project.issue</field>
|
|
||||||
<field name="view_type">form</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="view_id" ref="project_issue.project_issue_tree_view"/>
|
|
||||||
<field name="domain" eval=""/>
|
|
||||||
<field name="context">{"search_default_user_id":'', "search_default_draft":'', "search_default_todo":'', "portal":'True'}</field>
|
|
||||||
<field name="search_view_id" ref="project_issue.view_project_issue_filter"/>
|
|
||||||
<field name="target">current</field>
|
|
||||||
<field name="help" type="html">
|
|
||||||
<p class="oe_view_nocontent_create">
|
|
||||||
Click to create an issue.
|
|
||||||
</p><p>
|
|
||||||
You can track your issues from this menu and the action we
|
|
||||||
will take.
|
|
||||||
</p>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<menuitem name="Issues" id="portal_services_issues" parent="portal.portal_projects"
|
|
||||||
action="open_view_issue" sequence="10"/>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_issues,project_issue,project_issue.model_project_issue,base.group_portal,1,0,0,0
|
access_issues,project_issue,project_issue.model_project_issue,base.group_portal,1,0,0,0
|
||||||
access_case_section,crm_team,sales_team.model_crm_team,base.group_portal,1,0,0,0
|
access_case_section,crm_team,sales_team.model_crm_team,base.group_portal,1,0,0,0
|
||||||
access_issues_public,project_issue,project_issue.model_project_issue,base.group_public,1,0,0,0
|
|
||||||
|
@@ -3,10 +3,9 @@
|
|||||||
<data noupdate="1">
|
<data noupdate="1">
|
||||||
|
|
||||||
<record id="portal_issue_rule" model="ir.rule">
|
<record id="portal_issue_rule" model="ir.rule">
|
||||||
<field name="name">Project/Issue: portal users: public or (portal and colleagues following) or (followers and following)</field>
|
<field name="name">Project/Issue: portal users: (portal and colleagues following) or (followers and following)</field>
|
||||||
<field name="model_id" ref="project_issue.model_project_issue"/>
|
<field name="model_id" ref="project_issue.model_project_issue"/>
|
||||||
<field name="domain_force">['|', '|',
|
<field name="domain_force">['|',
|
||||||
('project_id.privacy_visibility', 'in', ['public']),
|
|
||||||
'&',
|
'&',
|
||||||
('project_id.privacy_visibility', '=', 'portal'),
|
('project_id.privacy_visibility', '=', 'portal'),
|
||||||
('message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
('message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
||||||
@@ -18,21 +17,13 @@
|
|||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.rule" id="project_issue.issue_user_rule">
|
<record model="ir.rule" id="project_issue.issue_user_rule">
|
||||||
<field name="name">Project/Issue: employees: public, portal, employee or (followers and following)</field>
|
<field name="name">Project/Issue: employees: portal, employee or (followers and following)</field>
|
||||||
<field name="domain_force">['|',
|
<field name="domain_force">['|',
|
||||||
('project_id.privacy_visibility', 'in', ['public', 'portal', 'employees']),
|
('project_id.privacy_visibility', 'in', ['portal', 'employees']),
|
||||||
'&',
|
'&',
|
||||||
('project_id.privacy_visibility', '=', 'followers'),
|
('project_id.privacy_visibility', '=', 'followers'),
|
||||||
('message_follower_ids', 'in', [user.partner_id.id]),
|
('message_follower_ids', 'in', [user.partner_id.id]),
|
||||||
]</field>
|
]</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.rule" id="issue_public_rule">
|
|
||||||
<field name="name">Project/Issue: public users: public only</field>
|
|
||||||
<field name="model_id" ref="project_issue.model_project_issue"/>
|
|
||||||
<field name="domain_force">[('project_id.privacy_visibility', '=', 'public')]</field>
|
|
||||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
.oe_portal_project_issue {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oe_portal_project_issue .oe_kanban_groups {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oe_portal_project_issue .oe_fold_column.oe_kanban_record {
|
|
||||||
float: none;
|
|
||||||
display: block;
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border-style: solid;
|
|
||||||
border-bottom-color: #B9B9B9;
|
|
||||||
border-left-color: #D8D8D8;
|
|
||||||
border-right-color: #D8D8D8;
|
|
||||||
border-top-color: #D8D8D8;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oe_portal_project_issue .oe_fold_column.oe_kanban_record .oe_kanban_content {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oe_portal_project_issue .oe_fold_column.oe_kanban_record h1 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.1em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from openerp.addons.portal_project.tests.test_access_rights import TestPortalProjectBase
|
from openerp.addons.project.tests.test_access_rights import TestPortalProjectBase
|
||||||
from openerp.exceptions import AccessError
|
from openerp.exceptions import AccessError
|
||||||
from openerp.tools import mute_logger
|
from openerp.tools import mute_logger
|
||||||
|
|
||||||
@@ -33,52 +33,14 @@ class TestPortalIssue(TestPortalProjectBase):
|
|||||||
Issue = self.env['project.issue']
|
Issue = self.env['project.issue']
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# CASE1: public project
|
# CASE1: portal project
|
||||||
# ----------------------------------------
|
|
||||||
|
|
||||||
# Do: Alfred reads project -> ok (employee ok public)
|
|
||||||
# Test: all project issues visible
|
|
||||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
|
||||||
test_issue_ids = set([self.issue_1.id, self.issue_2.id, self.issue_3.id, self.issue_4.id, self.issue_5.id, self.issue_6.id])
|
|
||||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
|
||||||
'access rights: project user cannot see all issues of a public project')
|
|
||||||
# Test: all project issues readable
|
|
||||||
issues.read(['name'])
|
|
||||||
# Test: all project issues writable
|
|
||||||
issues.sudo(self.user_projectuser.id).write({'description': 'TestDescription'})
|
|
||||||
|
|
||||||
# Do: Bert reads project -> crash, no group
|
|
||||||
# Test: no project issue visible
|
|
||||||
self.assertRaises(AccessError, Issue.sudo(self.user_noone.id).search, [('project_id', '=', pigs_id)])
|
|
||||||
# Test: no project issue readable
|
|
||||||
self.assertRaises(AccessError, issues.sudo(self.user_noone.id).read, ['name'])
|
|
||||||
# Test: no project issue writable
|
|
||||||
self.assertRaises(AccessError, issues.sudo(self.user_noone.id).write, {'description': 'TestDescription'})
|
|
||||||
|
|
||||||
# Do: Chell reads project -> ok (portal ok public)
|
|
||||||
# Test: all project issues visible
|
|
||||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
|
||||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
|
||||||
'access rights: project user cannot see all issues of a public project')
|
|
||||||
# Test: all project issues readable
|
|
||||||
issues.sudo(self.user_portal.id).read(['name'])
|
|
||||||
# Test: no project issue writable
|
|
||||||
self.assertRaises(AccessError, issues.sudo(self.user_portal.id).write, {'description': 'TestDescription'})
|
|
||||||
|
|
||||||
# Do: Donovan reads project -> ok (public ok public)
|
|
||||||
# Test: all project issues visible
|
|
||||||
issues = Issue.sudo(self.user_public.id).search([('project_id', '=', pigs_id)])
|
|
||||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
|
||||||
'access rights: project user cannot see all issues of a public project')
|
|
||||||
|
|
||||||
# ----------------------------------------
|
|
||||||
# CASE2: portal project
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
self.project_pigs.write({'privacy_visibility': 'portal'})
|
self.project_pigs.write({'privacy_visibility': 'portal'})
|
||||||
|
|
||||||
# Do: Alfred reads project -> ok (employee ok public)
|
# Do: Alfred reads project -> ok (employee ok public)
|
||||||
# Test: all project issues visible
|
# Test: all project issues visible
|
||||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||||
|
test_issue_ids = set([self.issue_1.id, self.issue_2.id, self.issue_3.id, self.issue_4.id, self.issue_5.id, self.issue_6.id])
|
||||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
self.assertEqual(set(issues.ids), test_issue_ids,
|
||||||
'access rights: project user cannot see all issues of a portal project')
|
'access rights: project user cannot see all issues of a portal project')
|
||||||
|
|
||||||
@@ -101,7 +63,7 @@ class TestPortalIssue(TestPortalProjectBase):
|
|||||||
self.issue_3.sudo(self.user_projectuser.id).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
self.issue_3.sudo(self.user_projectuser.id).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# CASE3: employee project
|
# CASE2: employee project
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
self.project_pigs.write({'privacy_visibility': 'employees'})
|
self.project_pigs.write({'privacy_visibility': 'employees'})
|
||||||
|
|
||||||
@@ -118,7 +80,7 @@ class TestPortalIssue(TestPortalProjectBase):
|
|||||||
self.assertFalse(issues.ids, 'access rights: portal user should not see issues of an employees project, even if assigned')
|
self.assertFalse(issues.ids, 'access rights: portal user should not see issues of an employees project, even if assigned')
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# CASE4: followers project
|
# CASE3: followers project
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
self.project_pigs.write({'privacy_visibility': 'followers'})
|
self.project_pigs.write({'privacy_visibility': 'followers'})
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
<template id="assets_backend" name="portal_project_issue assets" inherit_id="web.assets_backend">
|
|
||||||
<xpath expr="." position="inside">
|
|
||||||
<link rel="stylesheet" href="/website_project_issue/static/src/css/portal_project_issue.css"/>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<template id="portal_project_issue" name="Portal Project Issues" inherit_id="website_portal.account">
|
||||||
|
<xpath expr="//div[contains(@class,'o_my_documents')]/*[last()]" position="after">
|
||||||
|
<h3 class="page-header">Your Issues</h3>
|
||||||
|
<t t-if="not issues">
|
||||||
|
<p>There are currently no issues for your account.</p>
|
||||||
|
</t>
|
||||||
|
<t t-if="issues">
|
||||||
|
<table class="table table-hover status_table">
|
||||||
|
<thead>
|
||||||
|
<tr class="active">
|
||||||
|
<th>Issue</th>
|
||||||
|
<th>Description</th><th/>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<t t-foreach="issues" t-as="issue">
|
||||||
|
<tr t-att-class="'hidden to_hide' if issue_index > 4 else ''">
|
||||||
|
<td><a t-attf-href="/my/issues/#{issue.id}">Issue <t t-esc="issue.id"/></a></td>
|
||||||
|
<td><span t-field="issue.name"/></td><td/>
|
||||||
|
<td><span t-field="issue.stage_id.name"/></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
<tr t-att-class="'hidden' if len(issues) < 6 else ''">
|
||||||
|
<td colspan="4">
|
||||||
|
<a href="" class="o_my_show_more btn btn-xs btn-default"><span>Show more</span><span class="hidden">Show less</span></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</t>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="issues_followup" name="Project Issues">
|
||||||
|
<t t-call="website.layout">
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="container">
|
||||||
|
<div class="oe_structure">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<ol class="breadcrumb mt8">
|
||||||
|
<li><a href="/my/home">My Account</a></li>
|
||||||
|
<li>Issue <span t-field="issue.id"/></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h4>
|
||||||
|
Issue <span t-field="issue.id"/> - <span t-field="issue.name"/>
|
||||||
|
<span t-field="issue.stage_id.name" class="pull-right label label-info" title="Current stage of this issue"/>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="mb8">
|
||||||
|
<strong>Date:</strong> <span t-field="issue.create_date" t-field-options='{"widget": "date"}'/>
|
||||||
|
</div>
|
||||||
|
<div class='row'>
|
||||||
|
<div class="col-md-6" t-if="issue.user_id">
|
||||||
|
<strong>Assigned to</strong>
|
||||||
|
<div>
|
||||||
|
<address t-field="issue.user_id" t-field-options='{"widget": "contact", "fields": ["name", "email", "phone"], "no_marker": true}'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<strong>Reported by</strong>
|
||||||
|
<div t-if="issue.partner_id">
|
||||||
|
<address t-field="issue.partner_id" t-field-options='{"widget": "contact", "fields": ["name", "email"], "no_marker": true}'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt32">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h4><strong>Message and communication history</strong></h4>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10 col-md-offset-1 mt16">
|
||||||
|
<t t-call="website_mail.message_thread">
|
||||||
|
<t t-set="object" t-value="issue"/>
|
||||||
|
<t t-set="chatter_mode" t-value="'json'"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="website_project_issue.link_issues" name="Issues Link from User Account" inherit_id="website.layout" groups="base.group_portal">
|
|
||||||
<xpath expr="//li[@id='o_logout']" position="before">
|
|
||||||
<li><a href="/web#action=website_project_issue.open_view_issue" role="menuitem">Issues</a></li>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'Timesheet on Website Project Issue',
|
||||||
|
'version': '0.1',
|
||||||
|
'category': 'Tools',
|
||||||
|
'complexity': 'easy',
|
||||||
|
'description': """
|
||||||
|
Add timesheet support on issue in the frontend.
|
||||||
|
==================================================================================================
|
||||||
|
""",
|
||||||
|
'author': 'OpenERP SA',
|
||||||
|
'depends': ['website_project_issue', 'project_issue_sheet'],
|
||||||
|
'data': [
|
||||||
|
'views/project_issue_templates.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'security/portal_security.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'auto_install': True,
|
||||||
|
'category': 'Hidden',
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_timesheets_portal,access_timesheets_portal,analytic.model_account_analytic_line,base.group_portal,1,0,0,0
|
||||||
|
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data noupdate="1">
|
||||||
|
|
||||||
|
<record id="portal_issue_sheet_rule" model="ir.rule">
|
||||||
|
<field name="name">Project/Issue Timesheets: frontend access</field>
|
||||||
|
<field name="model_id" ref="analytic.model_account_analytic_line"/>
|
||||||
|
<field name="domain_force">['|',
|
||||||
|
'&',
|
||||||
|
('issue_id.project_id.privacy_visibility', '=', 'portal'),
|
||||||
|
('issue_id.message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
||||||
|
'&',
|
||||||
|
('issue_id.project_id.privacy_visibility', '=', 'followers'),
|
||||||
|
('issue_id.message_follower_ids', 'in', [user.partner_id.id]),
|
||||||
|
]</field>
|
||||||
|
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<template id="issues_followup_sheet" inherit_id="website_project_issue.issues_followup" name="Project Issues Timesheets">
|
||||||
|
<xpath expr="//div[@class='panel-body']" position="inside">
|
||||||
|
<t t-if="issue.timesheet_ids">
|
||||||
|
<hr/>
|
||||||
|
<table class="table table-hover o_my_status_table">
|
||||||
|
<thead>
|
||||||
|
<tr class="active">
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Responsible</th>
|
||||||
|
<th>Duration</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr t-foreach="issue.timesheet_ids" t-as="timesheet">
|
||||||
|
<td><span t-esc="timesheet.date"/></td>
|
||||||
|
<td><span t-esc="timesheet.name"/></td>
|
||||||
|
<td><span t-esc="timesheet.user_id.name"/></td>
|
||||||
|
<td><span t-field="timesheet.unit_amount" t-field-options='{"widget": "duration", "unit": "hour"}'/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</t>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user