diff --git a/addons/calendar_sms/models/calendar.py b/addons/calendar_sms/models/calendar.py index 763d407af2..648a96f0b1 100644 --- a/addons/calendar_sms/models/calendar.py +++ b/addons/calendar_sms/models/calendar.py @@ -15,7 +15,7 @@ class CalendarEvent(models.Model): """ Method overridden from mail.thread (defined in the sms module). SMS text messages will be sent to attendees that haven't declined the event(s). """ - return self.mapped('attendee_ids').filtered(lambda att: att.state != 'declined').mapped('partner_id') + return self.mapped('attendee_ids').filtered(lambda att: att.state != 'declined' and att.partner_id.phone_sanitized).mapped('partner_id') def _do_sms_reminder(self): """ Send an SMS text reminder to attendees that haven't declined the event """ diff --git a/addons/calendar_sms/tests/__init__.py b/addons/calendar_sms/tests/__init__.py new file mode 100644 index 0000000000..ee17b5b68c --- /dev/null +++ b/addons/calendar_sms/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. + +from . import test_calendar_sms diff --git a/addons/calendar_sms/tests/test_calendar_sms.py b/addons/calendar_sms/tests/test_calendar_sms.py new file mode 100644 index 0000000000..361b38a996 --- /dev/null +++ b/addons/calendar_sms/tests/test_calendar_sms.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. + +from datetime import datetime + +from flectra.tests.common import SingleTransactionCase + + +class TestCalendarSms(SingleTransactionCase): + + @classmethod + def setUpClass(cls): + super(TestCalendarSms, cls).setUpClass() + + cls.partner_phone = cls.env['res.partner'].create({ + 'name': 'Partner With Phone Number', + 'phone': '0477777777', + 'country_id': cls.env.ref('base.be').id, + }) + cls.partner_no_phone = cls.env['res.partner'].create({ + 'name': 'Partner With No Phone Number', + 'country_id': cls.env.ref('base.be').id, + }) + + def test_attendees_with_number(self): + """Test if only partners with sanitized number are returned.""" + attendees = self.env['calendar.event'].create({ + 'name': "Boostrap vs Foundation", + 'start': datetime(2022, 1, 1, 11, 11), + 'stop': datetime(2022, 2, 2, 22, 22), + 'partner_ids': [(6, 0, [self.partner_phone.id, self.partner_no_phone.id])], + })._sms_get_default_partners() + self.assertEqual(len(attendees), 1, "There should be only one partner retrieved") diff --git a/addons/sale_project/models/sale_order.py b/addons/sale_project/models/sale_order.py index facb6c3533..84d34ff006 100644 --- a/addons/sale_project/models/sale_order.py +++ b/addons/sale_project/models/sale_order.py @@ -107,7 +107,7 @@ class SaleOrder(models.Model): def write(self, values): if 'state' in values and values['state'] == 'cancel': - self.project_id.sale_line_id = False + self.project_id.sudo().sale_line_id = False return super(SaleOrder, self).write(values) diff --git a/addons/sale_project/tests/test_sale_project.py b/addons/sale_project/tests/test_sale_project.py index ebcfbf91bc..2fa5d10618 100644 --- a/addons/sale_project/tests/test_sale_project.py +++ b/addons/sale_project/tests/test_sale_project.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. -from flectra.tests.common import SavepointCase +from flectra.tests.common import SavepointCase, users class TestSaleProject(SavepointCase): @@ -80,15 +80,15 @@ class TestSaleProject(SavepointCase): 'service_tracking': 'project_only', 'project_id': False, }) + cls.partner = cls.env['res.partner'].create({'name': "Mur en béton"}) def test_sale_order_with_project_task(self): SaleOrderLine = self.env['sale.order.line'].with_context(tracking_disable=True) - partner = self.env['res.partner'].create({'name': "Mur en béton"}) sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': partner.id, - 'partner_invoice_id': partner.id, - 'partner_shipping_id': partner.id, + 'partner_id': self.partner.id, + 'partner_invoice_id': self.partner.id, + 'partner_shipping_id': self.partner.id, }) so_line_order_no_task = SaleOrderLine.create({ 'name': self.product_order_service1.name, @@ -141,11 +141,10 @@ class TestSaleProject(SavepointCase): self.assertTrue(so_line_order_only_project.project_id, "Sales order line should be linked to newly created project") def test_sol_product_type_update(self): - partner = self.env['res.partner'].create({'name': "Mur en brique"}) sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': partner.id, - 'partner_invoice_id': partner.id, - 'partner_shipping_id': partner.id, + 'partner_id': self.partner.id, + 'partner_invoice_id': self.partner.id, + 'partner_shipping_id': self.partner.id, }) self.product_order_service3.type = 'consu' sale_order_line = self.env['sale.order.line'].create({ @@ -160,3 +159,31 @@ class TestSaleProject(SavepointCase): self.product_order_service3.type = 'service' self.assertTrue(sale_order_line.is_service, "As the product is a service, the SOL should be a service") + + @users('demo') + def test_cancel_so_linked_to_project(self): + """ Test that cancelling a SO linked to a project will not raise an error """ + # Ensure user don't have edit right access to the project + group_sale_manager = self.env.ref('sales_team.group_sale_manager') + group_project_user = self.env.ref('project.group_project_user') + self.env.user.write({'groups_id': [(6, 0, [group_sale_manager.id, group_project_user.id])]}) + + sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({ + 'partner_id': self.partner.id, + 'partner_invoice_id': self.partner.id, + 'partner_shipping_id': self.partner.id, + 'project_id': self.project_global.id, + }) + sale_order_line = self.env['sale.order.line'].create({ + 'name': self.product_order_service2.name, + 'product_id': self.product_order_service2.id, + 'order_id': sale_order.id, + }) + self.assertFalse(self.project_global.tasks.sale_line_id, "The project tasks should not be linked to the SOL") + + sale_order.action_confirm() + self.assertEqual(self.project_global.tasks.sale_line_id.id, sale_order_line.id, "The project tasks should be linked to the SOL from the SO") + + self.project_global.sale_line_id = sale_order_line + sale_order.action_cancel() + self.assertFalse(self.project_global.sale_line_id, "The project should not be linked to the SOL anymore")