From 1b669d032f27d47d3bd8b5bcf94139987bffcead Mon Sep 17 00:00:00 2001 From: roen-odoo Date: Fri, 15 Oct 2021 12:07:41 +0000 Subject: [PATCH] [FIX] sale,sale_project : Avoid sending multiple email on upsell Expected behaviour: When you create a sale order with a project associated. When the sale order change state from non upsell to upsell sales person should receive one email. Current behaviour: The sales person receive an email for every entry in the timesheet after the sale order goes from non upsell to upsell. Step to reproduce: Create a sale order setup to create a project and task and the invoicing policy is ordered quantities. Add a timesheet entry which takes it past the ordered quantity. Create the invoice for the order. The state of the line and order goes to upsell, and the upsell email is sent to the salesperson. Add another line in the timesheet and the email is sent again to the salesperson opw-2581428 closes odoo/odoo#79496 X-original-commit: d9c45eae10a2a6fd42f48112b9dc3ae4ab089ea9 Signed-off-by: Laurent Stukkens (ltu) --- addons/sale/models/sale_order.py | 4 +- .../tests/test_sale_timesheet.py | 67 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/addons/sale/models/sale_order.py b/addons/sale/models/sale_order.py index 6e147242737..eb489b0034b 100644 --- a/addons/sale/models/sale_order.py +++ b/addons/sale/models/sale_order.py @@ -542,11 +542,13 @@ class SaleOrder(models.Model): return result def _compute_field_value(self, field): + if field.name == 'invoice_status' and not self.env.context.get('mail_activity_automation_skip'): + filtered_self = self.filtered(lambda so: (so.user_id or so.partner_id.user_id) and so._origin.invoice_status != 'upselling') super()._compute_field_value(field) if field.name != 'invoice_status' or self.env.context.get('mail_activity_automation_skip'): return - upselling_orders = self.filtered(lambda so: (so.user_id or so.partner_id.user_id) and so.invoice_status == 'upselling') + upselling_orders = filtered_self.filtered(lambda so: so.invoice_status == 'upselling') if not upselling_orders: return diff --git a/addons/sale_timesheet/tests/test_sale_timesheet.py b/addons/sale_timesheet/tests/test_sale_timesheet.py index 925ca719d63..f7d87d58727 100644 --- a/addons/sale_timesheet/tests/test_sale_timesheet.py +++ b/addons/sale_timesheet/tests/test_sale_timesheet.py @@ -666,3 +666,70 @@ class TestSaleTimesheet(TestCommonSaleTimesheet): self.assertEqual(self.partner_b, task_so1_timesheet2.partner_id, "The Task's second Timesheet entry should have its partner changed, as it was not invoiced and the Task's partner/customer changed.") self.assertEqual(so1_product_global_project_so_line, task_so1_timesheet1.so_line, "The Task's first Timesheet entry should not have changed as it was already invoiced (its so_line should still be equal to the first Sales Order line).") self.assertEqual(so2_product_global_project_so_line, task_so1_timesheet2.so_line, "The Task's second Timesheet entry should have it's so_line changed, as the Sales Order Item of the Task changed, and this entry was not invoiced.") + + def test_timesheet_upsell(self): + """ Test timesheet upselling and email """ + + sale_order = self.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'user_id': self.user_employee_company_B.id, + }) + # create SO and confirm it + uom_days = self.env.ref('uom.product_uom_day') + sale_order_line = self.env['sale.order.line'].create({ + 'order_id': sale_order.id, + 'name': self.product_order_timesheet3.name, + 'product_id': self.product_order_timesheet3.id, + 'product_uom_qty': 1, + 'product_uom': uom_days.id, + 'price_unit': self.product_order_timesheet3.list_price, + }) + sale_order.action_confirm() + task = sale_order_line.task_id + + # let's log some timesheets + self.env['account.analytic.line'].create({ + 'name': 'Test Line', + 'project_id': task.project_id.id, + 'task_id': task.id, + 'unit_amount': 8, + 'employee_id': self.employee_manager.id, + }) + + sale_order._create_invoices() + last_message_id = self.env['mail.message'].search([('model', '=', 'sale.order'), ('res_id', '=', sale_order.id)], limit=1).id or 0 + self.env['account.analytic.line'].create({ + 'name': 'Test Line', + 'project_id': task.project_id.id, + 'task_id': task.id, + 'unit_amount': 5, + 'employee_id': self.employee_user.id, + }) + + self.assertEqual(sale_order.invoice_status, 'upselling', 'Sale Timesheet: "invoice on delivery" timesheets should not modify the invoice_status of the so') + message_sent = self.env['mail.message'].search([ + ('id', '>', last_message_id), + ('subject', 'like', 'Upsell'), + ('model', '=', 'sale.order'), + ('res_id', '=', sale_order.id), + ]) + + self.assertEqual(len(message_sent), 1, 'Sale Timesheet: An email should always be sent to the saleperson when the state of the sale order change to upselling') + + self.env['account.analytic.line'].create({ + 'name': 'Test Line', + 'project_id': task.project_id.id, + 'task_id': task.id, + 'unit_amount': 5, + 'employee_id': self.employee_user.id, + }) + + message_sent = self.env['mail.message'].search([ + ('id', '>', last_message_id), + ('subject', 'like', 'Upsell'), + ('model', '=', 'sale.order'), + ('res_id', '=', sale_order.id), + ]) + self.assertEqual(len(message_sent), 1, 'Sale Timesheet: An email should only be sent to the saleperson when the state of the sale order change to upselling')