[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 by749810aand45396f7. 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>
This commit is contained in:
co-authored by
MaxLarue
parent
32f14b9118
commit
2dccf4d6cd
@@ -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
|
||||
|
||||
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('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
|
||||
|
||||
@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
|
||||
|
||||
@@ -121,32 +121,12 @@ class Project(models.Model):
|
||||
class ProjectTask(models.Model):
|
||||
_inherit = "project.task"
|
||||
|
||||
@api.model
|
||||
def _get_default_partner(self):
|
||||
partner = False
|
||||
if 'default_project_id' in self.env.context: # partner from SO line is prior on one from project
|
||||
project_sudo = self.env['project.project'].browse(self.env.context['default_project_id']).sudo()
|
||||
partner = project_sudo.sale_line_id.order_partner_id
|
||||
if not partner:
|
||||
partner = super(ProjectTask, self)._get_default_partner()
|
||||
return partner
|
||||
|
||||
@api.model
|
||||
def _default_sale_line_id(self):
|
||||
sale_line_id = False
|
||||
if self._context.get('default_parent_id'):
|
||||
parent_task = self.env['project.task'].browse(self._context['default_parent_id'])
|
||||
sale_line_id = parent_task.sale_line_id.id
|
||||
if not sale_line_id and self._context.get('default_project_id'):
|
||||
project = self.env['project.project'].browse(self.env.context['default_project_id'])
|
||||
if project.billable_type != 'no':
|
||||
sale_line_id = project.sale_line_id.id
|
||||
return sale_line_id
|
||||
|
||||
sale_line_id = fields.Many2one('sale.order.line', 'Sales Order Item', default=_default_sale_line_id, domain="[('is_service', '=', True), ('order_partner_id', '=', partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done'])]",
|
||||
sale_line_id = fields.Many2one('sale.order.line', 'Sales Order Item', domain="[('is_service', '=', True), ('order_partner_id', 'child_of', commercial_partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done'])]",
|
||||
compute='_compute_sale_line', store=True, readonly=False,
|
||||
help="Sales order item to which the task is linked. If an employee timesheets on a this task, "
|
||||
"and if this employee is not in the 'Employee/Sales Order Item Mapping' of the project, the "
|
||||
"timesheet entry will be linked to this sales order item.", copy=False)
|
||||
commercial_partner_id = fields.Many2one(related='partner_id.commercial_partner_id')
|
||||
sale_order_id = fields.Many2one('sale.order', 'Sales Order', compute='_compute_sale_order_id', store=True, readonly=False, help="Sales order to which the task is linked.")
|
||||
billable_type = fields.Selection([
|
||||
('task_rate', 'At Task Rate'),
|
||||
@@ -200,22 +180,21 @@ class ProjectTask(models.Model):
|
||||
result.setdefault('domain', {})['sale_line_id'] = domain
|
||||
return result
|
||||
|
||||
@api.onchange('partner_id')
|
||||
def _onchange_partner_id(self):
|
||||
result = super(ProjectTask, self)._onchange_partner_id()
|
||||
result = result or {}
|
||||
if self.sale_line_id.order_partner_id.commercial_partner_id != self.partner_id.commercial_partner_id:
|
||||
self.sale_line_id = False
|
||||
if self.partner_id:
|
||||
result.setdefault('domain', {})['sale_line_id'] = [('is_service', '=', True), ('is_expense', '=', False), ('order_partner_id', 'child_of', self.partner_id.commercial_partner_id.id), ('state', 'in', ['sale', 'done'])]
|
||||
return result
|
||||
@api.depends('project_id.sale_line_id.order_partner_id')
|
||||
def _compute_partner_id(self):
|
||||
for task in self:
|
||||
if not task.partner_id:
|
||||
task.partner_id = task.project_id.sale_line_id.order_partner_id
|
||||
super()._compute_partner_id()
|
||||
|
||||
@api.onchange('parent_id')
|
||||
def _onchange_parent_id(self):
|
||||
super(ProjectTask, self)._onchange_parent_id()
|
||||
# check sale_line_id and customer are coherent
|
||||
if self.sale_line_id and self.partner_id != self.sale_line_id.order_partner_id:
|
||||
self.sale_line_id = False
|
||||
@api.depends('partner_id.commercial_partner_id', 'sale_line_id.order_partner_id.commercial_partner_id', 'parent_id.sale_line_id', 'project_id.sale_line_id')
|
||||
def _compute_sale_line(self):
|
||||
for task in self:
|
||||
if not task.sale_line_id:
|
||||
task.sale_line_id = task.parent_id.sale_line_id or task.project_id.sale_line_id
|
||||
# check sale_line_id and customer are coherent
|
||||
if task.sale_line_id.order_partner_id.commercial_partner_id != task.partner_id.commercial_partner_id:
|
||||
task.sale_line_id = False
|
||||
|
||||
@api.constrains('sale_line_id')
|
||||
def _check_sale_line_type(self):
|
||||
@@ -236,15 +215,6 @@ class ProjectTask(models.Model):
|
||||
raise ValidationError(_('You have to unlink the task from the sale order item in order to delete it.'))
|
||||
return super(ProjectTask, self).unlink()
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Subtasks
|
||||
# ---------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _subtask_default_fields(self):
|
||||
result = super(ProjectTask, self)._subtask_default_fields()
|
||||
return result + ['sale_line_id']
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Actions
|
||||
# ---------------------------------------------------
|
||||
|
||||
@@ -7,3 +7,4 @@ from . import test_sale_service
|
||||
from . import test_project_billing
|
||||
from . import test_reinvoice
|
||||
from . import test_reporting
|
||||
from . import test_child_tasks
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details
|
||||
|
||||
from odoo.tests.common import SavepointCase, new_test_user
|
||||
|
||||
|
||||
class TestNestedTaskUpdate(SavepointCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.partner = cls.env['res.partner'].create({'name': "Mur en béton"})
|
||||
sale_order = cls.env['sale.order'].with_context(tracking_disable=True).create({
|
||||
'partner_id': cls.partner.id,
|
||||
'partner_invoice_id': cls.partner.id,
|
||||
'partner_shipping_id': cls.partner.id,
|
||||
})
|
||||
product = cls.env['product.product'].create({
|
||||
'name': "Prepaid Consulting",
|
||||
'type': 'service',
|
||||
})
|
||||
cls.order_line = cls.env['sale.order.line'].create({
|
||||
'name': "Order line",
|
||||
'product_id': product.id,
|
||||
'order_id': sale_order.id,
|
||||
})
|
||||
cls.user = new_test_user(cls.env, login='mla')
|
||||
|
||||
#----------------------------------
|
||||
#
|
||||
# When creating tasks that have a parent_id, they pick some values from their parent
|
||||
#
|
||||
#----------------------------------
|
||||
|
||||
def test_creating_subtask_user_id_on_parent_dont_go_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'user_id': self.user.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id, 'user_id': False})
|
||||
self.assertFalse(child.user_id)
|
||||
|
||||
def test_creating_subtask_partner_id_on_parent_goes_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.user.partner_id.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id})
|
||||
self.assertEqual(child.partner_id, self.user.partner_id)
|
||||
|
||||
def test_creating_subtask_email_from_on_parent_goes_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'email_from': 'a@c.be'})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id})
|
||||
self.assertEqual(child.email_from, 'a@c.be')
|
||||
|
||||
def test_creating_subtask_sale_line_id_on_parent_goes_on_child_if_same_partner_in_values(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': self.partner.id, 'parent_id': parent.id})
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
parent.write({'sale_line_id': False})
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
|
||||
def test_creating_subtask_sale_line_id_on_parent_goes_on_child_with_partner_if_not_in_values(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id})
|
||||
self.assertEqual(child.partner_id, parent.partner_id)
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
|
||||
def test_creating_subtask_sale_line_id_on_parent_dont_go_on_child_if_other_partner(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': self.user.partner_id.id, 'parent_id': parent.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
self.assertNotEqual(child.partner_id, parent.partner_id)
|
||||
|
||||
def test_creating_subtask_sale_line_id_on_parent_go_on_child_if_same_commercial_partner(self):
|
||||
commercial_partner = self.env['res.partner'].create({'name': "Jémémy"})
|
||||
self.partner.parent_id = commercial_partner
|
||||
self.user.partner_id.parent_id = commercial_partner
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': self.user.partner_id.id, 'parent_id': parent.id})
|
||||
self.assertEqual(child.sale_line_id, self.order_line, "Sale order line on parent should be transfered to child")
|
||||
self.assertNotEqual(child.partner_id, parent.partner_id)
|
||||
|
||||
#----------------------------------------
|
||||
#
|
||||
# When writing on a parent task, some values adapt on their children
|
||||
#
|
||||
#----------------------------------------
|
||||
|
||||
def test_write_user_id_on_parent_dont_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'user_id': False})
|
||||
child = self.env['project.task'].create({'name': 'child', 'user_id': False, 'parent_id': parent.id})
|
||||
self.assertFalse(child.user_id)
|
||||
parent.write({'user_id': self.user.id})
|
||||
self.assertFalse(child.user_id)
|
||||
parent.write({'user_id': False})
|
||||
self.assertFalse(child.user_id)
|
||||
|
||||
def test_write_partner_id_on_parent_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': False})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': False, 'parent_id': parent.id})
|
||||
self.assertFalse(child.partner_id)
|
||||
parent.write({'partner_id': self.user.partner_id.id})
|
||||
self.assertEqual(child.partner_id, parent.partner_id)
|
||||
parent.write({'partner_id': False})
|
||||
self.assertEqual(child.partner_id, self.user.partner_id)
|
||||
|
||||
def test_write_email_from_on_parent_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent'})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id})
|
||||
self.assertFalse(child.email_from)
|
||||
parent.write({'email_from': 'a@c.be'})
|
||||
self.assertEqual(child.email_from, parent.email_from)
|
||||
parent.write({'email_from': ''})
|
||||
self.assertEqual(child.email_from, 'a@c.be')
|
||||
|
||||
def test_write_sale_line_id_on_parent_write_on_child_if_same_partner(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id, 'partner_id': self.partner.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
parent.write({'sale_line_id': self.order_line.id})
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
parent.write({'sale_line_id': False})
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
|
||||
def test_write_sale_line_id_on_parent_write_on_child_with_partner_if_not_set(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
parent.write({'sale_line_id': self.order_line.id})
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
self.assertEqual(child.partner_id, self.partner)
|
||||
parent.write({'sale_line_id': False})
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
|
||||
def test_write_sale_line_id_on_parent_dont_write_on_child_if_other_partner(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'parent_id': parent.id, 'partner_id': self.user.partner_id.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
parent.write({'sale_line_id': self.order_line.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
|
||||
#----------------------------------
|
||||
#
|
||||
# When linking two existent task, some values go on the child
|
||||
#
|
||||
#----------------------------------
|
||||
|
||||
def test_linking_user_id_on_parent_dont_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'user_id': self.user.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'user_id': False})
|
||||
self.assertFalse(child.user_id)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertFalse(child.user_id)
|
||||
|
||||
def test_linking_partner_id_on_parent_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.user.partner_id.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': False})
|
||||
self.assertFalse(child.partner_id)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertEqual(child.partner_id, self.user.partner_id)
|
||||
|
||||
def test_linking_email_from_on_parent_write_on_child(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'email_from': 'a@c.be'})
|
||||
child = self.env['project.task'].create({'name': 'child', 'email_from': False})
|
||||
self.assertFalse(child.email_from)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertEqual(child.email_from, 'a@c.be')
|
||||
|
||||
def test_linking_sale_line_id_on_parent_write_on_child_if_same_partner(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': self.partner.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
parent.write({'sale_line_id': False})
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
|
||||
def test_linking_sale_line_id_on_parent_write_on_child_with_partner_if_not_set(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': False})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
self.assertFalse(child.partner_id)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertEqual(child.partner_id, parent.partner_id)
|
||||
self.assertEqual(child.sale_line_id, parent.sale_line_id)
|
||||
|
||||
def test_linking_sale_line_id_on_parent_write_dont_child_if_other_partner(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id})
|
||||
child = self.env['project.task'].create({'name': 'child', 'partner_id': self.user.partner_id.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
self.assertNotEqual(child.partner_id, parent.partner_id)
|
||||
child.write({'parent_id': parent.id})
|
||||
self.assertFalse(child.sale_line_id)
|
||||
|
||||
def test_writing_on_parent_with_multiple_tasks(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'user_id': False, 'partner_id': self.partner.id})
|
||||
children_values = [{'name': 'child%s' % i, 'user_id': False, 'parent_id': parent.id} for i in range(5)]
|
||||
children = self.env['project.task'].create(children_values)
|
||||
# test writing sale_line_id
|
||||
for child in children:
|
||||
self.assertFalse(child.sale_line_id)
|
||||
parent.write({'sale_line_id': self.order_line.id})
|
||||
for child in children:
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
|
||||
def test_linking_on_parent_with_multiple_tasks(self):
|
||||
parent = self.env['project.task'].create({'name': 'parent', 'partner_id': self.partner.id, 'sale_line_id': self.order_line.id, 'user_id': self.user.id})
|
||||
children_values = [{'name': 'child%s' % i, 'user_id': False} for i in range(5)]
|
||||
children = self.env['project.task'].create(children_values)
|
||||
# test writing user_id and sale_line_id
|
||||
|
||||
for child in children:
|
||||
self.assertFalse(child.user_id)
|
||||
self.assertFalse(child.sale_line_id)
|
||||
|
||||
children.write({'parent_id': parent.id})
|
||||
|
||||
for child in children:
|
||||
self.assertEqual(child.sale_line_id, self.order_line)
|
||||
self.assertFalse(child.user_id)
|
||||
@@ -598,4 +598,4 @@ class TestSaleService(TestCommonSaleTimesheetNoChart):
|
||||
|
||||
# copy the task
|
||||
task_copy = task.copy()
|
||||
self.assertEqual(task.sale_line_id, task_copy.sale_line_id, "Duplicatinga task should keep its Sale line")
|
||||
self.assertFalse(task_copy.sale_line_id, "Duplicatinga task should not keep its Sale line")
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<field name="sale_line_id" string="Sales Order Item" attrs="{'invisible': ['|', ('partner_id', '=', False), '&', ('sale_order_id', '!=', False), ('sale_line_id', '=', False)]}" options='{"no_open": True}' readonly="1" context="{'create': False, 'edit': False, 'delete': False}"/>
|
||||
<field name="billable_type" invisible="1"/>
|
||||
<field name="sale_order_id" invisible="1" />
|
||||
<field name="commercial_partner_id" invisible="1" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user