[MOV] project_issue: split project_issue.py and project_issue_view files
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
'description': """
|
||||
Track Issues/Bugs Management for Projects
|
||||
=========================================
|
||||
This application allows you to manage the issues you might face in a project like bugs in a system, client complaints or material breakdowns.
|
||||
This application allows you to manage the issues you might face in a project like bugs in a system, client complaints or material breakdowns.
|
||||
|
||||
It allows the manager to quickly check the issues, assign them and decide on their status quickly as they evolve.
|
||||
""",
|
||||
@@ -21,11 +21,14 @@ It allows the manager to quickly check the issues, assign them and decide on the
|
||||
'data': [
|
||||
'views/project_issue_view.xml',
|
||||
'views/project_issue_config_settings_views.xml',
|
||||
'views/account_analytic_account_view.xml',
|
||||
'views/project_project_view.xml',
|
||||
'views/res_partner_view.xml',
|
||||
'views/project_issue_menu.xml',
|
||||
'report/project_issue_report_view.xml',
|
||||
'security/project_issue_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/project_issue_data.xml',
|
||||
'data/mail_message_subtype_data.xml',
|
||||
'views/project_dashboard.xml',
|
||||
],
|
||||
'demo': ['data/project_issue_demo.xml'],
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import project_issue
|
||||
import account_analytic_account
|
||||
import project_project
|
||||
import project_task_type
|
||||
import res_partner
|
||||
import project_issue_config_settings
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
|
||||
class account_analytic_account(osv.Model):
|
||||
_inherit = 'account.analytic.account'
|
||||
_description = 'Analytic Account'
|
||||
|
||||
_columns = {
|
||||
'use_issues': fields.boolean('Use Issues', help="Check this box to manage customer activities through this project"),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_issues'] = template.use_issues
|
||||
return res
|
||||
|
||||
def _trigger_project_creation(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
|
||||
return res or (vals.get('use_issues') and not 'project_creation_in_progress' in context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
proj_ids = self.pool['project.project'].search(cr, uid, [('analytic_account_id', 'in', ids)])
|
||||
has_issues = self.pool['project.issue'].search(cr, uid, [('project_id', 'in', proj_ids)], count=True, context=context)
|
||||
if has_issues:
|
||||
raise UserError(_('Please remove existing issues in the project linked to the accounts you want to delete.'))
|
||||
return super(account_analytic_account, self).unlink(cr, uid, ids, context=context)
|
||||
@@ -457,123 +457,3 @@ class project_issue(osv.Model):
|
||||
headers['X-Odoo-Tags'] = ','.join([tag.name for tag in current_issue.tag_ids])
|
||||
res['headers'] = repr(headers)
|
||||
return res
|
||||
|
||||
|
||||
class project(osv.Model):
|
||||
_inherit = "project.project"
|
||||
|
||||
def _get_alias_models(self, cr, uid, context=None):
|
||||
res = super(project, self)._get_alias_models(cr, uid, context=context)
|
||||
res.append(("project.issue", "Issues"))
|
||||
return res
|
||||
|
||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
return {
|
||||
project_id: Issue.search_count(cr,uid, [('project_id', '=', project_id), '|', ('stage_id.fold', '=', False), ('stage_id', '=', False)], context=context)
|
||||
for project_id in ids
|
||||
}
|
||||
|
||||
def _issue_needaction_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
res = dict.fromkeys(ids, 0)
|
||||
projects = Issue.read_group(cr, uid, [('project_id', 'in', ids), ('message_needaction', '=', True)], ['project_id'], ['project_id'], context=context)
|
||||
res.update({project['project_id'][0]: int(project['project_id_count']) for project in projects})
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'issue_count': fields.function(_issue_count, type='integer', string="Issues",),
|
||||
'issue_ids': fields.one2many('project.issue', 'project_id', string="Issues",
|
||||
domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)]),
|
||||
'issue_needaction_count': fields.function(_issue_needaction_count, type='integer', string="Issues",),
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
res = super(project, self).write(vals)
|
||||
if 'active' in vals:
|
||||
# archiving/unarchiving a project does it on its issues, too
|
||||
issues = self.with_context(active_test=False).mapped('issue_ids')
|
||||
issues.write({'active': vals['active']})
|
||||
return res
|
||||
|
||||
|
||||
class account_analytic_account(osv.Model):
|
||||
_inherit = 'account.analytic.account'
|
||||
_description = 'Analytic Account'
|
||||
|
||||
_columns = {
|
||||
'use_issues': fields.boolean('Use Issues', help="Check this box to manage customer activities through this project"),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_issues'] = template.use_issues
|
||||
return res
|
||||
|
||||
def _trigger_project_creation(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
|
||||
return res or (vals.get('use_issues') and not 'project_creation_in_progress' in context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
proj_ids = self.pool['project.project'].search(cr, uid, [('analytic_account_id', 'in', ids)])
|
||||
has_issues = self.pool['project.issue'].search(cr, uid, [('project_id', 'in', proj_ids)], count=True, context=context)
|
||||
if has_issues:
|
||||
raise UserError(_('Please remove existing issues in the project linked to the accounts you want to delete.'))
|
||||
return super(account_analytic_account, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
|
||||
class project_project(osv.Model):
|
||||
_inherit = 'project.project'
|
||||
|
||||
_columns = {
|
||||
'label_issues': fields.char('Use Issues as', help="Customize the issues label, for example to call them cases."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'use_issues': True,
|
||||
'label_issues': 'Issues',
|
||||
}
|
||||
|
||||
def _check_create_write_values(self, cr, uid, vals, context=None):
|
||||
""" Perform some check on values given to create or write. """
|
||||
# Handle use_tasks / use_issues: if only one is checked, alias should take the same model
|
||||
if vals.get('use_tasks') and not vals.get('use_issues'):
|
||||
vals['alias_model'] = 'project.task'
|
||||
elif vals.get('use_issues') and not vals.get('use_tasks'):
|
||||
vals['alias_model'] = 'project.issue'
|
||||
|
||||
def on_change_use_tasks_or_issues(self, cr, uid, ids, use_tasks, use_issues, context=None):
|
||||
values = {}
|
||||
if use_tasks and not use_issues:
|
||||
values['alias_model'] = 'project.task'
|
||||
elif not use_tasks and use_issues:
|
||||
values['alias_model'] = 'project.issue'
|
||||
return {'value': values}
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
self._check_create_write_values(cr, uid, vals, context=context)
|
||||
return super(project_project, self).create(cr, uid, vals, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
self._check_create_write_values(cr, uid, vals, context=context)
|
||||
return super(project_project, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
class res_partner(osv.osv):
|
||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
partners = {id: self.search(cr, uid, [('id', 'child_of', ids)]) for id in ids}
|
||||
return {
|
||||
partner_id: Issue.search_count(cr, uid, [('partner_id', 'in', partners[partner_id])])
|
||||
for partner_id in partners.keys()
|
||||
}
|
||||
|
||||
""" Inherits partner and adds Issue information in the partner form """
|
||||
_inherit = 'res.partner'
|
||||
_columns = {
|
||||
'issue_count': fields.function(_issue_count, string='# Issues', type='integer'),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp import api
|
||||
|
||||
|
||||
class project_project(osv.Model):
|
||||
_inherit = 'project.project'
|
||||
|
||||
def _get_alias_models(self, cr, uid, context=None):
|
||||
res = super(project, self)._get_alias_models(cr, uid, context=context)
|
||||
res.append(("project.issue", "Issues"))
|
||||
return res
|
||||
|
||||
|
||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
return {
|
||||
project_id: Issue.search_count(cr,uid, [('project_id', '=', project_id), '|', ('stage_id.fold', '=', False), ('stage_id', '=', False)], context=context)
|
||||
for project_id in ids
|
||||
}
|
||||
|
||||
def _issue_needaction_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
res = dict.fromkeys(ids, 0)
|
||||
projects = Issue.read_group(cr, uid, [('project_id', 'in', ids), ('message_needaction', '=', True)], ['project_id'], ['project_id'], context=context)
|
||||
res.update({project['project_id'][0]: int(project['project_id_count']) for project in projects})
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'issue_count': fields.function(_issue_count, type='integer', string="Issues",),
|
||||
'issue_ids': fields.one2many('project.issue', 'project_id', string="Issues",
|
||||
domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)]),
|
||||
'issue_needaction_count': fields.function(_issue_needaction_count, type='integer', string="Issues",),
|
||||
'label_issues': fields.char('Use Issues as', help="Customize the issues label, for example to call them cases."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'use_issues': True,
|
||||
'label_issues': 'Issues',
|
||||
}
|
||||
|
||||
def _check_create_write_values(self, cr, uid, vals, context=None):
|
||||
""" Perform some check on values given to create or write. """
|
||||
# Handle use_tasks / use_issues: if only one is checked, alias should take the same model
|
||||
if vals.get('use_tasks') and not vals.get('use_issues'):
|
||||
vals['alias_model'] = 'project.task'
|
||||
elif vals.get('use_issues') and not vals.get('use_tasks'):
|
||||
vals['alias_model'] = 'project.issue'
|
||||
|
||||
def on_change_use_tasks_or_issues(self, cr, uid, ids, use_tasks, use_issues, context=None):
|
||||
values = {}
|
||||
if use_tasks and not use_issues:
|
||||
values['alias_model'] = 'project.task'
|
||||
elif not use_tasks and use_issues:
|
||||
values['alias_model'] = 'project.issue'
|
||||
return {'value': values}
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
self._check_create_write_values(cr, uid, vals, context=context)
|
||||
return super(project_project, self).create(cr, uid, vals, context=context)
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
self._check_create_write_values(vals)
|
||||
res = super(project_project, self).write(vals)
|
||||
if 'active' in vals:
|
||||
# archiving/unarchiving a project does it on its issues, too
|
||||
issues = self.with_context(active_test=False).mapped('issue_ids')
|
||||
issues.write({'active': vals['active']})
|
||||
return res
|
||||
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
|
||||
class res_partner(osv.osv):
|
||||
""" Inherits partner and adds Issue information in the partner form """
|
||||
_inherit = 'res.partner'
|
||||
|
||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
partners = {id: self.search(cr, uid, [('id', 'child_of', ids)]) for id in ids}
|
||||
return {
|
||||
partner_id: Issue.search_count(cr, uid, [('partner_id', 'in', partners[partner_id])])
|
||||
for partner_id in partners.keys()
|
||||
}
|
||||
|
||||
_columns = {
|
||||
'issue_count': fields.function(_issue_count, string='# Issues', type='integer'),
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="analytic_account_inherited_issue_form" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.issue.form.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="project.analytic_account_inherited_form"/>
|
||||
<field eval="18" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//div[@name="project"]' position='inside'>
|
||||
<field name="use_issues" groups="base.group_no_one"/>
|
||||
<label for="use_issues" groups="base.group_no_one"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -257,52 +257,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Project -->
|
||||
<record id="view_project_form_inherited" model="ir.ui.view">
|
||||
<field name="name">project.project.form.inherited</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//field[@name="use_tasks"]' position='attributes'>
|
||||
<attribute name="on_change">on_change_use_tasks_or_issues(use_tasks, use_issues)</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="options_active"]' position="attributes">
|
||||
<attribute name="invisible">0</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="options_active"]' position='inside'>
|
||||
<div>
|
||||
<field name="use_issues" class="oe_inline"
|
||||
on_change="on_change_use_tasks_or_issues(use_tasks, use_issues)"/>
|
||||
<label for="use_issues" class="oe_inline" string="Issues"/>
|
||||
<span attrs="{'invisible':[('use_issues', '=', False)]}">as </span>
|
||||
<field name="label_issues" class="oe_inline oe_input_align" attrs="{'invisible': [('use_issues', '=', False)]}"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible':[('use_issues','=', False)]}"
|
||||
name="%(act_project_project_2_project_issue_all)d" icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo" options="{'label_field': 'label_issues'}"/>
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr='//field[@name="use_tasks"]' position="attributes">
|
||||
<attribute name="attrs">{'on_change': 'on_change_use_tasks_or_issues(use_tasks, use_issues)'}</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="analytic_account_inherited_issue_form" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.issue.form.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="project.analytic_account_inherited_form"/>
|
||||
<field eval="18" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//div[@name="project"]' position='inside'>
|
||||
<field name="use_issues" groups="base.group_no_one"/>
|
||||
<label for="use_issues" groups="base.group_no_one"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_issues" model="ir.actions.act_window">
|
||||
<field name="res_model">project.issue</field>
|
||||
<field name="view_type">form</field>
|
||||
@@ -317,47 +271,28 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- res.partner -->
|
||||
<record model="ir.ui.view" id="res_partner_issues_button_view">
|
||||
<field name="name">res.partner.issues.button.view</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form" />
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="groups_id" eval="[(4, ref('project.group_project_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(action_view_issues)d"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Portal -->
|
||||
<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>
|
||||
|
||||
<!-- Portal -->
|
||||
<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"
|
||||
<menuitem name="Issues" id="portal_services_issues" parent="portal.portal_projects"
|
||||
action="open_view_issue" sequence="10"/>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_project_form_inherited" model="ir.ui.view">
|
||||
<field name="name">project.project.form.inherited</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//field[@name="use_tasks"]' position='attributes'>
|
||||
<attribute name="on_change">on_change_use_tasks_or_issues(use_tasks, use_issues)</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="options_active"]' position="attributes">
|
||||
<attribute name="invisible">0</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="options_active"]' position='inside'>
|
||||
<div>
|
||||
<field name="use_issues" class="oe_inline"
|
||||
on_change="on_change_use_tasks_or_issues(use_tasks, use_issues)"/>
|
||||
<label for="use_issues" class="oe_inline" string="Issues"/>
|
||||
<span attrs="{'invisible':[('use_issues', '=', False)]}">as </span>
|
||||
<field name="label_issues" class="oe_inline oe_input_align" attrs="{'invisible': [('use_issues', '=', False)]}"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible':[('use_issues','=', False)]}"
|
||||
name="%(act_project_project_2_project_issue_all)d" icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo" options="{'label_field': 'label_issues'}"/>
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr='//field[@name="use_tasks"]' position="attributes">
|
||||
<attribute name="attrs">{'on_change': 'on_change_use_tasks_or_issues(use_tasks, use_issues)'}</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- res.partner -->
|
||||
<record model="ir.ui.view" id="res_partner_issues_button_view">
|
||||
<field name="name">res.partner.issues.button.view</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form" />
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="groups_id" eval="[(4, ref('project.group_project_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(action_view_issues)d"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user