Files
odoo_source/addons/hr_org_chart/models/models.py
T
Xavier Bol (xbo) 16c4a54d42 [ADD] hr_org_chart: add hierarchy view
This commit adds a new view called hierarchy view, that view allows
the user to visualize a hierarchy in a model. For instance, that view
could be used for `hr.employee` to easily visualize the hierarchy
inside the company (the manager and his employees) as an Organization
Chart.
That commit introduces a new method for the hierarchy view, called
`hierarchy_read`, that method will be when the view will be loaded
to get the initial data to display.

Some details for the definition of that new view:
------------------------------------------------

Some attributes can be defined on the `hierarchy` tag:
- `parent_field` (default='parent_id') contains the parent field name
  to use to find the parent record of the current to build the hierarchy.
- `child_field` (optional attribute) contains the child field name
  to use to find the child records (it is in fact the one2many field).
  If that field is defined then some queries can be avoided since we
  directly fetch the children when a read/search_read is done.

Inside the `hierarchy` tag, the fields to read can be added and then
a template as to be defined as we do when we define the kanban view.
The template to create is called `hierarchy-box` and that template
will be used to display the card inside a node in the hierarchy view.

task-3376776
2023-10-16 08:17:31 +02:00

45 lines
1.8 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
class Base(models.AbstractModel):
_inherit = 'base'
@api.model
def hierarchy_read(self, domain, fields, parent_field, child_field=None):
if parent_field not in fields:
fields.append(parent_field)
records = self.search(domain)
focus_record = self.env[self._name]
fetch_child_ids_for_all_records = False
if len(records) == 1:
domain = [(parent_field, '=', records.id), ('id', '!=', records.id)]
if records[parent_field]:
focus_record = records
records += focus_record[parent_field]
domain = [('id', 'not in', records.ids), (parent_field, 'in', records.ids)]
records += self.search(domain)
elif not records:
records = self.search([(parent_field, '=', False)])
else:
fetch_child_ids_for_all_records = True
children_ids_per_record_id = {}
if not child_field:
children_ids_per_record_id = {
record.id: child_ids
for record, child_ids in self._read_group(
[(parent_field, 'in', records.ids if fetch_child_ids_for_all_records else (records - records[parent_field]).ids)],
(parent_field,),
('id:array_agg',),
)
}
result = records.read(fields)
if children_ids_per_record_id or focus_record:
for record_data in result:
if record_data['id'] in children_ids_per_record_id:
record_data['__child_ids__'] = children_ids_per_record_id[record_data['id']]
if record_data['id'] == focus_record.id:
record_data['__focus__'] = True
return result