45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
from odoo import models
|
||
|
||
|
||
class ProjectTask(models.Model):
|
||
_inherit = 'project.task'
|
||
|
||
def get_hierarchy(self, project_id=None):
|
||
"""返回项目下任务的树形结构(嵌套 children),供前端 D3 渲染。
|
||
|
||
:param project_id: 项目ID,为空则返回所有任务
|
||
:return: 含虚拟根的嵌套字典
|
||
"""
|
||
domain = []
|
||
if project_id:
|
||
domain.append(('project_id', '=', project_id))
|
||
tasks = self.search(domain)
|
||
|
||
by_id = {}
|
||
for t in tasks:
|
||
by_id[t.id] = {
|
||
'id': t.id,
|
||
'name': t.name or '未命名',
|
||
'parent_id': t.parent_id.id if t.parent_id else None,
|
||
'progress': round(t.progress or 0),
|
||
'user_id': t.user_id.name if t.user_id else False,
|
||
'stage_id': t.stage_id.name if t.stage_id else False,
|
||
'date_deadline': t.date_deadline.strftime('%Y-%m-%d') if t.date_deadline else False,
|
||
'children': [],
|
||
}
|
||
|
||
roots = []
|
||
for t in tasks:
|
||
node = by_id[t.id]
|
||
pid = node['parent_id']
|
||
if pid and pid in by_id:
|
||
by_id[pid]['children'].append(node)
|
||
else:
|
||
roots.append(node)
|
||
|
||
return {
|
||
'id': 0,
|
||
'name': '项目任务',
|
||
'children': roots,
|
||
}
|