Skip to content
Snippets Groups Projects
Commit cd48a806 authored by Antony Lesuisse's avatar Antony Lesuisse
Browse files

[ADD] sms: sms gateway using iap

parent 6b22476e
No related branches found
No related tags found
No related merge requests found
Showing
with 441 additions and 0 deletions
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': "Calendar SMS",
'summary': 'Send text messages as event reminders',
'description': "Send text messages as event reminders",
'category': 'Hidden',
'version': '1.0',
'depends': ['calendar', 'sms'],
'data': [
'views/calendar_views.xml',
],
'application': False,
'auto_install': True,
}
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * calendar_sms
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.saas~18+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-20 11:33+0000\n"
"PO-Revision-Date: 2017-09-20 11:33+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: calendar_sms
#: model:ir.model,name:calendar_sms.model_calendar_event
msgid "Event"
msgstr ""
#. module: calendar_sms
#: model:ir.model,name:calendar_sms.model_calendar_alarm
msgid "Event alarm"
msgstr ""
#. module: calendar_sms
#: code:addons/calendar_sms/models/calendar.py:23
#, python-format
msgid "Event reminder: %s on %s."
msgstr ""
#. module: calendar_sms
#: code:addons/calendar_sms/models/calendar.py:24
#, python-format
msgid "SMS text message reminder sent !"
msgstr ""
#. module: calendar_sms
#: model:ir.actions.act_window,name:calendar_sms.sms_message_send_action_mutli
msgid "Send SMS to attendees"
msgstr ""
#. module: calendar_sms
#: model:ir.model,name:calendar_sms.model_calendar_alarm_manager
msgid "calendar.alarm_manager"
msgstr ""
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import calendar
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import api, fields, models, _
_logger = logging.getLogger(__name__)
class CalendarEvent(models.Model):
_inherit = 'calendar.event'
def _get_default_sms_recipients(self):
""" Method overriden 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')
def _do_sms_reminder(self):
""" Send an SMS text reminder to attendees that haven't declined the event """
for event in self:
sms_msg = _("Event reminder: %s on %s.") % (event.name, event.start_datetime or event.start_date)
note_msg = _('SMS text message reminder sent !')
event.message_post_send_sms(sms_msg, note_msg=note_msg)
class CalendarAlarm(models.Model):
_inherit = 'calendar.alarm'
type = fields.Selection(selection_add=[('sms', 'SMS Text Message')])
class AlarmManager(models.AbstractModel):
_inherit = 'calendar.alarm_manager'
@api.model
def get_next_mail(self):
""" Cron method, overriden here to send SMS reminders as well
"""
result = super(AlarmManager, self).get_next_mail()
now = fields.Datetime.now()
last_sms_cron = self.env['ir.config_parameter'].get_param('calendar_sms.last_sms_cron', default=now)
cron = self.env['ir.model.data'].get_object('calendar', 'ir_cron_scheduler_alarm')
interval_to_second = {
"weeks": 7 * 24 * 60 * 60,
"days": 24 * 60 * 60,
"hours": 60 * 60,
"minutes": 60,
"seconds": 1
}
cron_interval = cron.interval_number * interval_to_second[cron.interval_type]
events_data = self.get_next_potential_limit_alarm('sms', seconds=cron_interval)
for event in self.env['calendar.event'].browse(events_data):
max_delta = events_data[event.id]['max_duration']
if event.recurrency:
found = False
for event_start in event._get_recurrent_date_by_event():
event_start = event_start.replace(tzinfo=None)
last_found = self.do_check_alarm_for_one_date(event_start, event, max_delta, 0, 'sms', after=last_sms_cron, missing=True)
for alert in last_found:
event.browse(alert['event_id'])._do_sms_reminder()
found = True
if found and not last_found: # if the precedent event had an alarm but not this one, we can stop the search for this event
break
else:
event_start = fields.Datetime.from_string(event.start)
for alert in self.do_check_alarm_for_one_date(event_start, event, max_delta, 0, 'sms', after=last_sms_cron, missing=True):
event.browse(alert['event_id'])._do_sms_reminder()
self.env['ir.config_parameter'].set_param('calendar_sms.last_sms_cron', now)
return result
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Add action entry in the Action Menu for Events -->
<act_window id="sms_message_send_action_mutli"
name="Send SMS to attendees"
src_model="calendar.event"
res_model="sms.send_sms"
view_type="form"
view_mode="form"
key2="client_action_multi"
target="new"/>
</odoo>
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import wizard
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'SMS gateway',
'category': 'Tools',
'summary': 'SMS Text Messaging',
'description': """
This module gives a framework for SMS text messaging
----------------------------------------------------
The service is provided by the In App Purchase Odoo platform.
""",
'depends': ['base', 'iap', 'mail'],
'data': [
'wizard/send_sms_views.xml',
'views/res_partner_views.xml',
],
'installable': True,
'auto_install': True,
}
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import mail_thread
from . import res_partner
from . import sms_api
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import models, _
from odoo.addons.iap.models.iap import InsufficientCreditError
_logger = logging.getLogger(__name__)
class MailThread(models.AbstractModel):
_inherit = 'mail.thread'
def _get_default_sms_recipients(self):
""" This method will likely need to be overriden by inherited models.
:returns partners: recordset of res.partner
"""
partners = self.env['res.partner']
if hasattr(self, 'partner_id'):
partners |= self.mapped('partner_id')
if hasattr(self, 'partner_ids'):
partners |= self.mapped('partner_ids')
return partners
def message_post_send_sms(self, sms_message, numbers=None, partners=None, note_msg=None, log_error=False):
""" Send an SMS text message and post an internal note in the chatter if successfull
:param sms_message: plaintext message to send by sms
:param partners: the numbers to send to, if none are given it will take those
from partners or _get_default_sms_recipients
:param partners: the recipients partners, if none are given it will take those
from _get_default_sms_recipients, this argument
is ignored if numbers is defined
:param note_msg: message to log in the chatter, if none is given a default one
containing the sms_message is logged
"""
if not numbers:
if not partners:
partners = self._get_default_sms_recipients()
# Collect numbers, we will consider the message to be sent if at least one number can be found
numbers = list(set([i.mobile for i in partners if i.mobile]))
if numbers:
try:
self.env['sms.api']._send_sms(numbers, sms_message)
mail_message = note_msg or _('SMS message sent: %s') % sms_message
except InsufficientCreditError as e:
if not log_error:
raise e
mail_message = _('Insufficient credit, unable to send SMS message: %s') % sms_message
else:
mail_message = _('No mobile number defined, unable to send SMS message: %s') % sms_message
for thread in self:
thread.message_post(body=mail_message)
return False
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class ResPartner(models.Model):
_inherit = 'res.partner'
def _get_default_sms_recipients(self):
""" Override of mail.thread method.
SMS recipients on partners are the partners themselves.
"""
return self
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.addons.iap.models import iap
DEFAULT_ENDPOINT = 'https://iap-sms.odoo.com'
class SmsApi(models.AbstractModel):
_name = 'sms.api'
@api.model
def _send_sms(self, numbers, message):
""" Send sms
"""
account = self.env['iap.account'].get('sms')
params = {
'account_token': account.account_token,
'numbers': numbers,
'message': message,
}
endpoint = self.env['ir.config_parameter'].sudo().get_param('sms.endpoint', DEFAULT_ENDPOINT)
r = iap.jsonrpc(endpoint + '/iap/message_send', params=params)
return True
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Add action entry in the Action Menu for Partners -->
<record id="partner_form_send_sms_form_view" model="ir.ui.view">
<field name="name">res.partner.form.send.sms</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="priority">10</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='phone']" position="replace">
<label for="phone"/>
<div class="o_row">
<field name="phone" widget="phone"/>
<button
type="action"
name="%(sms.send_sms_form_action)d"
class="btn-xs btn-link mb4 fa fa-envelope-o"
attrs="{'invisible':[('phone', '=', False)]}"
context="{'field_name': 'phone'}"
/>
</div>
</xpath>
<xpath expr="//field[@name='mobile']" position="replace">
<label for="mobile"/>
<div class="o_row">
<field name="mobile" widget="phone"/>
<button
type="action"
name="%(sms.send_sms_form_action)d"
class="btn-xs btn-link mb4 fa fa-envelope-o"
attrs="{'invisible':[('mobile', '=', False)]}"
context="{'field_name': 'mobile'}"
/>
</div>
</xpath>
</field>
</record>
</odoo>
# -*- coding: utf-8 -*-
from . import send_sms
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.addons.iap.models import iap
_logger = logging.getLogger(__name__)
class SendSMS(models.TransientModel):
_name = 'sms.send_sms'
recipients = fields.Char('Recipients', required=True)
message = fields.Text('Message', required=True)
def _get_records(self, model):
if self.env.context.get('active_domain'):
records = model.search(self.env.context.get('active_domain'))
elif self.env.context.get('active_ids'):
records = model.browse(self.env.context.get('active_ids', []))
else:
records = model.browse(self.env.context.get('active_id', []))
return records
@api.model
def default_get(self, fields):
result = super(SendSMS, self).default_get(fields)
active_model = self.env.context.get('active_model')
model = self.env[active_model]
records = self._get_records(model)
if getattr(records, '_get_default_sms_recipients'):
partners = records._get_default_sms_recipients()
phone_numbers = []
no_phone_partners = []
for partner in records:
number = partner.mobile
if number:
phone_numbers.append(number)
else:
no_phone_partners.append(partner.name)
if len(partners) > 1:
if no_phone_partners:
raise UserError(_('Missing mobile number for %s.') % ', '.join(no_phone_partners))
result['recipients'] = ', '.join(phone_numbers)
return result
def action_send_sms(self):
numbers = self.recipients.split(',')
active_model = self.env.context.get('active_model')
model = self.env[active_model]
records = self._get_records(model)
if getattr(records, 'message_post_send_sms'):
records.message_post_send_sms(self.message, numbers=numbers)
else:
self.env['sms.api']._send_sms(numbers, self.message)
return True
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="send_sms_view_form" model="ir.ui.view">
<field name="name">sms_send_sms.form</field>
<field name="model">sms.send_sms</field>
<field name="arch" type="xml">
<form string="Send an SMS">
<sheet>
<group>
<field name="recipients"/>
<field name="message" widget="text"/>
</group>
</sheet>
<footer>
<group>
<span>
<button string="Send" type="object" class="oe_highlight" name="action_send_sms"/>
<button string="Cancel" class="oe_link" special="cancel" />
</span>
</group>
</footer>
</form>
</field>
</record>
<record id="send_sms_form_action" model="ir.actions.act_window">
<field name="name">Send SMS</field>
<field name="res_model">sms.send_sms</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<!-- Add action entry in the Action Menu for Partners -->
<act_window id="send_sms_action"
name="Send SMS"
src_model="res.partner"
res_model="sms.send_sms"
view_type="form"
view_mode="form"
key2="client_action_multi"
target="new"/>
</odoo>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment