diff options
| author | Lucas Lefèvre <lul@odoo.com> | 2019-10-25 07:09:10 +0000 |
|---|---|---|
| committer | Lucas Lefèvre <lul@odoo.com> | 2019-10-25 14:22:36 +0000 |
| commit | 2dccf4d6cd076ed768f5ec7acbf3c41ef3e06c2e (patch) | |
| tree | 6ae6bc0cf6dedd2f2bd3c9a86b57019eddda78b7 /addons/project | |
| parent | 32f14b9118127655c55faa523268c080b7ea7f59 (diff) | |
[IMP] project: Use stored computed fields for parent to children task
Purpose
=======
When you create a task independently and link it to a Parent task later on,
several changes are applied: the person assigned on the sub-task switches
to the one set on the parent task, same for the customer, and so on.
This creates frustration because the user most likely set specific data on the
sub task for a reason. In addition, the changes are made implicitely, so the
user might not notice it or get confused as to what changed from the original
task.
Specification
=============
Values for fields `partner_id`, `email_from`, `project_id`, `sale_line_id` should be
transfered from parent task to children task, only if the value is not already set
on the child.
This was already partially implemented by 749810a and 45396f7.
But to achieve it, similar code was duplicated in several methods:
default_get, onchanges, write, create.
Since the new ORM, the same behavior can be achieved with only computed fields
with store=True and readonly=False. This commit changes the previous implementation
to take advantage of this which greatly improves code readability and maintainability.
Tests by Maximilen Larue
Business code by Lucas Lefèvre
closes odoo/odoo#39369
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Co-authored-by: MaxLarue <mla@odoo.com>
Diffstat (limited to 'addons/project')
| -rw-r--r-- | addons/project/models/project.py | 74 |
1 files changed, 21 insertions, 53 deletions
diff --git a/addons/project/models/project.py b/addons/project/models/project.py index d7d10055c7f..3581a360ce6 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -436,24 +436,6 @@ class Task(models.Model): _order = "priority desc, sequence, id desc" _check_company_auto = True - @api.model - def default_get(self, fields_list): - result = super(Task, self).default_get(fields_list) - # find default value from parent for the not given ones - parent_task_id = result.get('parent_id') or self._context.get('default_parent_id') - if parent_task_id: - parent_values = self._subtask_values_from_parent(parent_task_id) - for fname, value in parent_values.items(): - if fname not in result: - result[fname] = value - return result - - @api.model - def _get_default_partner(self): - if 'default_project_id' in self.env.context: - default_project_id = self.env['project.project'].browse(self.env.context['default_project_id']) - return default_project_id.exists().partner_id - def _get_default_stage_id(self): """ Gives default stage_id """ project_id = self.env.context.get('default_project_id') @@ -504,7 +486,8 @@ class Task(models.Model): index=True, copy=False, readonly=True) - project_id = fields.Many2one('project.project', string='Project', default=lambda self: self.env.context.get('default_project_id'), + project_id = fields.Many2one('project.project', string='Project', + compute='_compute_project_id', store=True, readonly=False, index=True, tracking=True, check_company=True, change_default=True) planned_hours = fields.Float("Planned Hours", help='It is the time planned to achieve the task. If this document has sub-tasks, it means the time needed to achieve this tasks and its childs.',tracking=True) subtask_planned_hours = fields.Float("Subtasks", compute='_compute_subtask_planned_hours', help="Computed using sum of hours planned of all subtasks created from main task. Usually these hours are less or equal to the Planned Hours (of main task).") @@ -514,7 +497,7 @@ class Task(models.Model): index=True, tracking=True) partner_id = fields.Many2one('res.partner', string='Customer', - default=lambda self: self._get_default_partner(), + compute='_compute_partner_id', store=True, readonly=False, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") partner_city = fields.Char(related='partner_id.city', readonly=False) manager_id = fields.Many2one('res.users', string='Project Manager', related='project_id.user_id', readonly=True, related_sudo=False) @@ -532,7 +515,8 @@ class Task(models.Model): child_ids = fields.One2many('project.task', 'parent_id', string="Sub-tasks", context={'active_test': False}) subtask_project_id = fields.Many2one('project.project', related="project_id.subtask_project_id", string='Sub-task Project', readonly=True) subtask_count = fields.Integer("Sub-task count", compute='_compute_subtask_count') - email_from = fields.Char(string='Email', help="These people will receive email.", index=True) + email_from = fields.Char(string='Email', help="These people will receive email.", index=True, + compute='_compute_email_from', store="True", readonly=False) # Computed field about working time elapsed between record creation and assignation/closing. working_hours_open = fields.Float(compute='_compute_elapsed', string='Working hours to assign', store=True, group_operator="avg") working_hours_close = fields.Float(compute='_compute_elapsed', string='Working hours to close', store=True, group_operator="avg") @@ -610,17 +594,6 @@ class Task(models.Model): for task in self: task.subtask_count = mapping.get(task.id, 0) - @api.onchange('partner_id') - def _onchange_partner_id(self): - self.email_from = self.partner_id.email - - @api.onchange('parent_id') - def _onchange_parent_id(self): - if self.parent_id: - for field_name, value in self._subtask_values_from_parent(self.parent_id.id).items(): - if not self[field_name]: - self[field_name] = value - @api.onchange('project_id') def _onchange_project(self): if self.project_id: @@ -713,11 +686,6 @@ class Task(models.Model): if vals.get('stage_id'): vals.update(self.update_date_end(vals['stage_id'])) vals['date_last_stage_update'] = fields.Datetime.now() - # substask default values - if vals.get('parent_id'): - for fname, value in self._subtask_values_from_parent(vals['parent_id']).items(): - if fname not in vals: - vals[fname] = value task = super(Task, self.with_context(context)).create(vals) return task @@ -750,19 +718,22 @@ class Task(models.Model): # Subtasks # --------------------------------------------------- - def _subtask_default_fields(self): - """ Return the list of field name for default value when creating a subtask """ - return ['partner_id', 'email_from'] + @api.depends('parent_id.partner_id', 'project_id.partner_id') + def _compute_partner_id(self): + for task in self: + if not task.partner_id: + task.partner_id = task.parent_id.partner_id or task.project_id.partner_id + + @api.depends('partner_id.email', 'parent_id.email_from') + def _compute_email_from(self): + for task in self: + task.email_from = task.partner_id.email or task.email_from or task.parent_id.email_from - def _subtask_values_from_parent(self, parent_id): - """ Get values for substask implied field of the given""" - result = {} - parent_task = self.env['project.task'].browse(parent_id) - for field_name in self._subtask_default_fields(): - result[field_name] = parent_task[field_name] - # special case for the subtask default project - result['project_id'] = parent_task.project_id.subtask_project_id - return self._convert_to_write(result) + @api.depends('parent_id.project_id.subtask_project_id') + def _compute_project_id(self): + for task in self: + if not task.project_id: + task.project_id = task.parent_id.project_id.subtask_project_id # --------------------------------------------------- # Mail gateway @@ -935,10 +906,7 @@ class Task(models.Model): 'default_company_id': default_project.company_id.id if default_project else self.env.company.id, 'search_default_parent_id': self.id, }) - parent_values = self._subtask_values_from_parent(self.id) - for fname, value in parent_values.items(): - if 'default_' + fname not in ctx: - ctx['default_' + fname] = value + action['context'] = ctx return action |
