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
45 lines
1.8 KiB
Python
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
|