diff --git a/addons/hr/models/hr_department.py b/addons/hr/models/hr_department.py index 0eb03f32020..29804f9ab9f 100644 --- a/addons/hr/models/hr_department.py +++ b/addons/hr/models/hr_department.py @@ -134,3 +134,29 @@ class Department(models.Model): def get_children_department_ids(self): return self.env['hr.department'].search([('id', 'child_of', self.ids)]) + + def get_department_hierarchy(self): + if not self: + return {} + + hierarchy = { + 'parent': { + 'id': self.parent_id.id, + 'name': self.parent_id.name, + 'employees': self.parent_id.total_employee, + } if self.parent_id else False, + 'self': { + 'id': self.id, + 'name': self.name, + 'employees': self.total_employee, + }, + 'children': [ + { + 'id': child.id, + 'name': child.name, + 'employees': child.total_employee + } for child in self.child_ids + ] + } + + return hierarchy diff --git a/addons/hr/static/src/components/department_chart/department_chart.js b/addons/hr/static/src/components/department_chart/department_chart.js new file mode 100644 index 00000000000..ca2817af7a6 --- /dev/null +++ b/addons/hr/static/src/components/department_chart/department_chart.js @@ -0,0 +1,43 @@ +/** @odoo-module */ + +import { registry } from '@web/core/registry'; +import { useService } from "@web/core/utils/hooks"; + +import { standardWidgetProps } from "@web/views/widgets/standard_widget_props"; + +const { onWillStart, useState, onWillUpdateProps, Component } = owl; + +export class DepartmentChart extends Component { + setup() { + super.setup(); + + this.action = useService('action'); + this.orm = useService('orm'); + this.state = useState({ + hierarchy: {} + }); + onWillStart(async () => await this.fetchHierarchy(this.props.record.data.id)); + + onWillUpdateProps(async (nextProps) => { + await this.fetchHierarchy(nextProps.record.data.id); + }); + } + + async fetchHierarchy(departmentId) { + this.state.hierarchy = await this.orm.call('hr.department', 'get_department_hierarchy', [departmentId]); + } + + openDepartmentEmployees(departmentId) { + this.action.doAction('hr.act_employee_from_department', { + additionalContext: { + 'active_id': departmentId, + } + }); + } +} +DepartmentChart.template = 'hr.DepartmentChart'; +DepartmentChart.props = { + ...standardWidgetProps, +}; + +registry.category("view_widgets").add("hr_department_chart", DepartmentChart); diff --git a/addons/hr/static/src/components/department_chart/department_chart.scss b/addons/hr/static/src/components/department_chart/department_chart.scss new file mode 100644 index 00000000000..a4bd7bdd27e --- /dev/null +++ b/addons/hr/static/src/components/department_chart/department_chart.scss @@ -0,0 +1,19 @@ +.o_widget_hr_department_chart { + display: flex; + justify-content: flex-end; + + .o_hr_department_chart { + .o_hr_department_chart_self { + .department_name { + font-weight: bold; + } + } + + @include media-breakpoint-up(sm) { + width: 50%; + } + @include media-breakpoint-down(md) { + flex-grow: 1; + } + } +} diff --git a/addons/hr/static/src/components/department_chart/department_chart.xml b/addons/hr/static/src/components/department_chart/department_chart.xml new file mode 100644 index 00000000000..3f85730e25a --- /dev/null +++ b/addons/hr/static/src/components/department_chart/department_chart.xml @@ -0,0 +1,47 @@ + + + +
+
Department Organization
+ +
+ + + +
+ +
+
+ + + +
+ + +
+ + + +
+
+
+
+ + + + +
+
+ + + + + + +
+
+
+
+
diff --git a/addons/hr/views/hr_department_views.xml b/addons/hr/views/hr_department_views.xml index 7986f851e75..cb2cc231935 100644 --- a/addons/hr/views/hr_department_views.xml +++ b/addons/hr/views/hr_department_views.xml @@ -18,11 +18,16 @@ - - - - - + + + + + + + +
+ +