diff --git a/addons/sale_timesheet/models/product.py b/addons/sale_timesheet/models/product.py index b3035565c9b..2f3c86d562f 100644 --- a/addons/sale_timesheet/models/product.py +++ b/addons/sale_timesheet/models/product.py @@ -20,4 +20,3 @@ class ProductTemplate(models.Model): self.track_service = 'timesheet' else: self.track_service = 'manual' - diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index a11e320a645..da90a057137 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -58,16 +58,9 @@ class SaleOrder(models.Model): @api.multi def action_confirm(self): + """ On SO confirmation, some lines should generate a task or a project. """ result = super(SaleOrder, self).action_confirm() - for order in self: - if not order.project_project_id: - for line in order.order_line: - if line.product_id.track_service == 'timesheet': - if not order.project_id: - 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_service_task)._timesheet_find_task() + self.order_line._timesheet_service_generation() return result @api.multi @@ -133,22 +126,25 @@ class SaleOrder(models.Model): 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') + task_id = fields.Many2one('project.task', 'Task', help="Task generated by the sales order item") + is_service = fields.Boolean("Is service", compute='_compute_is_service', help="Sales Order item should generate a task and/or a project, depending on the product settings.") @api.multi - def _compute_is_service_task(self): + def _compute_is_service(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' + so_line.is_service = so_line.product_id.type == 'service' and so_line.product_id.track_service in ['task', 'timesheet'] @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._timesheet_find_task() + if line.state == 'sale': + line._timesheet_service_generation() return line + ########################################### + ### Analytic : auto recompute delivered quantity + ########################################### + def _timesheet_compute_delivered_quantity_domain(self): # TODO JEM: avoid increment delivered for all AAL or just timesheet ? # see nim commit https://github.com/odoo/odoo/commit/21fbb9776a5fbd1838b189f1f7cf8c5d40663e14 @@ -161,6 +157,10 @@ class SaleOrderLine(models.Model): timesheet_domain = self._timesheet_compute_delivered_quantity_domain() return expression.OR([domain, timesheet_domain]) + ########################################### + ## Service : Project and task generation + ########################################### + def _convert_qty_company_hours(self): company_time_uom_id = self.env.user.company_id.project_time_mode_id if self.product_uom.id != company_time_uom_id.id and self.product_uom.category_id.id == company_time_uom_id.category_id.id: @@ -170,18 +170,19 @@ class SaleOrderLine(models.Model): return planned_hours def _timesheet_find_project(self): + self.ensure_one() Project = self.env['project.project'] project = self.product_id.with_context(force_company=self.company_id.id).project_id if not project: # find the project corresponding to the analytic account of the sales order account = self.order_id.project_id if not account: - self.order_id._create_analytic_account() + self.order_id._create_analytic_account(prefix=self.product_id.default_code or None) 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}) - project = Project.browse(project_id) + project_id = account.sudo().project_create({'name': account.name}) + project = Project.sudo().browse(project_id) return project def _timesheet_create_task_prepare_values(self): @@ -243,3 +244,14 @@ class SaleOrderLine(models.Model): task = so_line._timesheet_create_task()[so_line.id] result[so_line.id] = task return result + + @api.multi + def _timesheet_service_generation(self): + """ For service lines, create the task or the project. If already exists, it simply links + the existing one to the line. + """ + for so_line in self.filtered(lambda sol: sol.is_service): + if so_line.product_id.track_service == 'task': + so_line._timesheet_find_task() + if so_line.product_id.track_service == 'timesheet': + so_line._timesheet_find_project()