From b12ebdfd4e973d3ecf86bac64cbb9cdd97b89ac1 Mon Sep 17 00:00:00 2001 From: Vincent Larcin Date: Wed, 31 May 2023 12:50:03 +0200 Subject: [PATCH] [IMP] sale_{project,timesheet}: Add SO stat button to projects This commit adds a "Sales Order" stat button in the project form view to ease the creation of a SO from a project. This stat button is displayed if the project is billable and has a partner. Task-3278895 --- addons/sale_project/models/project.py | 6 +- addons/sale_project/models/sale_order.py | 13 ++++ .../sale_project/views/project_task_views.xml | 59 +++++++++++++++++++ .../views/project_task_views.xml | 6 ++ 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index 9a9c2cfcb21..b5535e47167 100755 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -121,10 +121,10 @@ class Project(models.Model): action_window = { "type": "ir.actions.act_window", "res_model": "sale.order", - 'name': _("%(name)s's Sales Order", name=self.name), - "context": {"create": False, "show_sale": True}, + 'name': _("%(name)s's Sales Orders", name=self.name), + "context": {"create": self.env.context.get('create_for_project_id'), "show_sale": True}, } - if len(all_sale_orders) == 1: + if len(all_sale_orders) <= 1: action_window.update({ "res_id": all_sale_orders.id, "views": [[False, "form"]], diff --git a/addons/sale_project/models/sale_order.py b/addons/sale_project/models/sale_order.py index d28ce045b1d..db4b6f9224b 100644 --- a/addons/sale_project/models/sale_order.py +++ b/addons/sale_project/models/sale_order.py @@ -4,6 +4,7 @@ from collections import defaultdict from odoo import api, fields, models, _ +from odoo.exceptions import UserError from odoo.tools.safe_eval import safe_eval @@ -203,6 +204,18 @@ class SaleOrder(models.Model): } } + @api.model_create_multi + def create(self, vals_list): + created_records = super().create(vals_list) + project = self.env['project.project'].browse(self.env.context.get('create_for_project_id')) + if project: + service_sol = next((sol for sol in created_records.order_line if sol.is_service), False) + if not service_sol: + raise UserError(_('This Sales Order must contain at least one product of type "Service".')) + if not project.sale_line_id: + project.sale_line_id = service_sol + return created_records + def write(self, values): if 'state' in values and values['state'] == 'cancel': self.project_id.sudo().sale_line_id = False diff --git a/addons/sale_project/views/project_task_views.xml b/addons/sale_project/views/project_task_views.xml index 28949b36d73..469a1d0e97c 100644 --- a/addons/sale_project/views/project_task_views.xml +++ b/addons/sale_project/views/project_task_views.xml @@ -49,6 +49,65 @@ project.project +
+ + + +
diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml index 3dc93ba4bb4..257bd6500c5 100644 --- a/addons/sale_timesheet/views/project_task_views.xml +++ b/addons/sale_timesheet/views/project_task_views.xml @@ -6,6 +6,12 @@ project.project + + {'create_for_project_id': active_id, 'default_project_id': active_id, 'default_partner_id': partner_id, 'default_analytic_account_id': analytic_account_id} + + + {'create_for_project_id': active_id, 'default_project_id': active_id, 'default_partner_id': partner_id, 'default_analytic_account_id': analytic_account_id} +