[IMP] sms: improve synchronization of SMS actions with notifications
Improve cancel / set outgoing actions on sms model. This notably allows to synchronize notifications when hitting action buttons on sms form view. Also add an action to set as error. This will be used when having IAP feedback on SMS sending. Task-2634957 Prepares Task-2535005 (SMS view pimp) and Task-2560666 (IAP feedback) PR odoo/odoo#75798
This commit is contained in:
@@ -45,6 +45,43 @@ class SmsSms(models.Model):
|
||||
('sms_optout', 'Opted Out'),
|
||||
], copy=False)
|
||||
|
||||
def action_set_canceled(self):
|
||||
self.state = 'canceled'
|
||||
notifications = self.env['mail.notification'].sudo().search([
|
||||
('sms_id', 'in', self.ids),
|
||||
# sent is sent -> cannot reset
|
||||
('notification_status', 'not in', ['canceled', 'sent']),
|
||||
])
|
||||
if notifications:
|
||||
notifications.write({'notification_status': 'canceled'})
|
||||
if not self._context.get('sms_skip_msg_notification', False):
|
||||
notifications.mail_message_id._notify_message_notification_update()
|
||||
|
||||
def action_set_error(self, failure_type):
|
||||
self.state = 'error'
|
||||
self.failure_type = failure_type
|
||||
notifications = self.env['mail.notification'].sudo().search([
|
||||
('sms_id', 'in', self.ids),
|
||||
# sent can be set to error due to IAP feedback
|
||||
('notification_status', '!=', 'exception'),
|
||||
])
|
||||
if notifications:
|
||||
notifications.write({'notification_status': 'exception', 'failure_type': failure_type})
|
||||
if not self._context.get('sms_skip_msg_notification', False):
|
||||
notifications.mail_message_id._notify_message_notification_update()
|
||||
|
||||
def action_set_outgoing(self):
|
||||
self.state = 'outgoing'
|
||||
notifications = self.env['mail.notification'].sudo().search([
|
||||
('sms_id', 'in', self.ids),
|
||||
# sent is sent -> cannot reset
|
||||
('notification_status', 'not in', ['ready', 'sent']),
|
||||
])
|
||||
if notifications:
|
||||
notifications.write({'notification_status': 'ready', 'failure_type': False})
|
||||
if not self._context.get('sms_skip_msg_notification', False):
|
||||
notifications.mail_message_id._notify_message_notification_update()
|
||||
|
||||
def send(self, delete_all=False, auto_commit=False, raise_exception=False):
|
||||
""" Main API method to send SMS.
|
||||
|
||||
@@ -59,9 +96,6 @@ class SmsSms(models.Model):
|
||||
if auto_commit is True and not getattr(threading.currentThread(), 'testing', False):
|
||||
self._cr.commit()
|
||||
|
||||
def set_outgoing(self):
|
||||
self.state = 'outgoing'
|
||||
|
||||
def resend_failed(self):
|
||||
sms_to_send = self.filtered(lambda sms: sms.state == 'error')
|
||||
notification_title = _('Warning')
|
||||
@@ -88,9 +122,6 @@ class SmsSms(models.Model):
|
||||
}
|
||||
}
|
||||
|
||||
def cancel(self):
|
||||
self.state = 'canceled'
|
||||
|
||||
@api.model
|
||||
def _process_queue(self, ids=None):
|
||||
""" Send immediately queued messages, committing after each message is sent.
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<form string="SMS">
|
||||
<header>
|
||||
<button name="send" string="Send Now" type="object" states='outgoing' class="oe_highlight"/>
|
||||
<button name="set_outgoing" string="Retry" type="object" states='error,canceled'/>
|
||||
<button name="cancel" string="Cancel" type="object" states='error,outgoing'/>
|
||||
<button name="action_set_outgoing" string="Retry" type="object" states='error,canceled'/>
|
||||
<button name="action_set_canceled" string="Cancel" type="object" states='error,outgoing'/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
||||
@@ -2,36 +2,116 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestSMSWizards(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSMSActionsCommon(TestMailFullCommon, TestMailFullRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSWizards, cls).setUpClass()
|
||||
super(TestSMSActionsCommon, cls).setUpClass()
|
||||
cls.test_record = cls.env['mail.test.sms'].with_context(**cls._test_context).create({
|
||||
'name': 'Test',
|
||||
'customer_id': cls.partner_1.id,
|
||||
})
|
||||
cls.test_record = cls._reset_mail_context(cls.test_record)
|
||||
cls.msg = cls.test_record.message_post(body='TEST BODY', author_id=cls.partner_employee.id)
|
||||
cls.sms_p1 = cls.env['sms.sms'].create({
|
||||
'body': 'TEST BODY',
|
||||
'failure_type': 'sms_number_format',
|
||||
'mail_message_id': cls.msg.id,
|
||||
'number': cls.partner_1.mobile,
|
||||
'partner_id': cls.partner_1.id,
|
||||
'state': 'error',
|
||||
})
|
||||
cls.notif_p1 = cls.env['mail.notification'].create({
|
||||
'mail_message_id': cls.msg.id,
|
||||
'res_partner_id': cls.partner_1.id,
|
||||
'sms_id': cls.sms_p1.id,
|
||||
'sms_number': cls.partner_1.mobile,
|
||||
'notification_type': 'sms',
|
||||
'notification_status': 'exception',
|
||||
'failure_type': 'sms_number_format',
|
||||
})
|
||||
cls.sms_p2 = cls.env['sms.sms'].create({
|
||||
'body': 'TEST BODY',
|
||||
'failure_type': 'sms_credit',
|
||||
'mail_message_id': cls.msg.id,
|
||||
'number': cls.partner_2.mobile,
|
||||
'partner_id': cls.partner_2.id,
|
||||
'state': 'error',
|
||||
})
|
||||
cls.notif_p2 = cls.env['mail.notification'].create({
|
||||
'mail_message_id': cls.msg.id,
|
||||
'res_partner_id': cls.partner_2.id,
|
||||
'sms_id': cls.sms_p2.id,
|
||||
'sms_number': cls.partner_2.mobile,
|
||||
'notification_type': 'sms',
|
||||
'notification_status': 'exception',
|
||||
'failure_type': 'sms_credit',
|
||||
})
|
||||
|
||||
|
||||
@tagged('sms_management')
|
||||
class TestSMSActions(TestSMSActionsCommon):
|
||||
|
||||
def test_sms_set_cancel(self):
|
||||
self._reset_bus()
|
||||
self.sms_p1.action_set_canceled()
|
||||
self.assertEqual(self.sms_p1.state, 'canceled')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'canceled', 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'exception', 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
self._reset_bus()
|
||||
self.sms_p2.with_context(sms_skip_msg_notification=True).action_set_canceled()
|
||||
self.assertEqual(self.sms_p2.state, 'canceled')
|
||||
|
||||
self.assertEqual(self.env['bus.bus'].search([]), self.env['bus.bus'], 'SMS: no bus notifications unless asked')
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'canceled', 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'canceled', 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
|
||||
def test_sms_set_error(self):
|
||||
self._reset_bus()
|
||||
(self.sms_p1 + self.sms_p2).with_context(sms_skip_msg_notification=True).action_set_canceled()
|
||||
self.assertEqual(self.sms_p1.state, 'canceled')
|
||||
self.assertEqual(self.sms_p2.state, 'canceled')
|
||||
self.assertEqual(self.env['bus.bus'].search([]), self.env['bus.bus'], 'SMS: no bus notifications unless asked')
|
||||
|
||||
(self.sms_p1 + self.sms_p2).action_set_error('sms_server')
|
||||
self.assertEqual(self.sms_p1.state, 'error')
|
||||
self.assertEqual(self.sms_p2.state, 'error')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'exception', 'failure_type': 'sms_server'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'exception', 'failure_type': 'sms_server'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
def test_sms_set_outgoing(self):
|
||||
self._reset_bus()
|
||||
(self.sms_p1 + self.sms_p2).action_set_outgoing()
|
||||
self.assertEqual(self.sms_p1.state, 'outgoing')
|
||||
self.assertEqual(self.sms_p2.state, 'outgoing')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'ready'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'ready'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
|
||||
@tagged('sms_management')
|
||||
class TestSMSWizards(TestSMSActionsCommon):
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend(self):
|
||||
self._reset_bus()
|
||||
|
||||
@@ -47,6 +127,7 @@ class TestSMSWizards(TestMailFullCommon, TestMailFullRecipients):
|
||||
], 'TEST BODY', self.msg, check_sms=True)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_update_number(self):
|
||||
self._reset_bus()
|
||||
|
||||
@@ -76,6 +157,7 @@ class TestSMSWizards(TestMailFullCommon, TestMailFullRecipients):
|
||||
], 'TEST BODY', self.msg, check_sms=False)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_internals(self):
|
||||
self._reset_bus()
|
||||
self.assertSMSNotification([
|
||||
@@ -91,6 +173,7 @@ class TestSMSWizards(TestMailFullCommon, TestMailFullRecipients):
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_resend()
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_w_cancel(self):
|
||||
self._reset_bus()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user