[IMP] project: Allow multi levels on sub-tasks
Purpose ======= Currently, it is only possible to have 1 level of sub-tasks per task. The user may want several levels of granurality. Specifications ============== Allow having multi levels of sub-tasks - Move the parent_id field out of the debug mode and display it above the Deadline field - Remove the 'parent task' stat button - Add the parent_id field to the project.task optional list view - Display the sub-tasks stat button on sub-tasks - The 'sub-tasks' stat button should only count/display tasks from the first level of sub-tasks - The name of the sub-task should be parent task: sub task level 1: sub task level 2: sub task level 3... - The sub-task should be created in the sub-task project set on the parent task's project - The subtask_planned_hours and the subtask_effective_hours fields should take into account the planned hours of all sub-level tasks TaskID: 2107078
This commit is contained in:
@@ -588,15 +588,12 @@ class Task(models.Model):
|
||||
@api.depends('child_ids.planned_hours')
|
||||
def _compute_subtask_planned_hours(self):
|
||||
for task in self:
|
||||
task.subtask_planned_hours = sum(task.child_ids.mapped('planned_hours'))
|
||||
task.subtask_planned_hours = sum(child_task.planned_hours + child_task.subtask_planned_hours for child_task in task.child_ids)
|
||||
|
||||
@api.depends('child_ids')
|
||||
def _compute_subtask_count(self):
|
||||
""" Note: since we accept only one level subtask, we can use a read_group here """
|
||||
task_data = self.env['project.task'].read_group([('parent_id', 'in', self.ids)], ['parent_id'], ['parent_id'])
|
||||
mapping = dict((data['parent_id'][0], data['parent_id_count']) for data in task_data)
|
||||
for task in self:
|
||||
task.subtask_count = mapping.get(task.id, 0)
|
||||
task.subtask_count = len(self._get_all_subtasks())
|
||||
|
||||
@api.onchange('project_id')
|
||||
def _onchange_project(self):
|
||||
@@ -882,21 +879,17 @@ class Task(models.Model):
|
||||
def action_assign_to_me(self):
|
||||
self.write({'user_id': self.env.user.id})
|
||||
|
||||
def action_open_parent_task(self):
|
||||
return {
|
||||
'name': _('Parent Task'),
|
||||
'view_mode': 'form',
|
||||
'res_model': 'project.task',
|
||||
'res_id': self.parent_id.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'context': dict(self._context, create=False)
|
||||
}
|
||||
def _get_all_subtasks(self):
|
||||
children = self.mapped('child_ids')
|
||||
if not children:
|
||||
return self.env['project.task']
|
||||
return children + children._get_all_subtasks()
|
||||
|
||||
def action_subtask(self):
|
||||
action = self.env.ref('project.project_task_action_sub_task').read()[0]
|
||||
|
||||
# only display subtasks of current task
|
||||
action['domain'] = [('id', 'child_of', self.id), ('id', '!=', self.id)]
|
||||
# display all subtasks of current task
|
||||
action['domain'] = [('id', 'in', self._get_all_subtasks().ids)]
|
||||
|
||||
# update context, with all default values as 'quick_create' does not contains all field in its view
|
||||
if self._context.get('default_project_id'):
|
||||
@@ -908,7 +901,6 @@ class Task(models.Model):
|
||||
'default_name': self.env.context.get('name', self.name) + ':',
|
||||
'default_parent_id': self.id, # will give default subtask field in `default_get`
|
||||
'default_company_id': default_project.company_id.id if default_project else self.env.company.id,
|
||||
'search_default_parent_id': self.id,
|
||||
})
|
||||
|
||||
action['context'] = ctx
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<record id="project_task_action_sub_task" model="ir.actions.act_window">
|
||||
<field name="name">Sub-tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">kanban,tree,form,calendar,pivot,graph,activity</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
|
||||
<field name="search_view_id" ref="project.view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
@@ -451,9 +451,8 @@
|
||||
</header>
|
||||
<sheet string="Task">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" icon="fa-tasks" type="object" name="action_open_parent_task" string="Parent Task" attrs="{'invisible' : [('parent_id', '=', False)]}" groups="project.group_subtask_project"/>
|
||||
<button name="action_subtask" type="object" class="oe_stat_button" icon="fa-tasks"
|
||||
attrs="{'invisible' : ['|', ('parent_id', '!=', False), ('id', '=', False)]}" context="{'default_user_id': user_id, 'default_parent_id': id, 'default_project_id': subtask_project_id}" groups="project.group_subtask_project">
|
||||
attrs="{'invisible' : [('id', '=', False)]}" context="{'default_user_id': user_id, 'default_parent_id': id, 'default_project_id': subtask_project_id}" groups="project.group_subtask_project">
|
||||
<field string="Sub-tasks" name="subtask_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="%(rating_rating_action_task)d" type="action" attrs="{'invisible': [('rating_count', '=', 0)]}" class="oe_stat_button" icon="fa-smile-o" groups="project.group_project_rating">
|
||||
@@ -483,14 +482,17 @@
|
||||
<field name="user_id"
|
||||
class="o_task_user_field"
|
||||
options='{"no_open": True}'/>
|
||||
<field
|
||||
name="parent_id"
|
||||
domain="[('parent_id', '=', False)]"
|
||||
groups="project.group_subtask_project"
|
||||
/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True}"/>
|
||||
</group>
|
||||
<group name="sales_order_group">
|
||||
</group>
|
||||
<group>
|
||||
<group name="dates">
|
||||
<field name="date_deadline"/>
|
||||
</group>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True}"/>
|
||||
<group name="dates">
|
||||
<field name="date_deadline"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
@@ -504,12 +506,6 @@
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<field name="email_cc" groups="base.group_no_one"/>
|
||||
<field
|
||||
name="parent_id"
|
||||
domain="[('parent_id', '=', False)]"
|
||||
attrs="{'invisible' : [('subtask_count', '>', 0)]}"
|
||||
groups="project.group_subtask_project"
|
||||
/>
|
||||
<field name="child_ids" invisible="1" />
|
||||
<field name="subtask_project_id" invisible="1" />
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
@@ -678,9 +674,11 @@
|
||||
<tree decoration-bf="message_needaction==True" decoration-danger="date_deadline and (date_deadline<current_date)" string="Tasks">
|
||||
<field name="message_needaction" invisible="1"/>
|
||||
<field name="sequence" invisible="not context.get('seq_visible', False)"/>
|
||||
<field name="name"/>
|
||||
<field name="name"/>
|
||||
<!-- YTI TODO user_invisible and seq_visible seem to be useless -->
|
||||
<field name="project_id" invisible="context.get('user_invisible', False)" optional="show"/>
|
||||
<field name="partner_id" optional="hide"/>
|
||||
<field name="parent_id" groups="project.group_subtask_project" optional="show"/>
|
||||
<field name="user_id" invisible="context.get('user_invisible', False)" optional="show"/>
|
||||
<field name="date_deadline" optional="hide"/>
|
||||
<field name="stage_id" invisible="context.get('set_visible',False)" optional="show"/>
|
||||
|
||||
Reference in New Issue
Block a user