[IMP] hr_org_chart: Adapt module with new hr.employee.public model
This commit is contained in:
committed by
Yannick Tivisse
parent
c9ca376146
commit
d09d5c2e8a
@@ -19,7 +19,7 @@ class HrOrgChartController(http.Controller):
|
||||
else:
|
||||
cids = [request.env.company.id]
|
||||
|
||||
Employee = request.env['hr.employee'].with_context(allowed_company_ids=cids)
|
||||
Employee = request.env['hr.employee.public'].with_context(allowed_company_ids=cids)
|
||||
# check and raise
|
||||
if not Employee.check_access_rights('read', raise_exception=False):
|
||||
return None
|
||||
@@ -35,13 +35,19 @@ class HrOrgChartController(http.Controller):
|
||||
return dict(
|
||||
id=employee.id,
|
||||
name=employee.name,
|
||||
link='/mail/view?model=hr.employee&res_id=%s' % employee.id,
|
||||
link='/mail/view?model=%s&res_id=%s' % ('hr.employee.public', employee.id,),
|
||||
job_id=job.id,
|
||||
job_name=job.name or '',
|
||||
direct_sub_count=len(employee.child_ids),
|
||||
indirect_sub_count=employee.child_all_count,
|
||||
)
|
||||
|
||||
@http.route('/hr/get_redirect_model', type='json', auth='user')
|
||||
def get_redirect_model(self):
|
||||
if request.env['hr.employee'].check_access_rights('read', raise_exception=False):
|
||||
return 'hr.employee'
|
||||
return 'hr.employee.public'
|
||||
|
||||
@http.route('/hr/get_org_chart', type='json', auth='user')
|
||||
def get_org_chart(self, employee_id, **kw):
|
||||
|
||||
@@ -50,7 +56,7 @@ class HrOrgChartController(http.Controller):
|
||||
return {}
|
||||
|
||||
# compute employee data for org chart
|
||||
ancestors, current = request.env['hr.employee'], employee
|
||||
ancestors, current = request.env['hr.employee.public'], employee
|
||||
while current.parent_id and len(ancestors) < self._managers_level+1:
|
||||
ancestors += current.parent_id
|
||||
current = current.parent_id
|
||||
@@ -81,8 +87,10 @@ class HrOrgChartController(http.Controller):
|
||||
return {}
|
||||
|
||||
if subordinates_type == 'direct':
|
||||
return employee.child_ids.ids
|
||||
res = employee.child_ids.ids
|
||||
elif subordinates_type == 'indirect':
|
||||
return (employee.subordinate_ids - employee.child_ids).ids
|
||||
res = (employee.subordinate_ids - employee.child_ids).ids
|
||||
else:
|
||||
return employee.subordinate_ids.ids
|
||||
res = employee.subordinate_ids.ids
|
||||
|
||||
return res
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import hr_org_chart_mixin
|
||||
from . import hr_employee
|
||||
|
||||
@@ -1,43 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class Employee(models.Model):
|
||||
_name = "hr.employee"
|
||||
_inherit = "hr.employee"
|
||||
_inherit = ["hr.employee"]
|
||||
|
||||
child_all_count = fields.Integer(
|
||||
'Indirect Surbordinates Count',
|
||||
compute='_compute_subordinates', store=False)
|
||||
|
||||
subordinate_ids = fields.One2many('hr.employee', string='Subordinates', compute='_compute_subordinates', help="Direct and indirect subordinates", groups='base.group_user')
|
||||
subordinate_ids = fields.One2many('hr.employee', string='Subordinates', compute='_compute_subordinates', help="Direct and indirect subordinates")
|
||||
|
||||
|
||||
def _get_subordinates(self, parents=None):
|
||||
"""
|
||||
Helper function to compute subordinates_ids.
|
||||
Get all subordinates (direct and indirect) of an employee.
|
||||
An employee can be a manager of his own manager (recursive hierarchy; e.g. the CEO is manager of everyone but is also
|
||||
member of the RD department, managed by the CTO itself managed by the CEO).
|
||||
In that case, the manager in not counted as a subordinate if it's in the 'parents' set.
|
||||
"""
|
||||
class HrEmployeePublic(models.Model):
|
||||
_inherit = ["hr.employee.public"]
|
||||
|
||||
if not parents:
|
||||
parents = self.env['hr.employee']
|
||||
|
||||
indirect_subordinates = self.env['hr.employee']
|
||||
parents |= self
|
||||
direct_subordinates = self.child_ids - parents
|
||||
for child in direct_subordinates:
|
||||
child_subordinate = child._get_subordinates(parents=parents)
|
||||
child.subordinate_ids = child_subordinate
|
||||
indirect_subordinates |= child_subordinate
|
||||
return indirect_subordinates | direct_subordinates
|
||||
|
||||
|
||||
@api.depends('child_ids', 'child_ids.child_all_count')
|
||||
def _compute_subordinates(self):
|
||||
for employee in self:
|
||||
employee.subordinate_ids = employee._get_subordinates()
|
||||
employee.child_all_count = len(employee.subordinate_ids)
|
||||
subordinate_ids = fields.One2many('hr.employee.public', string='Subordinates', compute='_compute_subordinates', help="Direct and indirect subordinates")
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class HrEmployeeBase(models.AbstractModel):
|
||||
_inherit = "hr.employee.base"
|
||||
|
||||
child_all_count = fields.Integer(
|
||||
'Indirect Surbordinates Count',
|
||||
compute='_compute_subordinates', store=False)
|
||||
|
||||
def _get_subordinates(self, parents=None):
|
||||
"""
|
||||
Helper function to compute subordinates_ids.
|
||||
Get all subordinates (direct and indirect) of an employee.
|
||||
An employee can be a manager of his own manager (recursive hierarchy; e.g. the CEO is manager of everyone but is also
|
||||
member of the RD department, managed by the CTO itself managed by the CEO).
|
||||
In that case, the manager in not counted as a subordinate if it's in the 'parents' set.
|
||||
"""
|
||||
if not parents:
|
||||
parents = self.env[self._name]
|
||||
|
||||
indirect_subordinates = self.env[self._name]
|
||||
parents |= self
|
||||
direct_subordinates = self.child_ids - parents
|
||||
for child in direct_subordinates:
|
||||
child_subordinate = child._get_subordinates(parents=parents)
|
||||
child.subordinate_ids = child_subordinate
|
||||
indirect_subordinates |= child_subordinate
|
||||
return indirect_subordinates | direct_subordinates
|
||||
|
||||
|
||||
@api.depends('child_ids', 'child_ids.child_all_count')
|
||||
def _compute_subordinates(self):
|
||||
for employee in self:
|
||||
employee.subordinate_ids = employee._get_subordinates()
|
||||
employee.child_all_count = len(employee.subordinate_ids)
|
||||
@@ -24,7 +24,7 @@ var FieldOrgChart = AbstractField.extend({
|
||||
init: function (parent, options) {
|
||||
this._super.apply(this, arguments);
|
||||
this.dm = new concurrency.DropMisordered();
|
||||
this.employee;
|
||||
this.employee = null;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -37,16 +37,16 @@ var FieldOrgChart = AbstractField.extend({
|
||||
* @param {integer} employee_id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_getOrgData: function (employee_id) {
|
||||
_getOrgData: function () {
|
||||
var self = this;
|
||||
return this.dm.add(this._rpc({
|
||||
route: '/hr/get_org_chart',
|
||||
params: {
|
||||
employee_id: employee_id,
|
||||
employee_id: this.employee,
|
||||
context: session.user_context,
|
||||
},
|
||||
})).then(function (data) {
|
||||
self.orgData = data;
|
||||
return data;
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -83,10 +83,9 @@ var FieldOrgChart = AbstractField.extend({
|
||||
}
|
||||
|
||||
var self = this;
|
||||
return this._getOrgData(this.employee).then(function () {
|
||||
|
||||
self.orgData['view_employee_id'] = self.recordData.id;
|
||||
self.$el.html(QWeb.render("hr_org_chart", self.orgData));
|
||||
return this._getOrgData().then(function (orgData) {
|
||||
orgData.view_employee_id = self.recordData.id;
|
||||
self.$el.html(QWeb.render("hr_org_chart", orgData));
|
||||
self.$('[data-toggle="popover"]').each(function () {
|
||||
$(this).popover({
|
||||
html: true,
|
||||
@@ -130,7 +129,7 @@ var FieldOrgChart = AbstractField.extend({
|
||||
_onEmployeeMoreManager: function(event) {
|
||||
event.preventDefault();
|
||||
this.employee = parseInt($(event.currentTarget).data('employee-id'));
|
||||
this._render()
|
||||
this._render();
|
||||
},
|
||||
/**
|
||||
* Redirect to the employee form view.
|
||||
@@ -140,16 +139,15 @@ var FieldOrgChart = AbstractField.extend({
|
||||
* @returns {Promise} action loaded
|
||||
*/
|
||||
_onEmployeeRedirect: function (event) {
|
||||
var self = this;
|
||||
event.preventDefault();
|
||||
var employee_id = parseInt($(event.currentTarget).data('employee-id'));
|
||||
return this.do_action({
|
||||
type: 'ir.actions.act_window',
|
||||
view_type: 'form',
|
||||
view_mode: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'current',
|
||||
res_model: 'hr.employee',
|
||||
res_id: employee_id,
|
||||
return this._rpc({
|
||||
model: 'hr.employee',
|
||||
method: 'get_formview_action',
|
||||
args: [employee_id],
|
||||
}).then(function(action) {
|
||||
return self.do_action(action);
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -164,22 +162,23 @@ var FieldOrgChart = AbstractField.extend({
|
||||
var employee_id = parseInt($(event.currentTarget).data('employee-id'));
|
||||
var employee_name = $(event.currentTarget).data('employee-name');
|
||||
var type = $(event.currentTarget).data('type') || 'direct';
|
||||
var self = this
|
||||
var self = this;
|
||||
if (employee_id) {
|
||||
this._getSubordinatesData(employee_id, type).then(function(data) {
|
||||
var domain = [['id', 'in', data]];
|
||||
|
||||
return self.do_action({
|
||||
name: employee_name,
|
||||
type: 'ir.actions.act_window',
|
||||
view_mode: 'kanban,list,form',
|
||||
views: [[false, 'kanban'], [false, 'list'], [false, 'form']],
|
||||
target: 'current',
|
||||
res_model: 'hr.employee',
|
||||
domain: domain,
|
||||
return self._rpc({
|
||||
model: 'hr.employee',
|
||||
method: 'get_formview_action',
|
||||
args: [employee_id],
|
||||
}).then(function(action) {
|
||||
action = _.extend(action, {
|
||||
'view_mode': 'kanban,list,form',
|
||||
'views': [[false, 'kanban'], [false, 'list'], [false, 'form']],
|
||||
'domain': domain,
|
||||
});
|
||||
return self.do_action(action);
|
||||
});
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
use bg-images to get a clean and centred images -->
|
||||
<a t-if="! is_self"
|
||||
class="o_media_object rounded-circle o_employee_redirect"
|
||||
t-att-style="'background-image:url(\'/web/image/hr.employee/' + employee.id + '/image/\')'"
|
||||
t-att-style="'background-image:url(\'/web/image/hr.employee.public/' + employee.id + '/image/\')'"
|
||||
t-att-alt="employee.name"
|
||||
t-att-data-employee-id="employee.id"
|
||||
t-att-href="employee.link"/>
|
||||
<div t-if="is_self"
|
||||
class="o_media_object rounded-circle"
|
||||
t-att-style="'background-image:url(\'/web/image/hr.employee/' + employee.id + '/image/\')'"/>
|
||||
t-att-style="'background-image:url(\'/web/image/hr.employee.public/' + employee.id + '/image/\')'"/>
|
||||
</div>
|
||||
|
||||
<div class="media-body">
|
||||
@@ -151,7 +151,7 @@
|
||||
|
||||
<t t-name="hr_orgchart_emp_popover_title">
|
||||
<div>
|
||||
<span t-att-style='"background-image:url(\"/web/image/hr.employee/" + employee.id + "/image/\")"'/>
|
||||
<span t-att-style='"background-image:url(\"/web/image/hr.employee.public/" + employee.id + "/image/\")"'/>
|
||||
<a href="#" class="float-right o_employee_redirect" t-att-data-employee-id="employee.id"><i class="fa fa-external-link" role="img" aria-label='Redirect' title="Redirect"></i></a>
|
||||
<b><t t-esc="employee.name"/></b>
|
||||
</div>
|
||||
|
||||
@@ -41,6 +41,8 @@ QUnit.module('hr_org_chart', {
|
||||
managers: [],
|
||||
managers_more: false,
|
||||
});
|
||||
} else if (route === '/hr/get_redirect_model') {
|
||||
return Promise.resolve('hr.employee');
|
||||
}
|
||||
return this._super(route, args);
|
||||
}
|
||||
@@ -92,6 +94,8 @@ QUnit.module('hr_org_chart', {
|
||||
name: 'Antoine Langlais',
|
||||
}
|
||||
});
|
||||
} else if (route === '/hr/get_redirect_model') {
|
||||
return Promise.resolve('hr.employee');
|
||||
}
|
||||
return this._super(route, args);
|
||||
}
|
||||
@@ -153,6 +157,8 @@ QUnit.module('hr_org_chart', {
|
||||
name: 'John Smith',
|
||||
}
|
||||
});
|
||||
} else if (route === '/hr/get_redirect_model') {
|
||||
return Promise.resolve('hr.employee');
|
||||
}
|
||||
return this._super(route, args);
|
||||
}
|
||||
@@ -164,4 +170,4 @@ QUnit.module('hr_org_chart', {
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,22 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_employee_public_view_form_inherit_org_chart" model="ir.ui.view">
|
||||
<field name="name">hr.employee.public.view.form.inherit.org_chart</field>
|
||||
<field name="model">hr.employee.public</field>
|
||||
<field name="inherit_id" ref="hr.hr_employee_public_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='o_work_employee_main']" position="after">
|
||||
<group>
|
||||
<div id="o_employee_right">
|
||||
<h4 class="o_org_chart_title mb16 mt0">Organization Chart</h4>
|
||||
<field name="child_ids" widget="hr_org_chart"/>
|
||||
</div>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_users_view_form" model="ir.ui.view">
|
||||
<field name="name">res.users.preferences.view.form.inherit.org_chart</field>
|
||||
<field name="model">res.users</field>
|
||||
|
||||
Reference in New Issue
Block a user