diff --git a/nuke_mid_task/__init__.py b/nuke_mid_task/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/nuke_mid_task/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/nuke_mid_task/__manifest__.py b/nuke_mid_task/__manifest__.py new file mode 100644 index 0000000..93dde30 --- /dev/null +++ b/nuke_mid_task/__manifest__.py @@ -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, +} \ No newline at end of file diff --git a/nuke_mid_task/models/__init__.py b/nuke_mid_task/models/__init__.py new file mode 100644 index 0000000..edf2d36 --- /dev/null +++ b/nuke_mid_task/models/__init__.py @@ -0,0 +1 @@ +from . import project_task diff --git a/nuke_mid_task/models/project_task.py b/nuke_mid_task/models/project_task.py new file mode 100644 index 0000000..26bf628 --- /dev/null +++ b/nuke_mid_task/models/project_task.py @@ -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', + } diff --git a/nuke_mid_task/security/ir.model.access.csv b/nuke_mid_task/security/ir.model.access.csv new file mode 100644 index 0000000..97dd8b9 --- /dev/null +++ b/nuke_mid_task/security/ir.model.access.csv @@ -0,0 +1 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink diff --git a/nuke_mid_task/views/project_task_views.xml b/nuke_mid_task/views/project_task_views.xml new file mode 100644 index 0000000..e116dbb --- /dev/null +++ b/nuke_mid_task/views/project_task_views.xml @@ -0,0 +1,22 @@ + + + + project.task.form.inherit.nuke + project.task + + + + + + +