nuke task
This commit is contained in:
parent
5050839056
commit
1db303d0a5
6 changed files with 128 additions and 0 deletions
1
nuke_mid_task/__init__.py
Normal file
1
nuke_mid_task/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import models
|
||||||
28
nuke_mid_task/__manifest__.py
Normal file
28
nuke_mid_task/__manifest__.py
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
'name': 'Task Nuker',
|
||||||
|
'version': '17.0.1.0.0',
|
||||||
|
'category': 'Project',
|
||||||
|
'summary': 'Add ability to nuke intermediate tasks while preserving hierarchy',
|
||||||
|
'description': """
|
||||||
|
This module adds a 'Nuke' button on tasks that have both parent and child tasks.
|
||||||
|
When activated:
|
||||||
|
- Requests confirmation
|
||||||
|
- Reassigns all child tasks to the parent task
|
||||||
|
- Deletes the intermediate task
|
||||||
|
- Logs the action in the chatter of both parent and child tasks
|
||||||
|
""",
|
||||||
|
'author': 'DurPro',
|
||||||
|
'website': 'https://www.durpro.com',
|
||||||
|
'depends': [
|
||||||
|
'project',
|
||||||
|
],
|
||||||
|
'data': [
|
||||||
|
'views/project_task_views.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
],
|
||||||
|
'assets': {},
|
||||||
|
'license': 'LGPL-3',
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
'auto_install': False,
|
||||||
|
}
|
||||||
1
nuke_mid_task/models/__init__.py
Normal file
1
nuke_mid_task/models/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import project_task
|
||||||
75
nuke_mid_task/models/project_task.py
Normal file
75
nuke_mid_task/models/project_task.py
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
from odoo import models, api, fields, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
class ProjectTask(models.Model):
|
||||||
|
_inherit = 'project.task'
|
||||||
|
|
||||||
|
can_be_nuked = fields.Boolean(
|
||||||
|
compute='_compute_can_be_nuked',
|
||||||
|
help="Technical field to determine if task can be nuked"
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends('parent_id', 'child_ids')
|
||||||
|
def _compute_can_be_nuked(self):
|
||||||
|
"""Compute if the task can be nuked based on parent and children presence"""
|
||||||
|
for task in self:
|
||||||
|
task.can_be_nuked = bool(task.parent_id and task.child_ids)
|
||||||
|
|
||||||
|
def action_nuke_task(self):
|
||||||
|
"""
|
||||||
|
Nuke the current task:
|
||||||
|
1. Verify the task can be nuked
|
||||||
|
2. Get parent and children
|
||||||
|
3. Reassign all children to the parent
|
||||||
|
4. Update children names to include nuked task name
|
||||||
|
5. Post messages in the chatter
|
||||||
|
6. Delete the current task
|
||||||
|
7. Return action to redirect to parent task
|
||||||
|
"""
|
||||||
|
self.ensure_one()
|
||||||
|
if not self.can_be_nuked:
|
||||||
|
raise UserError(_("This task cannot be nuked. It must have both a parent and child tasks."))
|
||||||
|
|
||||||
|
parent = self.parent_id
|
||||||
|
children = self.child_ids
|
||||||
|
nuked_name = self.name
|
||||||
|
|
||||||
|
# Post message to parent about the upcoming changes
|
||||||
|
parent.message_post(
|
||||||
|
body=_(
|
||||||
|
"The following task has been nuked: %(task)s\n"
|
||||||
|
"%(count)d child tasks have been reassigned to this task."
|
||||||
|
) % {
|
||||||
|
'task': nuked_name,
|
||||||
|
'count': len(children)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Reassign all children to the parent, update their names and notify them
|
||||||
|
for child in children:
|
||||||
|
old_name = child.name
|
||||||
|
# Update name to include nuked task's name
|
||||||
|
child.write({
|
||||||
|
'name': f"[{nuked_name}] {old_name}",
|
||||||
|
'parent_id': parent.id
|
||||||
|
})
|
||||||
|
child.message_post(
|
||||||
|
body=_("This task has been reassigned to %(new_parent)s due to the removal of %(old_parent)s.\nTask name updated from '%(old_name)s' to '%(new_name)s'") % {
|
||||||
|
'new_parent': parent.name,
|
||||||
|
'old_parent': nuked_name,
|
||||||
|
'old_name': old_name,
|
||||||
|
'new_name': child.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete the current task
|
||||||
|
self.unlink()
|
||||||
|
|
||||||
|
# Return action to redirect to parent task
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'project.task',
|
||||||
|
'res_id': parent.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'current',
|
||||||
|
}
|
||||||
1
nuke_mid_task/security/ir.model.access.csv
Normal file
1
nuke_mid_task/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
22
nuke_mid_task/views/project_task_views.xml
Normal file
22
nuke_mid_task/views/project_task_views.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_task_form_inherit_nuke" model="ir.ui.view">
|
||||||
|
<field name="name">project.task.form.inherit.nuke</field>
|
||||||
|
<field name="model">project.task</field>
|
||||||
|
<field name="inherit_id" ref="project.view_task_form2"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='recurrence_id']" position="after">
|
||||||
|
<field name="can_be_nuked" invisible="1"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//header" position="inside">
|
||||||
|
<button
|
||||||
|
name="action_nuke_task"
|
||||||
|
string="Nuke Task"
|
||||||
|
type="object"
|
||||||
|
confirm="Are you sure you want to nuke this task? All child tasks will be reassigned to the parent task."
|
||||||
|
invisible="not can_be_nuked"
|
||||||
|
groups="project.group_project_manager"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in a new issue