diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py
index 37e2f4bf9fe..a11e320a645 100644
--- a/addons/sale_timesheet/models/sale_order.py
+++ b/addons/sale_timesheet/models/sale_order.py
@@ -67,7 +67,7 @@ class SaleOrder(models.Model):
order._create_analytic_account(prefix=line.product_id.default_code or None)
order.project_id.project_create({'name': order.project_id.name})
break
- order.order_line.filtered(lambda line: line._is_task())._create_task()
+ order.order_line.filtered(lambda line: line.is_service_task)._timesheet_find_task()
return result
@api.multi
@@ -134,13 +134,19 @@ class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
task_id = fields.Many2one('project.task', 'Task')
+ is_service_task = fields.Boolean("Will create a task", compute='_compute_is_service_task')
+
+ @api.multi
+ def _compute_is_service_task(self):
+ for so_line in self:
+ so_line.is_service_task = so_line.product_id.type == 'service' and so_line.product_id.track_service == 'task'
@api.model
def create(self, values):
line = super(SaleOrderLine, self).create(values)
if line.state == 'sale' and not line.order_id.project_id and line.product_id.track_service in ['timesheet', 'task']:
line.order_id._create_analytic_account()
- line._create_task()
+ line._timesheet_find_task()
return line
def _timesheet_compute_delivered_quantity_domain(self):
@@ -163,7 +169,7 @@ class SaleOrderLine(models.Model):
planned_hours = self.product_uom_qty
return planned_hours
- def _get_project(self):
+ def _timesheet_find_project(self):
Project = self.env['project.project']
project = self.product_id.with_context(force_company=self.company_id.id).project_id
if not project:
@@ -174,13 +180,13 @@ class SaleOrderLine(models.Model):
account = self.order_id.project_id
project = Project.search([('analytic_account_id', '=', account.id)], limit=1)
if not project:
- project_id = account.project_create({'name': account.name, 'use_tasks': True})
+ project_id = account.project_create({'name': account.name})
project = Project.browse(project_id)
return project
- def _prepare_service_task_values(self):
+ def _timesheet_create_task_prepare_values(self):
self.ensure_one()
- project = self._get_project()
+ project = self._timesheet_find_project()
planned_hours = self._convert_qty_company_hours()
return {
'name': '%s:%s' % (self.order_id.name or '', self.product_id.name),
@@ -193,12 +199,47 @@ class SaleOrderLine(models.Model):
'company_id': self.company_id.id,
}
- def _create_task(self):
- for line in self:
- task_values = line._prepare_service_task_values()
- task = self.env['project.task'].create(task_values)
- self.write({'task_id': task.id})
+ @api.multi
+ def _timesheet_create_task(self):
+ """ Generate task for the given so line, and link it.
- def _is_task(self):
- self.ensure_one()
- return self.product_id.type == 'service' and self.product_id.track_service == 'task'
+ :return a mapping with the so line id and its linked task
+ :rtype dict
+ """
+ result = {}
+ for so_line in self:
+ # create task
+ values = so_line._timesheet_create_task_prepare_values()
+ task = self.env['project.task'].sudo().create(values)
+ so_line.write({'task_id': task.id})
+ # post message on SO
+ msg_body = _("Task Created (%s): %s") % (so_line.product_id.name, task.id, task.name)
+ so_line.order_id.message_post(body=msg_body)
+ # post message on task
+ task_msg = _("This task has been created from: %s (%s)") % (so_line.order_id.id, so_line.order_id.name, so_line.product_id.name)
+ task.message_post(body=task_msg)
+
+ result[so_line.id] = task
+ return result
+
+ @api.multi
+ def _timesheet_find_task(self):
+ """ Find the task generated by the so lines. If no task linked, it will be
+ created automatically.
+
+ :return a mapping with the so line id and its linked task
+ :rtype dict
+ """
+ # one search for all so lines
+ tasks = self.env['project.task'].search([('sale_line_id', 'in', self.ids)])
+ task_sol_mapping = {task.sale_line_id.id: task for task in tasks}
+
+ result = {}
+ for so_line in self:
+ # If the SO was confirmed, cancelled, set to draft then confirmed, avoid creating a new task.
+ task = task_sol_mapping.get(so_line.id)
+ # If not found, create one task for the so line
+ if not task:
+ task = so_line._timesheet_create_task()[so_line.id]
+ result[so_line.id] = task
+ return result