Fixe date deadline cascade
This commit is contained in:
parent
b1a625a0e4
commit
7ab530bd29
10 changed files with 102 additions and 67 deletions
|
|
@ -9,10 +9,13 @@
|
|||
'author': 'Your Name',
|
||||
'license': 'AGPL-3',
|
||||
'website': 'https://www.yourwebsite.com',
|
||||
'depends': ['project'],
|
||||
'depends': [
|
||||
'project',
|
||||
'project_enterprise'
|
||||
],
|
||||
'data': [
|
||||
'views/update_deadline_wizard_view.xml',
|
||||
'wizard/update_deadline_wizard.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'data/res_config_settings_data.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="default_enable_task_deadline_cascade" model="ir.config_parameter">
|
||||
<field name="key">project_task_date_deadline_cascade_update.enablecascade</field>
|
||||
<field name="value">False</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import project_task
|
||||
from . import res_config_settings
|
||||
|
|
|
|||
|
|
@ -1,24 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
from odoo import api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class ProjectTask(models.Model):
|
||||
_inherit = 'project.task'
|
||||
|
||||
|
||||
@api.model
|
||||
def write(self, vals):
|
||||
res = super(ProjectTask, self).write(vals)
|
||||
if 'date_deadline' in vals:
|
||||
for task in self:
|
||||
if task.child_ids:
|
||||
return {
|
||||
'name': _('Update Deadline'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'update.deadline.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'active_ids': self.ids},
|
||||
}
|
||||
return res
|
||||
def _update_child_dates_recursive(self, date_deadline=None, planned_date_begin=None):
|
||||
"""Update dates for all subtasks at all levels using _get_all_subtasks.
|
||||
|
||||
Args:
|
||||
date_deadline: The deadline date to set for all subtasks
|
||||
planned_date_begin: The planned start date to set for all subtasks
|
||||
"""
|
||||
if not self.child_ids:
|
||||
return
|
||||
|
||||
_logger.info(
|
||||
'Starting update for all subtasks of: %s (ID: %s)',
|
||||
self.name, self.id
|
||||
)
|
||||
|
||||
# Get all subtasks at all levels
|
||||
all_subtasks = self._get_all_subtasks()
|
||||
|
||||
if all_subtasks:
|
||||
# Update both dates for all subtasks at once
|
||||
values = {
|
||||
'date_deadline': date_deadline,
|
||||
'planned_date_begin': planned_date_begin
|
||||
}
|
||||
_logger.info(
|
||||
'Updating %d subtasks with values: %s',
|
||||
len(all_subtasks), values
|
||||
)
|
||||
all_subtasks.write(values)
|
||||
|
||||
@api.onchange('date_deadline')
|
||||
def _onchange_date_deadline(self):
|
||||
"""When parent task deadline changes, update all child tasks deadlines and planned dates recursively."""
|
||||
if self.date_deadline and self.child_ids and not self.env.context.get('skip_onchange'):
|
||||
_logger.info('Recursively updating deadline and planned date for all subtasks of: %s', self.name)
|
||||
self.with_context(skip_onchange=True)._update_child_dates_recursive(
|
||||
date_deadline=self.date_deadline,
|
||||
planned_date_begin=self.planned_date_begin # Always pass planned_date_begin
|
||||
)
|
||||
|
||||
@api.onchange('planned_date_begin')
|
||||
def _onchange_planned_date_begin(self):
|
||||
"""When parent task planned date changes, update all child tasks planned dates and deadlines recursively."""
|
||||
if self.planned_date_begin and self.child_ids and not self.env.context.get('skip_onchange'):
|
||||
_logger.info('Recursively updating planned date and deadline for all subtasks of: %s', self.name)
|
||||
self.with_context(skip_onchange=True)._update_child_dates_recursive(
|
||||
planned_date_begin=self.planned_date_begin,
|
||||
date_deadline=self.date_deadline # Always pass date_deadline
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
enable_task_deadline_cascade = fields.Boolean(
|
||||
string='Enable Task Deadline Cascade',
|
||||
config_parameter='project_task_date_deadline_cascade_update.enablecascade'
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_update_deadline_wizard,access.update.deadline.wizard,model_update_deadline_wizard,project.group_project_user,1,1,1,1
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.project.task.deadline</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="inherit_id" ref="project.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//block[@id='tasks_management']" position="inside">
|
||||
<setting id="task_deadline_cascade" help="Update child tasks deadline when parent deadline changes">
|
||||
<field name="enable_task_deadline_cascade"/>
|
||||
<div class="text-muted">
|
||||
Enable deadline cascade update for project tasks
|
||||
</div>
|
||||
</setting>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_update_deadline_wizard_form" model="ir.ui.view">
|
||||
<field name="name">update.deadline.wizard.form</field>
|
||||
<field name="model">update.deadline.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Update Deadline">
|
||||
<group>
|
||||
<field name="apply_to_children"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Apply" type="object" name="update_deadline" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_update_deadline_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Update Deadline</field>
|
||||
<field name="res_model">update.deadline.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_update_deadline_wizard_form"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import update_deadline_wizard
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class UpdateDeadlineWizard(models.TransientModel):
|
||||
_name = 'update.deadline.wizard'
|
||||
_description = 'Update Deadline Wizard'
|
||||
|
||||
apply_to_children = fields.Boolean(string='Apply to Child Tasks', default=False)
|
||||
|
||||
def update_deadline(self):
|
||||
context = dict(self._context or {})
|
||||
active_ids = context.get('active_ids', [])
|
||||
tasks = self.env['project.task'].browse(active_ids)
|
||||
for task in tasks:
|
||||
if task.child_ids and self.apply_to_children:
|
||||
task.child_ids.write({'date_deadline': task.date_deadline})
|
||||
Loading…
Reference in a new issue